Я не могу найти информацию, как разобрать мой XML с пространством имен:питон etree с XPath и пространства имен с префиксом
У меня есть этот XML:
<par:Request xmlns:par="http://somewhere.net/actual">
<par:actual>blabla</par:actual>
<par:documentType>string</par:documentType>
</par:Request>
И пытался разобрать его:
dom = ET.parse(u'C:\\filepath\\1.xml')
rootxml = dom.getroot()
for subtag in rootxml.xpath(u'//par:actual'):
#do something
print(subtag)
И получил исключение, поскольку он не знает о префиксе пространства имен. Есть ли лучший способ решить эту проблему, считая, что этот скрипт не будет знать о файле, который он будет анализировать, и тег будет искать?
Поиск Интернет и StackOverflow я нашел, что если я буду добавлять туда:
namespace = {u'par': u"http://somewhere.net/actual"}
for subtag in rootxml.xpath(u'//par:actual', namespaces=namespace):
#do something
print(subtag)
Это работает. Отлично. Но я не знаю, какой XML я буду разбирать, и поиск тега (например, //par:actual
) также неизвестен моему сценарию. Поэтому мне нужно как-то найти способ извлечения пространства имен из XML.
Я нашел много способов, как извлечь URI пространства имен, таких как:
print(rootxml.tag)
print(rootxml.xpath('namespace-uri(.)'))
print(rootxml.xpath('namespace-uri(/*)'))
Но как я должен извлечь префикс, чтобы создать словарь, который ElementTree хочет от меня? Я не хочу использовать регулярное выражение monster over xml body для извлечения префикса, я считаю, что для этого существует поддерживаемый способ, не так ли?
А может быть, существуют какие-то методы для извлечения из пространства имен ETree из XML в качестве словаря (как хочет ETree!) Без манипуляций руками?
Да, я подумал об этом. Сначала я даже пытался побудить пользователя использовать '{http://somewhere.net/actual} actual', чтобы убедиться, что он понимает, что именно он использует. Но это также не работает, и etree не понимают «//{...}actual», выбрасывая исключение. Но тогда я просто добавил пространство имен ввода от пользователя и сравнил его с существующим пространством имен xml, поэтому эта проблема была решена. – Arkady
Класс ETXPath должен решить проблему непонятия синтаксиса {}, но вы не сможете использовать его с методом '.xpath()', вы должны использовать его, как класс XPath (при использовании скомпилированных выражений xpath). Пример: 'path = etree.ETXPath ('// {http://somewhere.net/actual} actual')', а затем использовать его 'results = path (rootxml)' – Steven
Это правда. Я буду вам советоваться :-) – Arkady