解析POM文件时,我想读取/project/groupId它是否存在.但是,如果它不存在我想阅读/project/parent/groupId.怎么办?
如果您有XPath 2.0,那么很容易:
(/project/groupId, /project/parent/groupId)[1]
Run Code Online (Sandbox Code Playgroud)
在XPath 1.0中,它更加狡猾,因为没有像XPath 2.0那样的有序节点序列的概念 - 你可以构建节点集的联合,但位置谓词总是引用文档顺序,所以
(/project/groupId | /project/parent/groupId)[1]
Run Code Online (Sandbox Code Playgroud)
会给你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)
Run Code Online (Sandbox Code Playgroud)
为了解释这是做什么,举一个例子 - 父groupId是"foo",项目groupId是"bar".首先我们连接两个,父母首先 - "foobar".接下来,我们检查项目groupId元素是否存在,以及它是否存在
boolean(/project/groupId) * string-length(/project/parent/groupId) + 1= 3 + 1=4所以我们从第四个字符开始获取子字符串,给出结果"bar".
现在假设父groupId是"foo"并且没有项目groupId.在这种情况下
concat(/project/parent/groupId, /project/groupId) 只是"foo"boolean(/project/groupId) * string-length(/project/parent/groupId) + 1= 0 + 1=1由于"从第一个字符开始的子字符串"是整个字符串,因此这给出了"foo"的正确结果.
PS记住你需要考虑命名空间 - Maven POM文件通常声明http://maven.apache.org/POM/4.0.0为默认命名空间,因此你需要使用XPath库提供的任何机制来将其设置为默认命名空间(如果可能)或将其绑定到合适的前缀并使用像这样的路径/pom:project/pom:groupId