从XPath表达式获取/列出前缀

时间:2017-04-12 15:11:30

标签: java xml xpath

我有一些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工具。

1 个答案:

答案 0 :(得分:1)

使用javax.xml.xpath.XPath#compile(String)解析文档中的所有XPath表达式。

要知道表达式中引用了哪些名称空间前缀,请准备一个NamespaceContext实现,该实现记录所请求的命名空间绑定的前缀,并在调用compile方法之前通过XPath#setNamespaceContext(NamespaceContext)进行设置。

基于该前缀列表并在包含表达式字符串的属性上给出命名空间绑定,然后您可以构建所有使用的命名空间的列表。