Как мы можем проанализировать данные XML, которые содержат узлы с тегами пространства имен XML в Python? - PullRequest
2 голосов
/ 31 октября 2019

Я получаю XML в качестве ответа, поэтому хочу его проанализировать. Я перепробовал много библиотек Python, но не получил желаемых результатов. Поэтому, если вы можете помочь, это будет очень благодарно.

Следующий код возвращает None:

xmlResponse = ET.fromstring(context.response_document)
a = xmlResponse.findall('.//Body')
print(a)

Образец XML-данных:

<S:Envelope
       xmlns:S="http://www.w3.org/2003/05/soap-envelope">
       <S:Header>
           <wsa:Action s:mustUnderstand="1"
               xmlns:s="http://www.w3.org/2003/05/soap-envelope"
               xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:ihe:iti:2007:RegistryStoredQueryResponse
           </wsa:Action>
       </S:Header>
       <S:Body>
           <query:AdhocQueryResponse status="urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success"
               xmlns:query="urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0">
               <rim:RegistryObjectList
                   xmlns:rim="u`enter code here`rn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0"/>
               </query:AdhocQueryResponse>
           </S:Body>
       </S:Envelope>

Я хочучтобы получить статус от него, который находится в теле. Если вы можете предложить некоторые изменения в какой-либо библиотеке, пожалуйста, помогите мне. Спасибо

1 Ответ

0 голосов
/ 01 ноября 2019

Учитывая следующий базовый код:

import xml.etree.ElementTree as ET

root = ET.fromstring(xml)

Давайте построим поверх него, чтобы получить желаемый результат.

Ваш начальный поиск для .//Body x-path возвращает NONE, потому что онне существует в вашем XML-ответе.

Каждый тег в вашем XML имеет пространство имен , связанное с ним. Более подробную информацию о пространствах имен xml можно найти здесь .

Рассмотрим следующую строку со значением xmlns (пространство имен xml):

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">

Значение пространства именS установлено на http://www.w3.org/2003/05/soap-envelope.

Замена S в {S}Envelope на указанное выше значение даст вам итоговый тег для поиска в вашем XML:

root.find('{http://www.w3.org/2003/05/soap-envelope}Envelope') #top most node

Нам нужно сделать то же самое для <S:Body>.


Чтобы получить <S:Body> элементов и их дочерних узлов, вы можете сделать следующее:

body_node = root.find('{http://www.w3.org/2003/05/soap-envelope}Body')

for response_child_node in list(body_node):
  print(response_child_node.tag) #tag of the child node
  print(response_child_node.get('status')) #the status you're looking for

Выходы:

{urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0}AdhocQueryResponse
urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success

В качестве альтернативы

Вы также можете напрямую найти все {query}AdhocQueryResponse в своем XML, используя:

response_nodes = root.findall('.//{urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0}AdhocQueryResponse')

for response in response_nodes:
  print(response.get('status'))

Выходы:

urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success
...