Использование ElementTree для анализа строки XML с пространством имен - PullRequest
2 голосов
/ 15 декабря 2011

Я погуглил штаны безрезультатно.То, что я пытаюсь сделать, очень просто: я хотел бы получить доступ к значению UniqueID в следующем XML, содержащемся в строке, используя ElementTree.

from xml.etree.ElementTree import fromstring

xml_string = """<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>"""

NS = "http://www.example.com/dir/"

tree = fromstring(xml_string)

Я знаю, что должен использовать метод fromstring для анализа строки XML, но я не могу определить, как получить доступ к UniqueID.Я не уверен, как использовать методы find, findall или findtext в отношении пространства имен.

Любая помощь полностью приветствуется.

Ответы [ 2 ]

5 голосов
/ 15 декабря 2011

Следующее должно помочь вам:

>>> tree.findall('*/*')
[<Element '{http://www.example.com/dir/}UniqueID' at 0x10899e450>]

Здесь перечислены все элементы, которые находятся на два уровня ниже корня вашего дерева (элемент UniqueID, в вашем случае).В качестве альтернативы вы можете найти только элемент first на этом уровне, с tree.find().Затем вы можете напрямую получить текстовое содержимое элемента UniqueID:

>>> unique_id_elmt = tree.find('*/*')  # First (and only) element two levels below the root
>>> unique_id_elmt
<Element '{http://www.example.com/dir/}UniqueID' at 0x105ec9450>
>>> unique_id_elmt.text  # Text contained in UniqueID
'abcdefghijklmnopqrstuvwxyz0123456789'

В качестве альтернативы, вы можете напрямую найти некоторый точный элемент, указав его полный путь :

>>> tree.find('{{{0}}}Item/{{{0}}}UniqueID'.format(NS))  # Tags are prefixed with NS
<Element '{http://www.example.com/dir/}UniqueID' at 0x10899ead0>

Как указал Томалак, сайт Фредрика Лунда может содержать полезную информацию;Вы хотите проверить, как могут обрабатываться префиксы : на самом деле может быть более простой способ их обработки, чем указание пути NS в указанном выше методе.

3 голосов
/ 15 декабря 2011

Я знаю, что будут некоторые крики ужаса и понижения моего ответа в качестве ответного удара, поскольку я использую модуль re для анализа строки XML, но учтите, что:

  • В большинстве случаев следующее решение не вызовет проблем

  • Я бы хотел, чтобы downvoters приводил примеры случаев, вызывающих проблемы с моим решением

  • Я не разбираю строку, принимая слово «разбирать» в смысле «получить дерево перед тем, как проанализировать дерево, чтобы найти то, что ищем»;Я анализирую это: я непосредственно нахожу желаемую часть текста там, где она

Я не претендую на то, что XML-строка всегда должна анализироваться с помощью re .Вероятно, в большинстве случаев строка XML должна быть проанализирована с помощью специального анализатора.Я только говорю, что в таких простых случаях, как этот, в которых возможен простой и быстрый анализ, проще использовать инструмент регулярных выражений, который, кстати, быстрее.

import re

xml_string = """<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>"""

print xml_string
print '\n=================================\n'

print re.search('<UniqueID>(.+?)</UniqueID>', xml_string, re.DOTALL).group(1)

result

<ListObjectsResponse xmlns='http://www.example.com/dir/'>
        <Item>
                <UniqueID>abcdefghijklmnopqrstuvwxyz0123456789</UniqueID>
        </Item>
</ListObjectsResponse>

=================================

abcdefghijklmnopqrstuvwxyz0123456789
...