Разбор XML в Python с помощью примера ElementTree



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



<timeSeriesResponse>
<queryInfo>
<locationParam>01474500</locationParam>
<variableParam>99988</variableParam>
<timeParam>
<beginDateTime>2009-09-24T15:15:55.271</beginDateTime>
<endDateTime>2009-11-23T15:15:55.271</endDateTime>
</timeParam>
</queryInfo>
<timeSeries name="NWIS Time Series Instantaneous Values">
<values count="2876">
<value dateTime="2009-09-24T15:30:00.000-04:00" qualifiers="P">550</value>
<value dateTime="2009-09-24T16:00:00.000-04:00" qualifiers="P">419</value>
<value dateTime="2009-09-24T16:30:00.000-04:00" qualifiers="P">370</value>
.....
</values>
</timeSeries>
</timeSeriesResponse>


Я умею делать то, что мне нужно, используя жесткий метод. Но мне нужен мой код, чтобы быть немного более динамичным. Вот что получилось:



tree = ET.parse(sample.xml)
doc = tree.getroot()

timeseries = doc[1]
values = timeseries[2]

print child.attrib['dateTime'], child.text
#prints 2009-09-24T15:30:00.000-04:00, 550


вот несколько вещей, которые я пробовал, ни один из них не работал, сообщая, что они не могли найти таймсерии (или что-нибудь еще, что я пробовал):



tree = ET.parse(sample.xml)
tree.find('timeSeries')

tree = ET.parse(sample.xml)
doc = tree.getroot()
doc.find('timeSeries')


в принципе, я хочу загрузить xml-файл, найти тег timeSeries и перебрать теги значений, возвращая дату и время и значение самого тега; все, что я делаю в приведенном выше примере, но не жестко кодирует разделы xml, которые меня интересуют. Может ли кто-нибудь указать мне на некоторые примеры или дать мне некоторые предложения о том, как работать с этим?





Спасибо за помощь. Использование обоих приведенных ниже предложений работало над образцом файла, который я предоставил, однако они не работали над полным файлом. Вот ошибка, которую я получаю из реального файла, когда я использую метод Эда Каррела:



 (<type 'exceptions.AttributeError'>, AttributeError("'NoneType' object has no attribute 'attrib'",), <traceback object at 0x011EFB70>)


я понял, что в реальном файле было что-то, что ему не понравилось, поэтому я постепенно удалял вещи, пока это не сработало. Вот строки, которые я изменил:



originally: <timeSeriesResponse xsi:schemaLocation="a URL I removed" xmlns="a URL I removed" xmlns:xsi="a URL I removed">
changed to: <timeSeriesResponse>

originally: <sourceInfo xsi:type="SiteInfoType">
changed to: <sourceInfo>

originally: <geogLocation xsi:type="LatLonPointType" srs="EPSG:4326">
changed to: <geogLocation>


удаление атрибутов, которые имеют ' xsi:...- Исправлена проблема. Является атрибутом xsi:...'недопустимый XML? Так и будет трудно для меня, чтобы удалить эти программными средствами. Любые предлагаемые обходные пути?



вот полный XML-файл:http://www.sendspace.com/file/lofcpt





когда я первоначально задал этот вопрос, я не знал о пространствах имен в XML. Теперь, когда я знаю, что происходит, мне не нужно удалять атрибуты "xsi", которые являются объявлениями пространства имен. Я просто включаю их в свои поиски xpath. Смотрите на этой странице для получения дополнительной информации о пространствах имен в lxml.

726   2  

2 ответов:

Итак, теперь у меня есть ElementTree 1.2.6 на моем поле и выполнил следующий код против XML-фрагмента, который вы опубликовали:

import elementtree.ElementTree as ET

tree = ET.parse("test.xml")
doc = tree.getroot()
thingy = doc.find('timeSeries')

print thingy.attrib

и вот снова:

{'name': 'NWIS Time Series Instantaneous Values'}

похоже, что он нашел элемент timeSeries без необходимости использовать числовые индексы.

сейчас было бы полезно знать, что вы имеете в виду, когда говорите: "это не работает."Поскольку это работает для меня, учитывая тот же вход, маловероятно, что ElementTree сломан каким-то очевидным образом. Обновите свой вопрос с любыми сообщениями об ошибках, обратными следами или всем, что вы можете предоставить, чтобы помочь нам помочь вам.

если я правильно понял ваш вопрос:

for elem in doc.findall('timeSeries/values/value'):
    print elem.get('dateTime'), elem.text

или, если вы предпочитаете (и если есть только одно вхождение timeSeries/values:

values = doc.find('timeSeries/values')
for value in values:
    print value.get('dateTime'), elem.text

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

Я не вижу где проблема с не найти timeSeries происходит от однако. Может быть, вы просто забыли getroot() звонок? (обратите внимание, что вам это действительно не нужно, потому что вы можете работать и с самим elementtree, если вы измените выражение пути, например /timeSeriesResponse/timeSeries/values или //timeSeries/values)

Comments

    Ничего не найдено.