【问题标题】:Parse XML namespace with Element Tree findall使用 Element Tree findall 解析 XML 命名空间
【发布时间】:2015-05-04 21:04:24
【问题描述】:

在给定以下 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')
[]

【问题讨论】:

    标签: python xml docusignapi


    【解决方案1】:

    您应该更仔细地阅读文档,尤其是 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>
    

    ...您可以看到它打印了带有命名空间前缀 ({http://www.docusign.net/API/3.0}) 的根元素名称 (DocuSignEnvelopeInformation)。您可以使用相同的前缀作为 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 命名空间语法。

    【讨论】:

    • 谢谢,非常有帮助。我想使用你的最后一个例子 root.xpath 但它看起来不像 elementtree 元素支持 .xpath AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'xpath'
    • 此答案假设您使用的是 lxml.etree。
    猜你喜欢
    • 1970-01-01
    • 2021-05-03
    • 2014-01-10
    • 2010-11-08
    • 2018-07-15
    • 2012-06-11
    • 2015-09-08
    相关资源
    最近更新 更多