1

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

Red Spanner
  • 149
  • 10

3 Answers3

1

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
stranac
  • 26,638
  • 5
  • 25
  • 30
  • Hi stranac, Yes, I thought I was probably getting both aspects wrong, as I'm a noob at both XML and Python... but this project requires me to learn both simultaneously! It's fun, but not without challenges, as you've pointed out. I'll try this change as soon as I can, though I have to leave now for a meeting. – Red Spanner Aug 15 '12 at 02:03
0

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.

Aesthete
  • 18,622
  • 6
  • 36
  • 45
0

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)
Ihor Kaharlichenko
  • 5,944
  • 1
  • 26
  • 32
  • Hi Ihor, Thanks for this. I'm a relative noob, so some of this is over my head. I'm going to look at it in detail, both as a learning experience but also because it may offer a way forward for some other items I'll need to pull out of similar xml files in the future. – Red Spanner Aug 15 '12 at 16:18
  • I'm new to list comprehensions, so it's taken some time to understand this. I've looked at it in more detail, and this is very slick. Thanks again, Ihor. – Red Spanner Aug 15 '12 at 18:41
  • List comprehensions and generators are powerful features of Python. I suggest you to take a look at two videos taken from [Udacity CS212 course](http://www.udacity.com/view#Course/cs212/CourseRev/apr2012): about [list comprehensions](http://www.youtube.com/watch?v=MvXxpU3wcLc) and [generator expressions](http://www.youtube.com/watch?v=qZVWbkE-Fg0). – Ihor Kaharlichenko Aug 15 '12 at 22:17
  • Ihor, I just checked out those links --- looks like TERRIFIC info --- I'm all over it like a cheap suit. thanks VERY much for these links.I'd heard of udacity before, but had never looked at it. I'm like a kid in a candy store! – Red Spanner Aug 15 '12 at 23:20