Python Forum
Using xpath to get value of a nested element name using tag named
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using xpath to get value of a nested element name using tag named
#1
I have a nested XML tag file that parses correctly with elementtree.

I have been unable to find a method of getting the text value for an element nested in the file.

If I do a for loop I can do a findall and retrieve my values but would like to use a static mapping to get the data as it will be much more efficient.

Can anyone please tell me how to do this?
Reply
#2
Please show code
Reply
#3
This is an example XML file that I wish to parse.

I would like to be able to pick out the item data/country/year and get the values: 2008 2011 2011

I would also like to be able to pick out the item data/country/year for country = "Panama" and get 2011

I think I can use something like:
year = country.find('year').text 
to get the year for each country but have not been successful in figuring out the syntax to retrieve this for all countries or even just for Panama which is my objective.

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
This is the start of the code that I am writing:

#!/usr/local/bin/python
import xml.etree.ElementTree as ET

tree = ET.parse('/root/test/test_data_fixed.xml')
root = tree.getroot()
for country in root.findall('country'):
     rank = country.find('rank').text
     name = country.get('name')
     print(name, rank)
print root.findall("./country/neighbor")
print root.findall("./country/year.value")
Result is:
('Liechtenstein', '1')
('Singapore', '4')
('Panama', '68')
[<Element neighbor at 2315fc8>, <Element neighbor at 231d050>, <Element neighbor at 231d1b8>, <Element neighbor at 231d320>, <Element neighbor at 231d368>]
[]
Thanks in advance
Reply
#4
**Note**: I named my file 'stuff.xml' change this line to your filename
You may have to install lxml if you don't already have it:
pip install lxml
and finally, I use f-string which requires python 3.6 or newer
if you have to use earlier version for some reason, change line 15 to:
            print('tag: {}, value: {}'.format(element.tag, text))
You should use lxml:
from lxml import etree
import os

def parse_xml(filename):
    os.chdir(os.path.abspath(os.path.dirname(__file__)))
    with open(filename) as fp:
        xml_text = fp.read()
    tree = etree.fromstring(xml_text)

    for kid in tree.getchildren():
        for element in kid.getchildren():
            text = None
            if element.text:
                text = element.text.strip()
            print(f'tag: {element.tag}, value: {text}')


if __name__ == "__main__":
    parse_xml("stuff.xml")
output:
Output:
tag: rank, value: 1 tag: year, value: 2008 tag: gdppc, value: 141100 tag: neighbor, value: None tag: neighbor, value: None tag: rank, value: 4 tag: year, value: 2011 tag: gdppc, value: 59900 tag: neighbor, value: None tag: rank, value: 68 tag: year, value: 2011 tag: gdppc, value: 13600 tag: neighbor, value: None tag: neighbor, value: None
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  XPATH element does not change its value Martinelli 0 1,204 Oct-06-2019, 07:02 PM
Last Post: Martinelli
  Unable to locate element no such element gahhon 6 4,371 Feb-18-2019, 02:09 PM
Last Post: gahhon
  Replace element in a nested list nagymusic 4 17,794 Nov-19-2018, 08:03 PM
Last Post: nilamo
  Newbie question for sum the specific element in named tuple zydjohn 1 4,170 Dec-12-2017, 07:29 PM
Last Post: buran
  Change single element in 2D list changes every 1D element AceScottie 9 11,947 Nov-13-2017, 07:05 PM
Last Post: Larz60+
  Zip on single element in nested sequence. rhubarbpieguy 14 8,022 Jul-01-2017, 06:10 PM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020