使用从lxml xpath命令获取的数据填充Python列表

时间:2012-08-15 00:06:00

标签: python xpath lxml

我正在从专业服务器上读取仪器数据,该服务器以xml格式提供信息。我写的代码是:     来自lxml import etree as ET

xmlDoc = ET.parse('http://192.168.1.198/Bench_read.xml')
print ET.tostring(xmlDoc, pretty_print=True)

dmtCount = xmlDoc.xpath('//dmt')
print(len(dmtCount))

dmtVal = []

for i in range(1, len(dmtCount)):
    dmtVal[i:0] = xmlDoc.xpath('./address/text()')
    dmtVal[i:1] = xmlDoc.xpath('./status/text()')
    dmtVal[i:2] = xmlDoc.xpath('./flow/text()')
    dmtVal[i:3] = xmlDoc.xpath('./dp/text()')
    dmtVal[i:4] = xmlDoc.xpath('./inPressure/text()')
    dmtVal[i:5] = xmlDoc.xpath('./actVal/text()')
    dmtVal[i:6] = xmlDoc.xpath('./temp/text()')
    dmtVal[i:7] = xmlDoc.xpath('./valveOnPercent/text()')

print dmtVal

我得到的结果是:

$python XMLparse2.py
<response>

<heartbeat>0x24</heartbeat>

<dmt node="1">

    <address>0x21</address>
    <status>0x01</status>
    <flow>0.000000</flow>
    <dp>0.000000</dp>
    <inPressure>0.000000</inPressure>
    <actVal>0.000000</actVal>
    <temp>0x00</temp>
    <valveOnPercent>0x00</valveOnPercent>

</dmt>

<dmt node="2">

    <address>0x32</address>
    <status>0x01</status>
    <flow>0.000000</flow>
    <dp>0.000000</dp>
    <inPressure>0.000000</inPressure>
    <actVal>0.000000</actVal>
    <temp>0x00</temp>
    <valveOnPercent>0x00</valveOnPercent>

</dmt>

</response>

...Starting to parse XML nodes
2
[]
...Done

Sooo,什么都没有出来。我尝试使用/value代替xpath调用中的/text(),但结果没有改变。是我的问题:

1)for循环中的xpath命令不正确?或

2)我构建列表变量dmtVal的方式有问题吗?或

3)我完全错过了什么?

我欢迎任何建议!提前谢谢......

3 个答案:

答案 0 :(得分:1)

dmtVal[i:0]是切片的语法 您可能想要建立索引:dmtVal[i][0]。但这也行不通。

你通常不会在python中循环遍历列表的索引,而是循环遍历它的元素 所以,你要用

for element in some_list:

而不是

for i in xrange(len(some_list)):
    element = some_list[i]


处理xpath的方式也是错误的。

这样的事情应该有效(未经测试):

from lxml import etree as ET

xml_doc = ET.parse('http://192.168.1.198/Bench_read.xml')
dmts = xml_doc.xpath('//dmt')

dmt_val = []
for dmt in dmts:
    values = []
    values.append(dmt.xpath('./address/text()'))
    # do this for all values
    # making this a loop would be a good idea
    dmt_val.append(values)

print dmt_val

答案 1 :(得分:0)

你能解释一下:

dmtVal[i:0]

如果迭代以0的计数开始并且逐渐增加,那么您实际上并未在列表中存储任何内容。

答案 2 :(得分:0)

计算<dmt/>标签,然后通过索引迭代它们既低效又不具有Pythonic。除此之外,您使用错误的语法(切片而不是索引)来索引数组。事实上,您根本不需要索引val,而是使用列表推导来进行Pythonic方式。

以下是stranac建议的略微修改版本:

from lxml import etree as ET

xmlDoc = ET.parse('http://192.168.1.198/Bench_read.xml')
print ET.tostring(xmlDoc, pretty_print=True)

response = xmlDoc.getroot()

tags = (
    'address',
    'status',
    'flow',
    'dp',
    'inPressure',
    'actVal',
    'temp',
    'valveOnPercent',
)

dmtVal = []

for dmt in response.iter('dmt'):
    val = [dmt.xpath('./%s/text()' % tag) for tag in tags]
    dmtVal.append(val)