在Python中与LXML一起使用XPath
我有一个python脚本,用于解析XML并将其导出到csv文件的某些感兴趣的元素中。我曾试图改变现在的脚本允许标准下的XML文件的过滤,相当于XPath查询将是:在Python中与LXML一起使用XPath
\DC\Events\Confirmation[contains(TransactionId,"GTEREVIEW")]
当我尝试使用LXML这样做,我的代码是:
xml_file = lxml.etree.parse(xml_file_path)
namespace = "{" + xml_file.getroot().nsmap[None] + "}"
node_list = xml_file.findall(namespace + "Events/" + namespace + "Confirmation[TransactionId='*GTEREVIEW*']")
但这似乎不起作用。谁能帮忙? XML文件的 例子:
<Events>
<Confirmation>
<TransactionId>GTEREVIEW2012</TransactionId>
</Confirmation>
<Confirmation>
<TransactionId>GTEDEF2012</TransactionId>
</Confirmation>
</Events>
所以我想包含一个事务ID,其中包括字符串“GTEREVIEW”全部“确认”的节点。 感谢
findall()
不支持XPath表达式,只有ElementPath(见http://effbot.org/zone/element-xpath.htm)。 ElementPath不支持搜索包含特定字符串的元素。
为什么不使用XPath?假设文件test.xml
包含示例XML,以下工作:
> python
Python 2.7.9 (default, Jun 29 2016, 13:08:31)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
>>> tree=etree.parse("test.xml")
>>> tree.xpath("Confirmation[starts-with(TransactionId, 'GTEREVIEW')]")
[<Element Confirmation at 0x7f68b16c3c20>]
如果你坚持要用findall()
,你能做的最好的就是有TransactionId
子节点的所有Confirmation
元素的列表:
>>> tree.findall("Confirmation[TransactionId]")
[<Element Confirmation at 0x7f68b16c3c20>, <Element Confirmation at 0x7f68b16c3ea8>]
然后您需要手动过滤此列表,如:
>>> [e for e in tree.findall("Confirmation[TransactionId]")
if e[0].text.startswith('GTEREVIEW')]
[<Element Confirmation at 0x7f68b16c3c20>]
如果您的文档CON含有杂质的命名空间,下面将让你有TransactionId
子节点的所有Confirmation
元素,前提是该元素使用默认的命名空间(我用xmlns="file:xyz"
作为默认的命名空间):
>>> tree.findall("//{{{0}}}Confirmation[{{{0}}}TransactionId]".format(tree.getroot().nsmap[None]))
[<Element {file:xyz}Confirmation at 0x7f534a85d1b8>, <Element {file:xyz}Confirmation at 0x7f534a85d128>]
而且当然还有etree.ETXPath
的:
>>> find=etree.ETXPath("//{{{0}}}Confirmation[starts-with({{{0}}}TransactionId, 'GTEREVIEW')]".format(tree.getroot().nsmap[None]))
>>> find(tree)
[<Element {file:xyz}Confirmation at 0x7f534a85d1b8>]
这使您可以组合XPath和名称空间。
//Confirmation[TransactionId[contains(.,'GTEREVIEW')]]
father_tag[child_tag] # select father_tag that has child_tag
[child_tag[filter]] # select select child tag which match filter
[filter]
只是添加一些解释 –
其中是您的xml文件? – SomeDude
我已更新问题。 – naiminp