我在放在一行上的xml文档上使用xpath text()函数时遇到了麻烦。如果在完全相同的xml版本的漂亮打印版本上使用,text()工作正常。
在这种情况下,我使用ruby和nokogiri,但我在firefox附加组件XPath Checker中看到了相同的行为。我对nokogiri和XPath Checker都得到了完全相同的结果。
顺便说一下:
工作:
doc = Nokogiri::XML::Document.parse <<-EOXML
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getOSVersionResponse xmlns:ns="http://www.cisco.com/AXL/API/8.5">
<return>
<os>
<osName>Linux</osName>
<osVersion>2.6.18-194.26.1.el5PAE</osVersion>
<aarNeighborhoodName/>
</os>
</return>
</ns:getOSVersionResponse>
</soapenv:Body>
</soapenv:Envelope>
EOXML
不工作:
doc = Nokogiri::XML::Document.parse <<-EOXML
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:getOSVersionResponse xmlns:ns="http://www.cisco.com/AXL/API/8.5"><return><os><osName>Linux</osName><osVersion>2.6.18-194.26.1.el5PAE</osVersion><aarNeighborhoodName/></os></return></ns:getOSVersionResponse></soapenv:Body></soapenv:Envelope>
EOXML
Xpath查询:
doc.xpath("//*[not(text())]")
我的最终目标是找到并删除空的xml节点(在这种情况下为<aarNeighborhoodName/>
)。
使用漂亮的xml我找到一个空标签(这是正确的):
> doc.xpath("//*[not(text())]")
=> [#<Nokogiri::XML::Element:0x1862238 name="aarNeighborhoodName">]
> doc.xpath("//*[not(text())]").length
=> 1
将xml放在一行上我有
> doc.xpath("//*[not(text())]").length
=> 6
这是错误的,因为我没有六个空的xml节点。
如何使用单行xml文档使xpath工作?
谢谢
答案 0 :(得分:1)
//*[not(text())]
将为您提供所有没有任何直接子节点的文本节点元素。当您的XML全部在一行上时,除osName
和osVersion
之外的所有元素都是如此,因为它们没有任何子文本节点,只有子元素。当XML被漂亮打印时,大多数元素都有文本节点子节点,它们完全由空格组成,这就是为什么它在这种情况下似乎“有效”。
如果要测试完全为空的元素,根本没有子节点(文本节点,元素,注释......),请使用
//*[not(node())]
请注意,属性节点在XPath数据模型中不被视为“子”,因此仍会选择<emptyElement with="attribute" />
之类的内容。如果你想要排除那些,那么你需要
//*[not(@*|node())]