使用ElementTree示例在Python中解析XML

Cas*_*sey 62 python xml elementtree

我很难找到一个如何使用Element Tree在python中解析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>
Run Code Online (Sandbox Code Playgroud)

我能够使用硬编码方法做我需要的事情.但我需要我的代码更有活力.这是有效的:

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
Run Code Online (Sandbox Code Playgroud)

以下是我尝试过的一些事情,其中​​没有一个有效,报告说他们找不到时间序列(或我尝试过的任何其他内容):

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

tree = ET.parse(sample.xml)
doc = tree.getroot()
doc.find('timeSeries')
Run Code Online (Sandbox Code Playgroud)

基本上,我想加载xml文件,搜索timeSeries标记,并遍历值标记,返回dateTime和标记本身的值; 我在上面的例子中所做的一切,但不是硬编码我感兴趣的xml部分.有人能指出我的一些例子,或者给我一些关于如何解决这个问题的建议?


谢谢你的帮助.使用以下两个建议对我提供的示例文件起作用,但是,它们不能在完整文件上工作.这是我使用Ed Carrel的方法从真实文件中得到的错误:

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

我认为在它不喜欢的真实文件中有一些东西,所以我逐渐删除了东西直到它工作.以下是我更改的行:

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>
Run Code Online (Sandbox Code Playgroud)

删除具有'xsi:...'的属性可以解决问题.'xsi:...'不是有效的XML吗?我很难以编程方式删除它们.任何建议的工作?

这是完整的XML文件:http://www.sendspace.com/file/lofcpt


当我最初提出这个问题时,我并不知道XML中的命名空间.现在我知道发生了什么,我不必删除"xsi"属性,它们是命名空间声明.我只是将它们包含在我的xpath搜索中.有关lxml中命名空间的更多信息,请参阅此页面.

Ed *_*rel 46

所以我现在在我的盒子上有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
Run Code Online (Sandbox Code Playgroud)

得到以下回复:

{'name': 'NWIS Time Series Instantaneous Values'}
Run Code Online (Sandbox Code Playgroud)

它似乎找到了timeSeries元素而无需使用数字索引.

现在有用的是当你说"它不起作用"时知道你的意思.由于它在给定相同输入的情况下对我有效,因此ElementTree不太可能以某种明显的方式被破坏.使用任何错误消息,回溯或您可以提供的任何内容更新您的问题,以帮助我们为您提供帮助.

  • 对于新的python版本,导入已更改为:import xml.etree.ElementTree as ET (29认同)

Ste*_*ven 21

如果我理解你的问题:

for elem in doc.findall('timeSeries/values/value'):
    print elem.get('dateTime'), elem.text
Run Code Online (Sandbox Code Playgroud)

或者如果你愿意(如果只有一次出现timeSeries/values:

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

findall()方法返回所有匹配元素的列表,而find()仅返回第一个匹配元素.第一个示例遍历所有找到的元素,第二个循环遍历元素的子元素values,在这种情况下导致相同的结果.

但是,我没有看到找不到问题的地方timeSeries.也许你刚忘了getroot()电话?(请注意,您并不真正需要它,因为您也可以使用elementtree本身,如果您将路径表达式更改为例如/timeSeriesResponse/timeSeries/values//timeSeries/values)