use*_*587 3 python xml docusignapi
findall('Email')给定以下 xml,如何使用查询元素树?
<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>
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,它与命名空间有关,但我不确定。我查看了文档并没有运气。
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')
[]
Run Code Online (Sandbox Code Playgroud)
您应该更仔细地阅读文档,特别是关于使用命名空间解析 XML的部分,其中包含一个几乎正是您想要的示例。
但即使没有文档,答案实际上也包含在您的示例输出中。当您打印文档的根元素时...
>>> tree = etree.parse(open('data.xml'))
>>> root = tree.getroot()
>>> root
<Element {http://www.docusign.net/API/3.0}DocuSignEnvelopeInformation at 0x7f972cd079e0>
Run Code Online (Sandbox Code Playgroud)
...您可以看到它打印了DocuSignEnvelopeInformation带有命名空间前缀 ( {http://www.docusign.net/API/3.0})的根元素名称( )。您可以使用相同的前缀作为参数的一部分findall:
>>> root.findall('{http://www.docusign.net/API/3.0}Email')
Run Code Online (Sandbox Code Playgroud)
但这本身是行不通的,因为这只会找到Email根元素的直接子元素。您需要提供一个ElementPath表达式findall来执行对整个文档的搜索。这有效:
>>> root.findall('.//{http://www.docusign.net/API/3.0}Email')
[<Element {http://www.docusign.net/API/3.0}Email at 0x7f972949a6c8>]
Run Code Online (Sandbox Code Playgroud)
您还可以使用 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>]
Run Code Online (Sandbox Code Playgroud)
这使您可以使用类似 XML 的namespace:前缀而不是 LXML 命名空间语法。