5

I have this kind of XML structure (output from the Esprima ASL converted from JSON), it can get even more nested than this (ASL.xml):

<?xml version="1.0" encoding="UTF-8" ?>
    <program>
    <type>Program</type>
    <body>
        <type>VariableDeclaration</type>
        <declarations>
            <type>VariableDeclarator</type>
            <id>
                <type>Identifier</type>
                <name>answer</name>
            </id>
            <init>
                <type>BinaryExpression</type>
                <operator>*</operator>
                <left>
                    <type>Literal</type>
                    <value>6</value>
                </left>
                <right>
                    <type>Literal</type>
                    <value>7</value>
                </right>
            </init>
        </declarations>
        <kind>var</kind>
    </body>
    </program> 

Usualy for XML I use the for node inroot.childNodes` but this works only for the direct children:

import xml.dom.minidom as  md
dom = md.parse("ASL.xml")
root = dom.documentElement
for node in root.childNodes:
    if node.nodeType == node.ELEMENT_NODE:
        print node.tagName,"has value:",  node.nodeValue:, "and is child of:",node.parentNode.tagName 

How can I walk all the elements of the XML regardless how many nested elements are?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Eduard Florinescu
  • 16,747
  • 28
  • 113
  • 179

3 Answers3

9

This is probably best achieved with a recursive function. Something like this should do it but I've not tested it so consider it pseudocode.

import xml.dom.minidom as  md

def print_node(root):
    if root.childNodes:
        for node in root.childNodes:
           if node.nodeType == node.ELEMENT_NODE:
               print node.tagName,"has value:",  node.nodeValue, "and is child of:", node.parentNode.tagName
               print_node(node)

dom = md.parse("ASL.xml")
root = dom.documentElement
print_node(root)
redrah
  • 1,204
  • 11
  • 20
  • 1
    Just the kind of thing I am after. Could anyone please elobrate the following code to list the attributes in an xml file as well. thanks. – Saed Sep 02 '15 at 13:49
2

If it's not important to use xml.dom.minidom:

import xml.etree.ElementTree as ET
tree = ET.fromstring("""...""")
for  elt in tree.iter():
    print "%s: '%s'" % (elt.tag, elt.text.strip())

Output:

program: ''
type: 'Program'
body: ''
type: 'VariableDeclaration'
declarations: ''
type: 'VariableDeclarator'
id: ''
type: 'Identifier'
name: 'answer'
init: ''
type: 'BinaryExpression'
operator: '*'
left: ''
type: 'Literal'
value: '6'
right: ''
type: 'Literal'
value: '7'
kind: 'var'
kalgasnik
  • 3,149
  • 21
  • 19
  • Any idea how to modify this code to display if its a sub-element or other attributes as well. Thanks. – Saed Sep 02 '15 at 14:39
1

For the 2.6+ equivalent of kalgasnik's Elementree code, just replace iter() with getiterator():

import xml.etree.ElementTree as ET
tree = ET.fromstring("""...""")
for  elt in tree.getiterator():
    print "%s: '%s'" % (elt.tag, elt.text.strip())
Jackson Lee
  • 131
  • 3