Действительно простой способ разобраться с XML в Python?

Как было указано, это зависит от типа. Для встроенных типов данных лучше всего перейти по значению.

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

Если вы занимаетесь программированием шаблонов, вы обычно вынуждены всегда передавать const ref, поскольку вы не знаете типов Передача штрафов за передачу чего-то плохого по значению намного хуже, чем штрафы за прохождение встроенного типа по const ref.

24
задан Community 23 May 2017 в 12:16
поделиться

9 ответов

Вы хотите тонкий шпон? Это легко приготовить. Попробуйте в качестве начала следующую тривиальную оболочку вокруг ElementTree:

# geetree.py
import xml.etree.ElementTree as ET

class GeeElem(object):
    """Wrapper around an ElementTree element. a['foo'] gets the
       attribute foo, a.foo gets the first subelement foo."""
    def __init__(self, elem):
        self.etElem = elem

    def __getitem__(self, name):
        res = self._getattr(name)
        if res is None:
            raise AttributeError, "No attribute named '%s'" % name
        return res

    def __getattr__(self, name):
        res = self._getelem(name)
        if res is None:
            raise IndexError, "No element named '%s'" % name
        return res

    def _getelem(self, name):
        res = self.etElem.find(name)
        if res is None:
            return None
        return GeeElem(res)

    def _getattr(self, name):
        return self.etElem.get(name)

class GeeTree(object):
    "Wrapper around an ElementTree."
    def __init__(self, fname):
        self.doc = ET.parse(fname)

    def __getattr__(self, name):
        if self.doc.getroot().tag != name:
            raise IndexError, "No element named '%s'" % name
        return GeeElem(self.doc.getroot())

    def getroot(self):
        return self.doc.getroot()

Вы вызываете ее так:

>>> import geetree
>>> t = geetree.GeeTree('foo.xml')
>>> t.xml_api_reply.weather.forecast_information.city['data']
'Mountain View, CA'
>>> t.xml_api_reply.weather.current_conditions.temp_f['data']
'68'
8
ответ дан Owen S. 23 May 2017 в 12:16
поделиться

Я нашел следующий модуль python-simplexml , который в попытках автора получить что-то похожее на SimpleXML из PHP действительно является small wrapper around ElementTree. Это менее 100 строк, но, кажется, делает то, что было запрошено:

>>> import SimpleXml
>>> x = SimpleXml.parse(urllib.urlopen('http://www.google.com/ig/api?weather=94043'))
>>> print x.weather.current_conditions.temp_f['data']
58
1
ответ дан Nas Banov 23 May 2017 в 12:16
поделиться

Если вы не возражаете против использования сторонней библиотеки, то BeautifulSoup выполнит почти то, что вы просите:

>>> from BeautifulSoup import BeautifulStoneSoup
>>> soup = BeautifulStoneSoup('''<snip>''')
>>> soup.xml_api_reply.weather.current_conditions.temp_f['data']
u'68'
2
ответ дан Mike Boers 23 May 2017 в 12:16
поделиться

Проект suds предоставляет клиентскую библиотеку веб-служб, которая работает почти так же, как вы описываете - предоставьте ей wsdl, а затем используйте фабричные методы для создания определенных типов (и обработки ответов тоже!).

0
ответ дан 28 November 2019 в 23:57
поделиться

lxml уже упоминался. Вы также можете проверить lxml.objectify для некоторых действительно простых манипуляций.

>>> from lxml import objectify
>>> tree = objectify.fromstring(your_xml)
>>> tree.weather.attrib["module_id"]
'0'
>>> tree.weather.forecast_information.city.attrib["data"]
'Mountain View, CA'
>>> tree.weather.forecast_information.postal_code.attrib["data"]
'94043'
15
ответ дан 28 November 2019 в 23:57
поделиться

Если вы еще не сделали этого, я бы посоветовал изучить DOM API для Python. DOM - это довольно широко используемая система интерпретации XML, поэтому он должен быть довольно надежным.

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

-1
ответ дан 28 November 2019 в 23:57
поделиться

Взгляните на Amara 2, особенно на Bindery часть этого руководства .

Это работает примерно так, как вы описываете.

С другой стороны. Методы ElementTree find * () могут дать вам 90% этого и поставляются вместе с Python.

3
ответ дан 28 November 2019 в 23:57
поделиться

Я считаю, что встроенный xml-модуль python сделает свое дело. Посмотрите "xml.parsers.expat"

xml.parsers.expat

1
ответ дан 28 November 2019 в 23:57
поделиться

Я настоятельно рекомендую lxml.etree и xpath для синтаксического анализа и анализа ваших данных. Вот полный пример. Я обрезал xml, чтобы его было легче читать.

import lxml.etree

s = """<?xml version="1.0" encoding="utf-8"?>
<xml_api_reply version="1">
  <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" >
    <forecast_information>
      <city data="Mountain View, CA"/> <forecast_date data="2010-06-23"/>
    </forecast_information>
    <forecast_conditions>
      <day_of_week data="Sat"/>
      <low data="59"/>
      <high data="75"/>
      <icon data="/ig/images/weather/partly_cloudy.gif"/>
      <condition data="Partly Cloudy"/>
    </forecast_conditions>
  </weather>
</xml_api_reply>"""

tree = lxml.etree.fromstring(s)
for weather in tree.xpath('/xml_api_reply/weather'):
    print weather.find('forecast_information/city/@data')[0]
    print weather.find('forecast_information/forecast_date/@data')[0]
    print weather.find('forecast_conditions/low/@data')[0]
    print weather.find('forecast_conditions/high/@data')[0]
4
ответ дан 28 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: