Populating Python list using data obtained from lxml xpath command

本小妞迷上赌 提交于 2019-12-11 05:41:36

问题


I'm reading instrument data from a specialty server that delivers the info in xml format. The code I've written is: from 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

And the results I get are:

$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, nothing is coming out. I've tried using /value in place of the /text() in the xpath call, but the results are unchanged. Is my problem:

1) An incorrect xpath command in the for loop? or

2) A problem in the way I've structured list variable dmtVal ? or

3) Something else I'm missing completely?

I'd welcome any suggestions! Thanks in advance...


回答1:


Counting <dmt/> tags and then iterating over them by index is both inefficient and un-Pythonic. Apart from that you are using wrong syntax (slice instead of index) for indexing arrays. In fact you don't need to index the val at all, to do it Pythonic way use list comprehensions.

Here's a slightly modified version of what stranac suggested:

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)



回答2:


dmtVal[i:0] is the syntax for slicing.
You probably wanted indexing: dmtVal[i][0]. But that also wouldn't work.

You don't typically loop over the indices of a list in python, you loop over it's elements instead.
So, you'd use

for element in some_list:

rather than

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


The way you handle your xpaths is also wrong.

Something like this should work(not tested):

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



回答3:


Can you explain this:

dmtVal[i:0]

If the iteration starts with a count of 0 and increments over times, you're not actually storing anything in the list.



来源:https://stackoverflow.com/questions/11962576/populating-python-list-using-data-obtained-from-lxml-xpath-command

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!