Подтвердить что ты не робот

Есть ли какой-нибудь анализатор Python XML, который был разработан с учетом людей?

Мне нравится Python, но я не хочу писать 10 строк, чтобы получить атрибут от элемента. Может быть, это только я, но minidom не то, что mini. Код, который я должен написать для того, чтобы разбирать что-то, используя его, очень похож на Java-код.

Есть ли что-то более user-friendly? Что-то с перегруженными операторами и которое отображает элементы в объекты?

Я хотел бы иметь доступ к этому:


<root>
<node value="30">text</node>
</root>

как-то вроде этого:


obj = parse(xml_string)
print obj.node.value

и не использовать getChildren или некоторые другие подобные методы.

4b9b3361

Ответ 1

Вы должны взглянуть на ElementTree. Это не делает именно то, что вы хотите, но это намного лучше, чем мини-. Если я правильно помню, начиная с python 2.4, он включался в стандартные библиотеки. Для большей скорости используйте cElementTree. Для более высокой скорости (и дополнительных функций) вы можете использовать lxml (проверьте API-интерфейс объекта для ваших потребностей/подходов).

Я должен добавить, что BeautifulSoup частично отчасти то, что вы хотите. Там также Amara, которые имеют такой подход.

Ответ 2

Я на самом деле написал библиотеку, которая делает все так, как вы ее себе представляли. Библиотека называется "xe", и вы можете ее получить: http://home.avvanta.com/~steveha/xe.html

xe может импортировать XML, чтобы вы могли работать с данными объектно-ориентированным способом. Он фактически использует xml.dom.minidom для синтаксического анализа, но затем он просматривает полученное дерево и упаковывает данные в объекты xe.

EDIT: Хорошо, я пошел дальше и реализовал ваш пример в xe, чтобы вы могли видеть, как это работает. Вот классы для реализации XML, который вы показали:

import xe

class Node(xe.TextElement):
    def __init__(self, text="", value=None):
        xe.TextElement.__init__(self, "node", text)
        if value is not None:
            self.attrs["value"] = value

class Root(xe.NestElement):
    def __init__(self):
        xe.NestElement.__init__(self, "root")
        self.node = Node()

И вот пример использования вышеизложенного. Я поместил ваш образец XML в файл с именем example.xml, но вы также можете просто вставить его в строку и передать строку.

>>> root = Root()
>>> print root
<root/>
>>> root.import_xml("example.xml")
<Root object at 0xb7e0c52c>
>>> print root
<root>
    <node value="30">text</node>
</root>
>>> print root.node.attrs["value"]
30
>>>

Обратите внимание, что в этом примере тип "значение" будет строкой. Если вам действительно нужны атрибуты другого типа, это тоже возможно с небольшим количеством работы, но я не стал беспокоиться об этом примере. (Если вы посмотрите на PyFeed, для OPML есть класс, у которого есть атрибут, который не является текстом.)

Ответ 3

У меня была такая же потребность в простом XML-синтаксисе и после долгого времени, потраченного на проверку разных библиотек, я нашел xmltramp.

На основе вашего примера xml:

import xmltramp

xml_string = """<root>
<node value="30">text</node>
</root>"""

obj = xmltramp.parse(xml_string)
print obj.node('value')             # 30
print str(obj.node)                 # text

Я не нашел ничего более удобного для пользователя.

Ответ 4

Я потратил довольно много времени на выполнение приведенных выше примеров и через репозитории, перечисленные в разделе pip.

Самый простой (и наиболее Pythonic) способ анализа XML, который я нашел до сих пор, был XMLToDict - https://github.com/martinblech/xmltodict

Пример из документации, доступной в GitHub выше, скопирован ниже; Это сделало жизнь ОЧЕНЬ простой и ЛЕГКО для меня много раз;

>>> doc = xmltodict.parse("""
... <mydocument has="an attribute">
...   <and>
...     <many>elements</many>
...     <many>more elements</many>
...   </and>
...   <plus a="complex">
...     element as well
...   </plus>
... </mydocument>
... """)
>>>
>>> doc['mydocument']['@has']
u'an attribute'
>>> doc['mydocument']['and']['many']
[u'elements', u'more elements']
>>> doc['mydocument']['plus']['@a']
u'complex'
>>> doc['mydocument']['plus']['#text']
u'element as well'

Он работает очень хорошо и дал мне то, что я искал. Однако, если вы смотрите на обратные преобразования, это совсем другое дело.