使用XPath、etree和Python提取值
我正在用XPath、Python和etree来提取一个值。我对收到的.xml文件没有任何控制权,而且我觉得这个文件似乎有点不合法。
我的方法已经成功提取了我想要检查的文本节点对象。
# This is the tag.
textTag = lastExportTree.xpath("//TEXT_NODE[@PROPERTY = '%s']/TEXT[@ID = '%s']" % (key, id[1]))
# This is a part of the xml. I already have the text node I want to examine.
<TEXT ID="1001" STATE="5" LOCKED="false"><SYSTEMMESSAGE>CALBUY</SYSTEMMESSAGE>Hiho</TEXT>
<TEXT ID="1002" STATE="1" LOCKED="false"/>
<TEXT ID="1003" STATE="5" LOCKED="false">Stack</TEXT>
<TEXT ID="1004" STATE="1" LOCKED="false">Overflow</TEXT>
如果我想访问ID为"1003"的内容,我只需要输入:
print(textTag.text); # Will print 'Stack'
但是ID为"1001"的标签里也包含了SYSTEMMESSAGE标签。我该怎么才能访问内容'HiHo'呢?(textTag.text是无法使用的!)我收到的这个xml是无效的吗?
非常感谢你的回答!
2 个回答
0
假设你在展示 lastExportTree 下面的节点,这段代码应该可以做到:
lastExportTree.xpath('TEXT[@STATE="5" and @LOCKED="false" and SYSTEMMESSAGE]/text()')[0]
这段代码的意思是去找所有名为 TEXT 的子节点,这些节点需要有特定的 STATE 和 LOCKED 属性,并且还要有一个叫 SYSTEMMESSAGE 的子元素。
1
我之前也遇到过这个问题,最后我们得到了这样的解决方案。在我们的情况下,我们想要找到一个元素中所有非脚本和非样式的子元素里的文本。
# Just to pre-compile our XPath. This will get all the text from this element from
# each of the child elements that aren't 'script' or 'style'
textXpath = etree.XPath(
'(.|.//*[not(name()="script")][not(name()="style")])/text()')
# If instead you don't want to include the current element:
# textXpath = etree.XPath(
# './/*[not(name()="script")][not(name()="style")]/text()')
results = ''.join(textXpath(textTag))
这段代码可能看起来不太美观,但这是我们最终使用的办法。