9

for the xml

<grandparent>
  <parent1>
     <child>data1</child>
  </parent1>
  <parent2>
     <child>data2</child>
  </parent2>
</grandparent>

I need the list containing tuples of parent,data for each parent in xml.

Is there a way to do it USING cElementTree? I am able to do it for child,data, but unfortunately child is identical in all the values, hence it is of not much use.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
Mohit Ranka
  • 4,193
  • 12
  • 41
  • 41

3 Answers3

6

It seems you can get access to the parent from the child using version 1.3 of ElementTree (check http://effbot.org/zone/element-xpath.htm), by using xpath commands like child.find('../parent'). But I think python ships with version 1.2 or something.

You should also check for lxml which is compatible with etree and has full Xpath support http://lxml.de/

twasbrillig
  • 17,084
  • 9
  • 43
  • 67
Mapad
  • 8,407
  • 5
  • 41
  • 40
  • The docs says something like `Changed in version 2.7: The ElementTree API is updated to 1.3.` in http://docs.python.org/2/library/xml.etree.elementtree I'm using 2.7 but for me `'../myparent'` still doesn't seem to work; what does this mean? – n611x007 Jan 10 '13 at 22:45
  • Yes I don't think this is support in cElementTree. e.g.: ET.fromstring("").find('.//b').find('..') returns None – Andy Smith Oct 09 '14 at 10:27
  • 1
    @AndySmith I think I know why it returns none. The [doc says](https://docs.python.org/3/library/xml.etree.elementtree.html#supported-xpath-syntax) : `Selects the parent element. Returns None if the path attempts to reach the ancestors of the start element (**the element find was called on**).` – Bob Jun 16 '16 at 20:18
5
parent_map = dict((c, p) for p in tree.getiterator() for c in p)
parent_map[el].remove(el)
watbywbarif
  • 6,487
  • 8
  • 50
  • 64
  • +1. because in elementTree, accessing parent by `..` is broken or not working or any other way that i don't know.so your way will solve it!!! we can also do it as `{c:p for p in tree.getiterator() for c in p}` – namit Jan 29 '13 at 10:52
  • @namit I can confirm this. I can correctly access my nodes but when I do `print('parent = ', el.findall("../"))` which is how [this](https://docs.python.org/3/library/xml.etree.elementtree.html#supported-xpath-syntax) said so, I get null objects. – Bob Jun 16 '16 at 20:06
  • @namit turns out I didn't correctly read the documentation for `..`: `Selects the parent element. Returns None if the path attempts to reach the ancestors of the start element (the element find was called on).`[link](https://docs.python.org/3/library/xml.etree.elementtree.html#supported-xpath-syntax) – Bob Jun 16 '16 at 20:53
0

This syntax seemed to work for cElementTree

ET.fromstring("<c><a><b></b></a></c>").find('.//b/..')

No going to base parent, and using double slash then single slash in path.
(would have posted as a comment to above thread but it seems I have no privilege to)

MerryDan
  • 41
  • 3