如何在给定以下xml的情况下使用查询元素树findall('Email')
?
<DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>
<RecipientStatus>
<Type>Signer</Type>
<Email>joe@gmail.com</Email>
<UserName>Joe Shmoe</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2015-05-04T09:58:01.947</Sent>
<Delivered>2015-05-04T09:58:14.403</Delivered>
<Signed>2015-05-04T09:58:29.473</Signed>
</RecipientStatus>
</EnvelopeStatus>
</DocuSignEnvelopeInformation>
我觉得它与命名空间有关,但我不确定。我看着docs,没有运气。
tree = <xml.etree.ElementTree.ElementTree object at 0x7f27a47c4fd0>
root = tree.getroot()
root
<Element '{http://www.docusign.net/API/3.0}DocuSignEnvelopeInformation' at 0x7f27a47b8a48>
root.findall('Email')
[]
答案 0 :(得分:3)
您应该更仔细地阅读文档,特别是Parsing XML with Namespaces部分,其中包含一个几乎完全符合您要求的示例。
但即使没有文档,答案实际上也包含在您的示例输出中。当您打印文档的根元素时......
>>> tree = etree.parse(open('data.xml'))
>>> root = tree.getroot()
>>> root
<Element {http://www.docusign.net/API/3.0}DocuSignEnvelopeInformation at 0x7f972cd079e0>
...您可以看到它使用名称空间前缀(DocuSignEnvelopeInformation
)打印了根元素名称({http://www.docusign.net/API/3.0}
)。您可以将此相同的前缀用作findall
的参数的一部分:
>>> root.findall('{http://www.docusign.net/API/3.0}Email')
但这本身并不起作用,因为这只会找到Email
元素,它们是根元素的直接子元素。您需要提供ElementPath表达式,以使findall
执行整个文档的搜索。这有效:
>>> root.findall('.//{http://www.docusign.net/API/3.0}Email')
[<Element {http://www.docusign.net/API/3.0}Email at 0x7f972949a6c8>]
您还可以使用XPath和名称空间前缀执行类似的搜索,如下所示:
>>> root.xpath('//docusign:Email',
... namespaces={'docusign': 'http://www.docusign.net/API/3.0'})
[<Element {http://www.docusign.net/API/3.0}Email at 0x7f972949a6c8>]
这使您可以使用类似XML的namespace:
前缀而不是LXML命名空间语法。