XPath表达式,如果NodeA存在,则选择NodeA,否则返回NodeB

时间:2014-12-01 18:04:29

标签: xpath

解析POM文件时,我想阅读/project/groupId(如果存在)。但是,如果它不存在,我想阅读/project/parent/groupId。怎么办?

2 个答案:

答案 0 :(得分:5)

如果您有XPath 2.0,那么很简单:

(/project/groupId, /project/parent/groupId)[1]

在XPath 1.0中它是一个小问题,因为没有像你在XPath 2.0中得到的有序节点序列的概念 - 你可以建立节点集的联合,但位置谓词总是引用文档顺序,所以< / p>

(/project/groupId | /project/parent/groupId)[1]

会在XML文档中为您提供/project/groupId/project/parent/groupId中的任何一个。

对于这种情况,您可以根据以下事实使用技巧:当您将布尔值视为XPath中的数字时,true变为1,false变为0:

substring(concat(/project/parent/groupId, /project/groupId),
          boolean(/project/groupId) * string-length(/project/parent/groupId) + 1)

为了解释这是做什么,举一个例子 - 父groupId是&#34; foo&#34;,项目groupId是&#34; bar&#34;。首先,我们连接两个,父母首先 - &#34; foobar&#34;。接下来,我们检查项目groupId元素是否存在,并且因为它确实存在

  • boolean(/project/groupId) * string-length(/project/parent/groupId) + 1 = 3 + 1 = 4

所以我们从第四个字符开始获取子字符串,给出结果&#34; bar&#34;。

现在假设父groupId是&#34; foo&#34;并且没有项目groupId。在这种情况下

  • concat(/project/parent/groupId, /project/groupId)只是&#34; foo&#34;
  • boolean(/project/groupId) * string-length(/project/parent/groupId) + 1 = 0 + 1 = 1

因为&#34;子串从第一个字符开始&#34;是整个字符串,这给出了&#34; foo&#34;。

的正确结果

P.S。记住您需要考虑命名空间 - Maven POM文件通常将http://maven.apache.org/POM/4.0.0声明为默认命名空间,因此您需要使用XPath库提供的任何机制将其设置为默认命名空间(如果可能)或绑定它到合适的前缀并使用/pom:project/pom:groupId

之类的路径

答案 1 :(得分:0)

您可以检查&#34; / project / groupId&#34;的重新多边形DOMNodeList的长度。 Xpath查询包含任何节点,如果它没有运行&#34; / project / parent / groupId&#34;查询。

可能只需一次拍摄,但我需要更多信息。