什么XPath表达式找到具有给定命名空间声明的元素集?

jam*_*iss 3 java xml xpath xml-namespaces

假设我有一个带有2个带有前缀的名称空间声明的XML文档foo,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://www.foo.com">
  <one>
    <!-- children nodes here -->
  </one>
  <two>
    <!-- children nodes here -->
  </two>
  <three xmlns:foo="http://www.foo.com">
    <!-- children nodes here -->
  </three>
</root>
Run Code Online (Sandbox Code Playgroud)

我想评估一个XPath表达式(在Java中),该表达式将返回具有此命名空间声明的元素的NodeList,即rootthree节点.我不是在寻找这个命名空间在范围内的所有节点,而只是寻找具有命名空间声明的节点.

这是我计划使用的Java:

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression xPathExpression = null;  
NodeList nodeList = null;
boolean theExpressionWasCompiled = true;
xPathExpression = xPath.compile(xPathStatement); // XPath goes here!
nodeList = (NodeList) xPathExpression.evaluate(document, XPathConstants.NODESET);
Run Code Online (Sandbox Code Playgroud)

我应该使用什么的XPath(该值xPathStatementcompile()方法)?

编辑:XPath 1或2确定.

最终编辑:事实证明,XPath不能完全符合我的要求(如果你想要细节,请参阅下面的Dimitre的解释).我能做的最好的事情是多次评估XPath(每个命名空间声明一次),以找到具有命名空间声明的每个元素.我碰巧已经知道每个命名空间的声明次数,因此知道要评估多少次对我来说不是问题.不是超级高效,但确实有效.这是我使用的XPath,它与Dimitre提出的非常类似(见下文):

//*[namespace::*[local-name() = 'foo']]
     [not
       (parent::node()
         [namespace::*
           [local-name() = 'foo']
         ]
       )
     ]
Run Code Online (Sandbox Code Playgroud)

感谢我的朋友Roger Costello制作我使用过的XPath.

Mar*_*nen 5

根据我的理解,XPath无法满足您的需求.XPath数据模型具有名称空间节点,这些节点位于任何给定元素节点的范围内; 在那个模型中你是否解析

<root xmlns:foo="http://example.com/">
  <child>
    <grandchild/>
  </child>
</root>
Run Code Online (Sandbox Code Playgroud)

要么

<root xmlns:foo="http://example.com/">
  <child xmlns:foo="http://example.com/">
    <grandchild/>
  </child>
</root>
Run Code Online (Sandbox Code Playgroud)

要么

<root xmlns:foo="http://example.com/">
  <child xmlns:foo="http://example.com/">
    <grandchild xmlns:foo="http://example.com/"/>
  </child>
</root>
Run Code Online (Sandbox Code Playgroud)

在暴露于XPath(以及XSLT或XQuery)的模型中没有什么区别,在所有三种情况下,所有三个元素节点都有一个名称空间,其范围内包含本地名称foo和值http://example.com/.

基于此,我没有看到如何编写XPath来区分由于名称空间声明而在范围内具有命名空间节点的元素节点以及从祖先元素继承它的那些节点.

所以我认为您的问题不能用XPath解决.你可能想要等到Dimitre之类的人确认或拒绝我的观点.

  • James,我试图解释如何在XPath数据模型中建模命名空间信息,在XPath和XSLT 1.0数据模型中有命名空间节点,我用一个例子解释了标记中的命名空间声明如何导致数据模型中的命名空间节点,以及此外,我视图中的现有数据模型缺少您正在寻找的信息,即找出存在某个名称空间声明的元素节点.如果您认为这与您的观点无关,那么请等到其他人对您的问题提供更深入的了解. (2认同)