java - 使用 Java 和 Saxon 发现可选 XML 属性

标签 java xml xslt xsd saxon

我们需要填充 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/

相关文章:

java - 删除文件时 Jenkins SVN 插件失败(校验和不匹配)

java - ListView 不使用 Firebase 填充

xml - 在Windows上安装Hadoop时出错

xslt - 如何从一个 xhtml 文档中提取一个 div 部分到另一个 xhtml 文档中

xml - 在 xsl 报告中的输出周围添加括号

java - 在多用户环境中使 grails 服务方法原子化

java - 如何在不释放鼠标左键的情况下对 JButton 执行 "Unclick"操作?

java - 如何检查响应是否为 xml 格式而不是 HTML?

java - 从 XMLResponse 创建 FileReader?

XSLT - 将属性添加到单独模板中的元素?