我有一些XML
(实际上是XBRL
个)文档,其中包含test
属性包含XPath表达式的一些元素:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<link:linkbase
xmlns:ea="http://xbrl.org/2008/assertion/existence"
xmlns:generic="http://xbrl.org/2008/generic"
xmlns:link="http://www.xbrl.org/2003/linkbase"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xff="http://www.xbrl.org/2010/function/formula">
<generic:link xlink:role="http://www.xbrl.org/2003/role/link" xlink:type="extended">
<!-- .... -->
<va:valueAssertion
... some attribs ...
test="if(xff:has-fallback-value(xs:QName('someQName'))) then false() else (count($someVariable) ge 1)"
/>
<!-- ... -->
</generic:link>
</link:linkbase>
处理XPath表达式的约定是,它使用与XML文档中声明的前缀相同的名称空间。
我们还有一些(自定义)linting机制,其中包含一个规则,用于检查声明的前缀及其命名空间是否已被使用&#34;在文件中。
这意味着在上面的xml示例中,xff和xs前缀应该被识别为&#34;使用&#34;,因为它们存在于XPath表达式中。然而,标准工具(在Java中)并不能帮助我们看到这种情况。
例如,我可以在范围内使用前缀,并检查是否可以找到&#34;前缀:&#34;在XPath字符串中;但这似乎是一个非常错误的解决方案,容易出现误报和漏报。另一种方式是&#34;只是&#34;使用命名空间绑定的所有可能组合来评估XPath表达式,并检查最小的命名空间集是什么。由于评估可能会跳过整个代码分支,因此不会对所有内容产生影响。 (例如,遇到if语句时)。其次,由于我们讨论了包含多个XPath表达式的许多(约100个)文档,因此可能性的爆炸性增长很快。
有谁知道解决这个问题的[n](好)方法?目前,我们在JVM上使用Scala来实现检查。因此,首选原生Java或Scala解决方案。如果需要,可以使用其他JVM语言或依赖于非Java工具。
答案 0 :(得分:1)
使用javax.xml.xpath.XPath#compile(String)
解析文档中的所有XPath表达式。
要知道表达式中引用了哪些名称空间前缀,请准备一个NamespaceContext
实现,该实现记录所请求的命名空间绑定的前缀,并在调用compile方法之前通过XPath#setNamespaceContext(NamespaceContext)
进行设置。
基于该前缀列表并在包含表达式字符串的属性上给出命名空间绑定,然后您可以构建所有使用的命名空间的列表。