MA1
MA1

Reputation: 2847

Python xml creation from list with element levels

This is the first time i am working with xml processing.

The following python list contains all the elements/nodes that will used to create the final xml. Every item of the list is also a list composed of element/node and level pair.

For example:

['root', 1]

'root' is the name of the element, and 1 is level or position of 'root' in the xml tree.

[
['root', 1],
['dir', 2],
['book1',3],
['chapter1', 4],
['page1', 5],
['page2', 5],
['book2', 3],
['book3', 3],
['author', 3]
]

Following is the xml corresponding to above list

<root>
  <dir>
    <book1>
      <chapter1>
        <page1 para=4>
        <page2 para=5>
      </chapter1>
    </book1>
    <book2 para=3/>
    <book3 para=3/>
    <author name=abc>
  </dir>
</root>

The problem i am facing is, i don't know how to keep track of previous nodes so that new nodes are added into correct parent nodes?

For example:

should be added under

So during xml creation, after how to get/find parent node of so that child should be added at correct place?

Can anyone guide me to write a generic solution for this problem?

Upvotes: 0

Views: 150

Answers (3)

jterrace
jterrace

Reputation: 67073

Here's what I came up with:

xml_arr = [
['root', 1],
['dir', 2],
['book1',3],
['chapter1', 4],
['page1', 5],
['page2', 5],
['book2', 3],
['book3', 3],
['author', 3]
]

from xml.etree import ElementTree as etree

root = xml_arr.pop(0)
cur_level = root[1]
root = etree.Element(root[0])
cur_element = root
parents = [root]

for tag, level in xml_arr:
    while level < cur_level:
        cur_level -= 1
        parents.pop()
        cur_element = parents[-1]
    if level == cur_level:
        parents[-2].append(etree.Element(tag))
    if level > cur_level:
        cur_level = level
        new_elem = etree.Element(tag)
        cur_element.append(new_elem)
        parents.append(new_elem)
        cur_element = new_elem

print etree.tostring(root)

This prints:

<root><dir><book1><chapter1><page1 /><page2 /></chapter1></book1><book2 /><book3 /><author /></dir></root>

Or when pretty printed:

<root>
    <dir>
        <book1>
            <chapter1>
                <page1/>
                <page2/>
            </chapter1>
        </book1>
        <book2/>
        <book3/>
        <author/>
    </dir>
</root>

Upvotes: 0

yilmazhuseyin
yilmazhuseyin

Reputation: 6612

I had the same problem last week. Here is my solution

http://www.yilmazhuseyin.com/blog/dev/convert-python-dict-xml/

Basic difference between your approach and mine is I used dicts instead of lists

Upvotes: 0

stew
stew

Reputation: 11366

keep a "lastforlevel" array which stores the last item appended at a given level. If you try create an element for level n, you need to append it to lastforlevel[n-1].

Upvotes: 1

Related Questions