使用 Java & Saxon 发现可选的 XML 属性
Discover Optional XML Attributes with Java & Saxon
我们需要在 XML 文件中填充每个 ID 属性。该文件恰好是一个 DITA 主题,DITA 定义了专门化的功能(有点像继承)。
由于该继承选项,为了在未来验证我们的系统,我们希望 'discover' ID 属性有效,但我找不到任何关于如何以编程方式发现可选属性的示例。
有没有人有使用 Java 或 Saxon 的例子。我们对 XSL 或使用 saxon java API 持开放态度。我们只想获取 XML 文件 X
并找到 X 中属性 "id"
有效的所有节点。
对于 Saxon,如果您根据模式验证元素,那么 saxon:type [1] 将为您提供其类型注释。所以(使用 XQuery 语法,但您同样可以使用 XSLT):
let $e := validate(<e/>)
let $type-of-e := saxon:type($e)
然后获取在此类型上定义的属性:
let $attUses := $type-of-e("attribute uses")
或者如果您只想要可选的:
let $optionalAtts := $attUses[not(.("required"))]
如果您想要可选属性的 QName:
let $optionalAttributeNames := $optionalAtts ! .("attribute declaration") ! QName(.("target namespace"), .("name"))
这是在架构组件模型中导航。您需要熟悉 XSD 第 1 部分中对此模型的描述。例如,XSD 表示一个 "attribute use" 组件有一个名为 属性 的 {attribute declaration}
,那么在 Saxon 中,属性使用由一个函数表示,可以用参数 "attribute declaration" 调用到 return 属性声明组件(它本身是另一个函数)。
让我们尝试更进一步,看看您的具体任务,找到 id 属性有效的所有节点。如果我们假设您的实例文档已经针对模式有效,并且整个文档携带类型注释作为针对模式的验证结果,那么您可以定义:
declare function f:allows-id($e as element(*)) as xs:boolean {
let $type-of-e := saxon:type($e)
let $attUses := $type-of-e("attribute uses")
let $attNames := $attUses ! .("attribute declaration") ! QName(.("target namespace"), .("name"))
return $attNames = QName("", "id")
}
然后您可以找到所有允许 id 属性但没有 id 属性的元素
//*[f:allows-id(.) and not(@id)]
一个小观察:这不会找到由于架构中的通配符 (xs:anyAttribute) 而使 @id 属性有效的元素,或者存在开放内容模型的元素:它只会找到那些在类型定义中显式声明了 id 属性的。
[1] http://www.saxonica.com/documentation/#!functions/saxon/type
我们需要在 XML 文件中填充每个 ID 属性。该文件恰好是一个 DITA 主题,DITA 定义了专门化的功能(有点像继承)。
由于该继承选项,为了在未来验证我们的系统,我们希望 'discover' ID 属性有效,但我找不到任何关于如何以编程方式发现可选属性的示例。
有没有人有使用 Java 或 Saxon 的例子。我们对 XSL 或使用 saxon java API 持开放态度。我们只想获取 XML 文件 X
并找到 X 中属性 "id"
有效的所有节点。
对于 Saxon,如果您根据模式验证元素,那么 saxon:type [1] 将为您提供其类型注释。所以(使用 XQuery 语法,但您同样可以使用 XSLT):
let $e := validate(<e/>)
let $type-of-e := saxon:type($e)
然后获取在此类型上定义的属性:
let $attUses := $type-of-e("attribute uses")
或者如果您只想要可选的:
let $optionalAtts := $attUses[not(.("required"))]
如果您想要可选属性的 QName:
let $optionalAttributeNames := $optionalAtts ! .("attribute declaration") ! QName(.("target namespace"), .("name"))
这是在架构组件模型中导航。您需要熟悉 XSD 第 1 部分中对此模型的描述。例如,XSD 表示一个 "attribute use" 组件有一个名为 属性 的 {attribute declaration}
,那么在 Saxon 中,属性使用由一个函数表示,可以用参数 "attribute declaration" 调用到 return 属性声明组件(它本身是另一个函数)。
让我们尝试更进一步,看看您的具体任务,找到 id 属性有效的所有节点。如果我们假设您的实例文档已经针对模式有效,并且整个文档携带类型注释作为针对模式的验证结果,那么您可以定义:
declare function f:allows-id($e as element(*)) as xs:boolean {
let $type-of-e := saxon:type($e)
let $attUses := $type-of-e("attribute uses")
let $attNames := $attUses ! .("attribute declaration") ! QName(.("target namespace"), .("name"))
return $attNames = QName("", "id")
}
然后您可以找到所有允许 id 属性但没有 id 属性的元素
//*[f:allows-id(.) and not(@id)]
一个小观察:这不会找到由于架构中的通配符 (xs:anyAttribute) 而使 @id 属性有效的元素,或者存在开放内容模型的元素:它只会找到那些在类型定义中显式声明了 id 属性的。
[1] http://www.saxonica.com/documentation/#!functions/saxon/type