2

I have a nested XML that looks like this:

<data>foo <data1>hello</data1> bar</data>

I am using minidom, but no matter how I try to get the values between "data", I am only get "foo" but not "bar"

It is even worse if the XML is like this:

<data><data1>hello</data1> bar</data>

I only get a "None", which is correct according to the logic above. So I came accross this: http://levdev.wordpress.com/2011/07/29/get-xml-element-value-in-python-using-minidom and concluded that it is due to the limitation of minidom?

So I used the method in that blog and I now get

foo <data1>hello</data1> bar

and

<data1>hello</data1> bar

which is acceptable. However, if I try to create a new node (createTextNode) using the output above as node values, the XML becomes:

<data>foo &lt;data1&gt;hello&lt;/data1&gt; bar</data>

and

<data>&lt;data1&gt;hello&lt;/data1&gt; bar</data>

Is there any way that I can create it so that it looks like the original? Thank you.

3
  • I'm not an XML-parsing expert, but from what I understand, your "data" tag contains three child nodes: a text node containing "foo ", an element node for the <data1> tag, and another text node containing " bar". You have to get both of the text nodes in order to do what you want. As for whether there's an elegant way to do that in XML libraries, (or Python's minidom in particular) I don't know. Commented Apr 28, 2014 at 2:47
  • I think I get what you mean, will get back to you Commented Apr 28, 2014 at 3:10
  • @pandubear , you are right, there are indeed two text nodes Commented Apr 28, 2014 at 3:42

3 Answers 3

2

You can use element tree For xml it very efficient for both retrieval and creation of the node

have a look at the link below

element tree-- tutorials mixed xml

someof the examples of creating node

import xml.etree.ElementTree as ET

  data = ET.Element('data')

data1= ET.SubElement(data, 'data1',attr="value")
data1.text="hello"
data.text="bar"
data1.tail="some code"
ET.dump(data)

output :<data>bar<data1 attr="value">hello</data1>some code</data>

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

6 Comments

Yes but what about the value behind </data1>? i.e <data>bar<data1>hello</data1>foo</data> By that I mean "foo"
i think that is not correct format of xml ..But can try like giving space btw word <data>bar foo<data1>hello</data1></data>
No, that's valid XML depending on what project is using it, for instance, look at here: github.com/CyanogenMod/android_packages_apps_Settings/blob/…
@Ryuinferno . CHECK THE UPDATED CODE. USE TAIL . U GET EXPECTED RESULT
Thanks for the effort but I have found the exact answer for my question (using minidom), posted below...:)
|
0

Use the following function to prettify your xml so it is a LOT easier to see...first of all..

import xml.dom.minidom as minidom

def prettify(elem):
    """Return a pretty-printed XML string for the Element.  Props goes
    to Maxime from stackoverflow for this code."""
    rough_string = et.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")

That makes stepping through the tree visually a lot simpler.

Next I would suggest a modification in your xml that will make your life a whole lot easier i think.

Instead of :

<data>foo
    <data1>hello</data1>
    bar
</data>

which is not a correct XML format I would save your 'foo' and 'bar' as attributes of

it looks like this:

<data var1='foo' var2='bar'>
    <data1>hello</data1>
</data>

to do this using xml.etree.ElementTree:

import xml.etree.ElementTree as ET

data = ET.Element('data', {'var1:'foo', 'var2':'bar'})
data1= ET.SubElement(data, 'data1')
data1.text='hello'
print prettify(data)

Comments

0

So after pointed out by @pandubear, the XML:

<data>foo <data1>hello</data1> bar</data>

Does have two text nodes, containing "foo " and " bar", so what can be done is to iterate through all the child nodes in data and get the values.

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.