Development Tip

ElementTree 예제를 사용하여 Python에서 XML 구문 분석

yourdevel 2020. 11. 28. 12:35
반응형

ElementTree 예제를 사용하여 Python에서 XML 구문 분석


Element Tree를 사용하여 파이썬에서 XML을 구문 분석하는 방법에 대한 좋은 기본 예제를 찾는 데 어려움을 겪고 있습니다. 내가 찾은 바에 따르면 이것은 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

다음은 내가 시도한 몇 가지 작업입니다. 아무도 작동하지 않았으며 timeSeries (또는 내가 시도한 다른 항목)를 찾을 수 없다고보고했습니다.

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

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

기본적으로 xml 파일을로드하고, timeSeries 태그를 검색하고, 값 태그를 반복하여 dateTime과 태그 자체의 값을 반환하고 싶습니다. 위의 예에서 제가하고있는 모든 작업은 제가 관심있는 xml 섹션을 하드 코딩하지는 않습니다. 누구든지 저에게 몇 가지 예를 알려 주거나이 작업을 수행하는 방법에 대한 몇 가지 제안을 할 수 있습니까?


모든 도움에 감사드립니다. 아래 제안 사항을 모두 사용하여 내가 제공 한 샘플 파일에서 작동했지만 전체 파일에서는 작동하지 않았습니다. Ed Carrel의 방법을 사용할 때 실제 파일에서 얻은 오류는 다음과 같습니다.

 (<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>

Removing the attributes that have 'xsi:...' fixed the problem. Is the 'xsi:...' not valid XML? It will be hard for me to remove these programmatically. Any suggested work arounds?

Here is the full XML file: http://www.sendspace.com/file/lofcpt


When I originally asked this question, I was unaware of namespaces in XML. Now that I know what's going on, I don't have to remove the "xsi" attributes, which are the namespace declarations. I just include them in my xpath searches. See this page for more info on namespaces in lxml.


So I have ElementTree 1.2.6 on my box now, and ran the following code against the XML chunk you posted:

import elementtree.ElementTree as ET

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

print thingy.attrib

and got the following back:

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

It appears to have found the timeSeries element without needing to use numerical indices.

What would be useful now is knowing what you mean when you say "it doesn't work." Since it works for me given the same input, it is unlikely that ElementTree is broken in some obvious way. Update your question with any error messages, backtraces, or anything you can provide to help us help you.


If I understand your question correctly:

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

or if you prefer (and if there is only one occurrence of timeSeries/values:

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

The findall() method returns a list of all matching elements, whereas find() returns only the first matching element. The first example loops over all the found elements, the second loops over the child elements of the values element, in this case leading to the same result.

I don't see where the problem with not finding timeSeries comes from however. Maybe you just forgot the getroot() call? (note that you don't really need it because you can work from the elementtree itself too, if you change the path expression to for example /timeSeriesResponse/timeSeries/values or //timeSeries/values)

참고URL : https://stackoverflow.com/questions/1786476/parsing-xml-in-python-using-elementtree-example

반응형