繁体   English   中英

如何使用XPath选择几个XML元素?

[英]How can I select several XML elements using XPath?

假设以下XML:

<response>
<header>
<resultCode>0000</resultCode>
<resultMsg>OK</resultMsg>
</header>
<body>
<items>
 <item>
  <addr1>America</addr1>
  <addr2>(Atlanta)</addr2>
 </item>
 <item>
  <addr1>Canada</addr1>
  <addr2>(Toronto)</addr2>
 </item>
 <item>
  <addr1>France</addr1>
  <addr2>(Paris)</addr2>
 </item>
 </items>
</body>
</response>

我想使用XPath选择几个XML元素。 因此,我在下面编写了JAVA代码。

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(urlBuilder.toString());

XPath xpath = XPathFactory.newInstance().newXPath();

NodeList items = (NodeList) xpath.evaluate("//item", doc, XPathConstants.NODESET );
NodeList addrAll= (NodeList) xpath.evaluate("//item/addr1 | //item/addr2", doc, XPathConstants.NODESET);

System.out.println("length:"+addrAll.getLength());      
for(int tmp=0; tmp<addrAll.getLength();tmp++){
    System.out.println(addrAll.item(tmp).getTextContent());
}

结果是:

    length:6
    America
    (Atlanta)
    Canada
    (Toronto)
    France
    (Paris)

但是,这不是我想要的。 我的预期输出:

length:3    
America (Atlanta)
Canada (Toronto)
France (Paris)

我希望你能理解我的问题。 我该如何编辑我的代码呢?

这不是xpath的工作方式。 它检索它指定的信息,但不会连接多个数据点。

为此,您可以使用xslt,也可以创建两个xpath,每个addrX部分一个,然后让Java客户端代码将它们组合在一起。

您如何更新Java代码取决于几件事,例如,如果每item都将同时包含addr1addr2

如果可以依靠,则可以执行以下操作:

System.out.println("length:"+addrAll.getLength());      
for(int tmp=0; tmp<addrAll.getLength();tmp+=2){
    String country = addrAll.item(tmp).getTextContent();
    String city = addrAll.item(tmp+1).getTextContent();
    System.out.printf("%s %s\n", country, city);
}

XPath 1.0具有一组有限的可用数据类型:字符串,布尔值,数字和节点集。 您想要的答案是三个字符串的序列,它们不对应于现有节点,并且在XPath 1.0中没有这样的东西,而是三个字符串的序列。

如果您在Java世界中,那么实际上没有理由将自己局限于XPath 1.0。 XPath 2.0扩展了类型系统以允许字符串序列,因此您可以使用//item/concat(addr1, ' ', addr2)//item/string-join(*, ' ')

XPath 2.0已经存在了十多年了-向前迈进! 您可能还会考虑使用比DOM更现代的树模型:JDOM2和XOM非常容易使用。

List<WebElement> items = wd.findElements(By.xpath("//items/item"));
System.out.println("length: " + items.size());
items.forEach(item -> System.out.println(item.getText()));

输出:

length: 3 
America (Atlanta) 
Canada (Toronto) 
France (Paris)

您可以将其放入列表或地图。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM