Разбор XML в хеш-таблицу - PullRequest
       33

Разбор XML в хеш-таблицу

4 голосов
/ 15 декабря 2009

У меня есть XML-файл в следующем формате:

<doc>
<id name="X">
  <type name="A">
    <min val="100" id="80"/>
    <max val="200" id="90"/>
   </type>
  <type name="B">
    <min val="100" id="20"/>
    <max val="20" id="90"/>
  </type>
</id>

<type...>
</type>
</doc>

Я хотел бы проанализировать этот документ и создать хеш-таблицу

{X: {"A": [(100,80), (200,90)], "B": [(100,20), (20,90)]}, Y: .....} 

Как бы я это сделал в Python?

Ответы [ 6 ]

12 голосов
/ 15 декабря 2009

Я не согласен с предложением в других ответах использовать minidom - это так себе адаптация Python стандарта, изначально задуманного для других языков, пригодного для использования, но не очень подходящего. Рекомендуемый подход в современном Python: ElementTree .

Тот же интерфейс также реализован, быстрее, в стороннем модуле lxml , но если вам не нужна невероятная скорость, версия, включенная в стандартную библиотеку Python, подходит (и в любом случае быстрее, чем minidom) - Ключевым моментом является программирование на этот интерфейс, тогда вы всегда можете переключиться на другую реализацию того же интерфейса в будущем, если хотите, с минимальными изменениями в вашем собственном коде.

Например, после необходимых импортов & c следующий код является минимальной реализацией вашего примера (он не проверяет правильность XML, просто извлекает данные в предположении корректности - добавить различные виды проверок довольно легко курс):

from xml.etree import ElementTree as et  # or, import any other, faster version of ET

def xml2data(xmlfile):
  tree = et.parse(xmlfile)
  data = {}
  for anid in tree.getroot().getchildren():
    currdict = data[anid.get('name')] = {}
    for atype in anid.getchildren():
      currlist = currdict[atype.get('name')] = []
      for c in atype.getchildren():
        currlist.append((c.get('val'), c.get('id')))
  return data

Это дает желаемый результат с учетом вашего образца ввода.

3 голосов
/ 16 декабря 2009

Не изобретайте велосипед. Используйте Amara toolkit. В любом случае имена переменных - это просто ключи в словаре. http://www.xml3k.org/Amara

2 голосов
/ 15 декабря 2009

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

Сложи это, похоже, делай, что хочешь. Некоторые значения читаются по положению атрибута, а не по имени атрибута. И нет обработки ошибок. И print () в конце означает его Python 3.x.

Я оставлю это как упражнение, чтобы улучшить это, просто хотел опубликовать фрагмент, чтобы вы начали.

Счастливого взлома! :)

xml.txt

<doc>
<id name="X">
  <type name="A">
    <min val="100" id="80"/>
    <max val="200" id="90"/>
   </type>
  <type name="B">
    <min val="100" id="20"/>
    <max val="20" id="90"/>
  </type>
</id>
</doc>

parsexml.py

from xml.dom import minidom
data={}
doc=minidom.parse("xml.txt")
for n in doc.childNodes[0].childNodes:
    if n.localName=="id":
        id_name = n.attributes.item(0).nodeValue
        data[id_name] = {}
        for j in n.childNodes:
            if j.localName=="type":
                type_name = j.attributes.item(0).nodeValue
                data[id_name][type_name] = [(),()]
                for k in j.childNodes:
                    if k.localName=="min":
                        data[id_name][type_name][0] = \
                            (k.attributes.item(1).nodeValue, \
                             k.attributes.item(0).nodeValue)
                    if k.localName=="max":
                        data[id_name][type_name][1] = \
                            (k.attributes.item(1).nodeValue, \
                             k.attributes.item(0).nodeValue)
print (data)

Выход:

{'X': {'A': [('100', '80'), ('200', '90')], 'B': [('100', '20'), ('20', '90')]}}
2 голосов
/ 15 декабря 2009

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

Документы довольно хороши, так что вы должны быстро приступить к работе.

Dan.

1 голос
/ 15 декабря 2009

Другая библиотека для разбора XML: http://www.crummy.com/software/BeautifulSoup/

0 голосов
/ 15 декабря 2009

Почему бы не попробовать что-то вроде библиотеки PyXml . У них много документации и учебных пособий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...