我们需要填充 XML 文件中的每个 ID 属性。该文件恰好是 DITA 主题,并且 DITA 定义了专门化的功能(有点像继承)。
由于继承选项,为了让我们的系统面向 future ,我们希望“发现”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 statements}
的属性,那么在 Saxon 中属性的使用由一个函数来表示,可以使用参数“属性声明”来调用该函数,以返回属性声明组件(其本身就是另一个函数)。
让我们尝试更进一步,看看您的具体任务,查找 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 属性但没有 as 的元素
//*[f:allows-id(.) and not(@id)]
一个小观察:这不会找到由于架构 (xs:anyAttribute) 中的通配符而使 @id 属性有效的元素,或者存在开放内容模型的元素:它只会找到那些id 属性在类型定义中显式声明。
[1] http://www.saxonica.com/documentation/#!functions/saxon/type
关于java - 使用 Java 和 Saxon 发现可选 XML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36041371/