1

I have the following XML structure and I want to add a new node if it does not exist at a specific location.

<root>
    <OuterLevel>
        <Node>
            <Name>NodeA</Name>
        </Node>
        <Node>
            <Name>NodeB</Name>
        <Node>
        <SpecialNode>
            <Name>NodeZ</Name>
        </SpecialNode>
    </OuterLevel>
 </root>

I wrote a python script using element tree. http://docs.python.org/library/xml.etree.elementtree.html

import xml.etree.ElementTree as ET
tree = ET.parse('sampleFile.xml')
root = tree.getroot()
newNodeStr = 'NewNode'

if root[0][0].tag != newNodeStr :
    print('Now we add it')
    newNode = ET.Element(newNodeStr)
    newNodeName = ET.Element('Name')
    newNodeName.text = 'NodeC'
    newNode.append(newNodeName)
    root[0].insert(0, newNode)

tree.write('sampleFileNew.xml')

I wanted the XML structure to look like this:

<root>
    <OuterLevel>
        <NewNode>
            <Name>NodeC</Name>
        </NewNode>
        <Node>
            <Name>NodeA</Name>
        </Node>
        <Node>
            <Name>NodeB</Name>
        <Node>
        <SpecialNode>
            <Name>NodeZ</Name>
        </SpecialNode>
    </OuterLevel>
 </root>

But instead, it looks like this:

<root>
    <OuterLevel>
        <NewNode><Name>NodeC</Name></NewNode><Node>
            <Name>NodeA</Name>
        </Node>
        <Node>
            <Name>NodeB</Name>
        <Node>
        <SpecialNode>
            <Name>NodeZ</Name>
        </SpecialNode>
    </OuterLevel>
 </root>

I used the insert() method from element tree because I thought it would give me what I needed, which is inserting a node at a specific location. However, it looks like the insert() doesn't actually care about what is already in that position in the tree structure. Is there a method that I can use to fix the ordering? Is there a better way of doing this?

1
  • 5
    Your examples are the same apart from indentation. There is no different ordering here. If you just want the indentation right, that's a matter of pretty printing. Commented Oct 12, 2012 at 18:49

3 Answers 3

2

syntactically those two outputs are the same, tree.write() might print your output the way you want it if you save the file and then re-parse it although I am not sure.

Sign up to request clarification or add additional context in comments.

Comments

1

Try this one it will pretty print the output as you want.

    try:
        reparsed = mini.parseString(mini.parse('YOUR_FILE_NAME').toxml())
        pretty_string =  '\n'.join([line for line in reparsed.toprettyxml(indent=' '*4).split('\n') if line.strip()])

        f = open('YOUR_FILE_NAME', 'w') 
        f.write(pretty_string) 
    finally:
        f.close()

Comments

1

It looks like you may need to use the pretty_print = True when you're rewriting the tree to the file. Perhaps you're parsing it in it's previous pretty_print form but the insert() does not add your new node in pretty_print form.

If you're not using LXML i'm not sure if this is possible, but try just changing the print to:

tree.write('sampleFileNew.xml', pretty_print = True)

Again, you may need to import lxml to use this functionality. Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.