Reputation: 713
I have an XML file which looks like this
<tagset>
<image>
<imageName>apanar_06.08.2002/IMG_1261.JPG</imageName>
<resolution x="1600" y="1200" />
<taggedRectangles>
<taggedRectangle x="174.0" y="392.0" width="274.0" height="195.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="512.0" y="391.0" width="679.0" height="183.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="184.0" y="612.0" width="622.0" height="174.0" offset="-2.0" rotation="0.0" userName="admin" />
<taggedRectangle x="863.0" y="599.0" width="446.0" height="187.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="72.0" y="6.0" width="95.0" height="87.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="247.0" y="2.0" width="197.0" height="88.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="792.0" y="0.0" width="115.0" height="81.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="200.0" y="848.0" width="228.0" height="139.0" offset="0.0" rotation="0.0" userName="admin" />
<taggedRectangle x="473.0" y="878.0" width="165.0" height="109.0" offset="14.0" rotation="0.0" userName="admin" />
<taggedRectangle x="684.0" y="878.0" width="71.0" height="106.0" offset="12.0" rotation="0.0" userName="admin" />
<taggedRectangle x="806.0" y="844.0" width="218.0" height="141.0" offset="26.0" rotation="0.0" userName="admin" />
</taggedRectangles>
</image>
</tagset>
I want to access the <imageName>
tag after I reach a <taggedRectangle>
tag.
I wrote the following code
import xml.etree.ElementTree as ET
with open('locations.xml','r') as file:
contents = file.read()
tree = ET.fromstring(contents) #tree represents the root node of the xml file which is tagset
tags = tree.findall(".//taggedRectangle")
attribs = ['x','y','width','height']
x = []
y = []
width = []
height = []
imageName = []
for tag in tags:
x.append(tag.get('x'))
y.append(tag.get('y'))
width.append(tag.get('width'))
height.append(tag.get('height'))
print(type(tag))
print(tag.tag)
temp = tag.find('./..') ####THIS LINE IS BEING REFERRED AFTERWARDS####
print(type(temp))
Now, in the line I have highlighted above, I expect temp
to be referring to the <taggedRectangles
> node. But it shows me type NoneType
. Why?
(locations.xml refers to the name of the xml file in my device, the content of which is like the XML file in the beginning of the question)
Note - https://docs.python.org/3/library/xml.etree.elementtree.html According to the documentation, my syntax seems valid to me, but I can't figure out the error.
Upvotes: 0
Views: 219
Reputation: 30991
Note that temp = tag.find('./..')
(using ElementTree) is not likely to get
the parent element.
Open The ElementTree XML API site (mentioned in your post) and find
Supported XPath syntax. Description of .. reads:
Returns None if the path attempts to reach the ancestors of the start element.
I think the proper recipe to your problem is to use lxml instead of ElementTree, as it contains some methods and functionality missing in ElementTree.
I tried the below code:
from lxml import etree as et
root = et.XML(contents) # contents contains your XML
for elem in root.findall('.//taggedRectangle'):
x = elem.get('x')
pic = elem.xpath('../../imageName')[0].text
print(x, pic)
and got the following result:
174.0 apanar_06.08.2002/IMG_1261.JPG
512.0 apanar_06.08.2002/IMG_1261.JPG
184.0 apanar_06.08.2002/IMG_1261.JPG
863.0 apanar_06.08.2002/IMG_1261.JPG
72.0 apanar_06.08.2002/IMG_1261.JPG
247.0 apanar_06.08.2002/IMG_1261.JPG
792.0 apanar_06.08.2002/IMG_1261.JPG
200.0 apanar_06.08.2002/IMG_1261.JPG
473.0 apanar_06.08.2002/IMG_1261.JPG
684.0 apanar_06.08.2002/IMG_1261.JPG
806.0 apanar_06.08.2002/IMG_1261.JPG
As you can see, e.g. in xpath method you are free to use double dots in XPath expressions, without limitations imposed by ElementTree. But this method is present only in lxml.
Upvotes: 1