2016-01-21 2 views
1

У меня есть XML-строка, что мне нужно, чтобы разобрать в питоне, который выглядит следующим образом:Как разобрать многоуровневое XML Строки

<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() 

ответ

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' 

Если вы знаете ваше сообщение всегда будет содержать эти элементы.

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.

2

Вы можете использовать метод getiterator на дереве, чтобы перебирать элементы в нем. Вы можете проверить tag на каждый элемент, чтобы убедиться, что он правильный.

>>> err = [node.text for node in tree.getiterator() if node.tag.endswith('ErrorMessage')] 
>>> err 
['Invalid Location'] 
Смежные вопросы