如何解析分层XML String

时间:2016-01-21 19:36:12

标签: python xml

我有一个xml字符串,我需要在python中解析,如下所示:

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
     <s:Body>
         <PostLoadsResponse xmlns="http://webservices.truckstop.com/v11">
             <PostLoadsResult xmlns:a="http://schemas.datacontract.org/2004/07/WebServices.Objects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                 <Errors xmlns="http://schemas.datacontract.org/2004/07/WebServices">
                    <Error>
                         <ErrorMessage>Invalid Location</ErrorMessage>
                    </Error>
                </Errors>
            </PostLoadsResult>
        </PostLoadsResponse>
    </s:Body>
</s:Envelope>'

我在使用xmltree访问此树的错误消息时遇到了问题:

import xml.etree.ElementTree as ET
ET.fromstring(text).findall('{http://schemas.xmlsoap.org/soap/envelope/}Body')[0].getchildren()[0].getchildren()[0].getchildren()

3 个答案:

答案 0 :(得分:5)

您需要handle namespaces并且可以使用xml.etree.ElementTree

执行此操作
tree = ET.fromstring(data)

namespaces = {
    's': 'http://schemas.xmlsoap.org/soap/envelope/', 
    'd': "http://schemas.datacontract.org/2004/07/WebServices"
}
print(tree.find(".//d:ErrorMessage", namespaces=namespaces).text)

打印Invalid Location

答案 1 :(得分:2)

使用部分XPath support

ET.fromstring(text).find('.//{http://schemas.datacontract.org/2004/07/WebServices}ErrorMessage')

这将指示它在任何深度找到名为ErrorMessage且名称空间为http://schemas.datacontract.org/2004/07/WebServices的第一个元素。

但是,使用

之类的东西可能会更快
ET.fromstring(text).find('{http://schemas.xmlsoap.org/soap/envelope/}Body').find('{http://webservices.truckstop.com/v11}PostLoadsResponse').find('{http://webservices.truckstop.com/v11}PostLoadsResult').find('{http://schemas.datacontract.org/2004/07/WebServices}Errors').find('{http://schemas.datacontract.org/2004/07/WebServices}Error').find('{http://schemas.datacontract.org/2004/07/WebServices}ErrorMessage'

如果您知道您的消息将始终包含这些元素。

答案 2 :(得分:2)

您可以使用树上的getiterator方法迭代其中的项目。您可以查看每个项目的tag,看看它是否正确。

>>> err = [node.text for node in tree.getiterator() if node.tag.endswith('ErrorMessage')]
>>> err
['Invalid Location']