Разбор 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.
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.textThe
findall()метод возвращает список всех совпадающих элементов, тогда какfind()возвращает только первый найденный элемент. Первый пример перебирает все найденные элементы, второй перебирает дочерние элементыvaluesэлемент, в этом случае приводящий к тому же результату.Я не вижу где проблема с не найти
timeSeriesпроисходит от однако. Может быть, вы просто забылиgetroot()звонок? (обратите внимание, что вам это действительно не нужно, потому что вы можете работать и с самим elementtree, если вы измените выражение пути, например/timeSeriesResponse/timeSeries/valuesили//timeSeries/values)
Comments