Как анализировать XML-данные с некоторыми элементами, не отформатированными в xml, в Python

#xml-parsing #lxml #cisco

Вопрос:

У меня есть следующий ответ от CUCM api:

 <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:executeSQLQueryResponse xmlns:ns="http://www.cisco.com/AXL/API/12.5"><return><row><pkid>63d1f8a1-0964-caa0-d496-ff91340c236c</pkid><userid>Semenova.LA</userid><firstname/><lastname>Семенова</lastname><snrenabled>t</snrenabled><devicecount>1</devicecount><licensetype>Enhanced         </licensetype><licenses>1</licenses></row></return></ns:executeSQLQueryResponse></soapenv:Body></soapenv:Envelope>
 

Я попытался проанализировать этот ответ. Я использовал библиотеку lxml.

 from lxml import etree

root = etree.fromstring(response)
 

Но я получил следующую ошибку

Файл «srclxmletree.pyx», строка 3237, в файле lxml.etree.из файла строки «srclxmlparser.pxi», строка 1891, в файле lxml.etree._parseMemoryDocument Ошибка значения: строки Юникода с объявлением кодировки не поддерживаются. Пожалуйста, используйте ввод байтов или фрагменты XML без объявления.

Это выглядит как какой-то элемент в ответе в неподдерживаемом, если я сокращу ответ на

 response='''<return><row><pkid>63d1f8a1-0964-caa0-d496-ff91340c236c</pkid><userid>Semenova.LA</userid><firstname/><lastname>Семенова</lastname><snrenabled>t</snrenabled><devicecount>1</devicecount><licensetype>Enhanced         </licensetype><licenses>1</licenses></row></return>'''
 

Все работает, как и ожидалось
Что я должен сделать, чтобы это исправить?
Должен ли я удалить ненужный элемент, такой как:

  <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:executeSQLQueryResponse xmlns:ns="http://www.cisco.com/AXL/API/12.5">
 

Как я могу это сделать?

Спасибо большое!

Ответ №1:

Попробуйте изменить

 root = etree.fromstring(response)
 

Для

 root = etree.fromstring(resp.encode())
 

Комментарии:

1. К сожалению, это не решает проблему » код » <Элемент { schemas.xmlsoap.org/soap/envelope }Конверт в 0x1dcfa363740>

Ответ №2:

Я применил немасштабируемое решение-просто вырезать начальную и конечную строку по шаблону

 cut_string ='''<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:executeSQLQueryResponse xmlns:ns="http://www.cisco.com/AXL/API/12.5">'''
cut_string2 = '''</ns:executeSQLQueryResponse></soapenv:Body></soapenv:Envelope>'''
s = response.replace(cut_string, "")
ss = s.replace(cut_string2, "")
root = etree.fromstring(ss.encode())
 

Есть ли более разумное решение?

Например — получить строку между return>String</return>