Question

I'm using ElementTree in Python to read an XML file and get some values. The problem is that I successfully got the variable names, but I cannot read the values contained, for instance, in the TABLE tag under DEFINITION tag.

Here's my code to read the names:

tree = parse("basicfirealarm.xml")
root = tree.find('NETWORK')

for node in root:
    var = node.find('NAME')        # access the var definition
    print var.text

This is the file I'm trying to read, can you give me some suggestions how I can access the values in the TABLE tag using ElementTree?

Thank you

<?xml version="1.0" encoding="US-ASCII"?>

<!-- DTD for the XMLBIF 0.3 format -->
<!DOCTYPE BIF [
<!ELEMENT BIF ( NETWORK )*>
   <!ATTLIST BIF VERSION CDATA #REQUIRED>
<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )* )>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT VARIABLE ( NAME, ( OUTCOME |  PROPERTY )* ) >
<!ATTLIST VARIABLE TYPE (nature|decision|utility) "nature">
<!ELEMENT OUTCOME (#PCDATA)>
<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >
<!ELEMENT FOR (#PCDATA)>
<!ELEMENT GIVEN (#PCDATA)>
<!ELEMENT TABLE (#PCDATA)>
<!ELEMENT PROPERTY (#PCDATA)>
]>

<BIF VERSION="0.3">
<NETWORK>

<VARIABLE TYPE="nature">
   <NAME>tampering</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (-148.1863, -197.12207)</PROPERTY>
</VARIABLE>

<VARIABLE TYPE="nature">
   <NAME>fire</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (67.29127, -200.31433)</PROPERTY>
</VARIABLE>

<VARIABLE TYPE="nature">
   <NAME>alarm</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (-46.03397, -61.451008)</PROPERTY>
</VARIABLE>

<VARIABLE TYPE="nature">
   <NAME>smoke</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (158.27069, -67.83553)</PROPERTY>
</VARIABLE>

<VARIABLE TYPE="nature">
   <NAME>leaving</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (-44.437843, 74.22005)</PROPERTY>
</VARIABLE>

<VARIABLE TYPE="nature">
   <NAME>report</NAME>
   <OUTCOME>T</OUTCOME>
   <OUTCOME>F</OUTCOME>
   <PROPERTY>position = (-42.841713, 200.31433)</PROPERTY>
</VARIABLE>


<DEFINITION>
   <FOR>tampering</FOR>
   <TABLE> 0.02 0.98</TABLE>
</DEFINITION>

<DEFINITION>b
   <FOR>fire</FOR>
   <TABLE> 0.01 0.99</TABLE>
</DEFINITION>

<DEFINITION>
   <FOR>alarm</FOR>
   <GIVEN>tampering</GIVEN>
   <GIVEN>fire</GIVEN>
   <TABLE> 0.5 0.5 0.85 0.15 0.99 0.01 1.0E-4 0.9999</TABLE>
</DEFINITION>

<DEFINITION>
   <FOR>smoke</FOR>
   <GIVEN>fire</GIVEN>
   <TABLE> 0.9 0.1 0.01 0.99</TABLE>
</DEFINITION>

<DEFINITION>
   <FOR>leaving</FOR>
   <GIVEN>alarm</GIVEN>
   <TABLE> 0.88 0.12 0.0010 0.999</TABLE>
</DEFINITION>

<DEFINITION>
   <FOR>report</FOR>
   <GIVEN>leaving</GIVEN>
   <TABLE> 0.75 0.25 0.01 0.99</TABLE>
</DEFINITION>


</NETWORK>
</BIF>
Was it helpful?

Solution

You need to use findall() with 'DEFINITION' and then the 'TABLE' tag under it:

>>> root = tree.find('NETWORK')
>>> 
>>> for node in root.findall('DEFINITION'):
...   print node.find('TABLE').text
... 
 0.02 0.98
 0.01 0.99
 0.5 0.5 0.85 0.15 0.99 0.01 1.0E-4 0.9999
 0.9 0.1 0.01 0.99
 0.88 0.12 0.0010 0.999
 0.75 0.25 0.01 0.99

And if you want the VARIABLE names and values:

>>> for node in root.findall('DEFINITION'):
...     for child in node:
...         if child.tag in ('FOR', 'TABLE'):
...             print child.tag, '=', child.text 
... 
FOR = tampering
TABLE =  0.02 0.98
FOR = fire
TABLE =  0.01 0.99
FOR = alarm
TABLE =  0.5 0.5 0.85 0.15 0.99 0.01 1.0E-4 0.9999
# etc.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top