Python Forum
How do I get attribute XPATHs list ?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I get attribute XPATHs list ?
#1
How do I get attribute XPATHs list ?
======================================

Thanks for reviewing my 1st thread in this forum.

I am trying to list all Xpaths of the input file using Python code.

Here is the input.

Output:
<?xml version="1.0" encoding="UTF-8"?> <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>2012</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
Here is the python code:

import xml.etree.ElementTree as ET
from lxml import etree
infile = 'D:\Python_work\eclipse-workspace\My1stPythonP\CountryData.xml'
output ="D:\\Python_work\\eclipse-workspace\\My1stPythonP\\outfile.out"
tree = etree.parse(infile)
root = tree.getroot()
f = open(output,'w') #open write to file
count = tree.xpath("count(.//country)")
print (count)
f.write("%s\n" %(count))
xpathf = root.find('.//country')
print(xpathf.get("value"))
xpathf = root.find('.//data/country/year')
print(xpathf.get("value"))
print (tree.getroot() )
xmlstr = ET.tostring(root,  method='xml')
root1 = ET.fromstring(xmlstr)

tree1 = etree.ElementTree(root)
for e in root.iter():
     f.write("%s\n" %(tree1.getpath(e)))
f.close()
1) tree1.getpath(e) getting the list of XPATHs, but attribute XPATHS are missing from the list

2) xpathf = root.find('.//country')
print(xpathf.get("value"))
xpathf = root.find('.//data/country/year')
print(xpathf.get("value"))

are not printing the data value of XPATHs './/country' & './/data/country/year'

I am looking to extract the value based on XPATH.

3) What is the way to extract the attribute value based on XPATHs?

4) If there is the name space spec in input file, the above code produce the XPATH list as

Output:
/* /*/*[1] /*/*[2] /*/*[2]/*[1] /*/*[2]/*[2] /*/*[2]/*[3] /*/*[2]/*[4] /*/*[2]/*[5] /*/*[2]/*[6] /*/*[2]/*[7] /*/*[2]/*[8] /*/*[2]/*[9] /*/*[2]/*[10]
Are there ways to get readable XPATH, when input file contain a namespace spec?

Thanks for your guidance.
Reply
#2
(Jun-20-2020, 10:26 PM)MDRI Wrote: 2) xpathf = root.find('.//country')
print(xpathf.get("value"))
xpathf = root.find('.//data/country/year')
print(xpathf.get("value"))
When you are using XPath expressions can not use .find(),need to use .xpath().
Here a quick test.
from lxml import etree

root = etree.parse(r'country.xml')
root = root.getroot()
Usage test:
>>> parse = root.xpath('//year')
>>> parse
[<Element year at 0x3a6a8a0>,
 <Element year at 0x3a6a8c8>,
 <Element year at 0x3a6a8f0>]

>>> parse[0].text
'2008'
>>> [tag.text for tag in parse]
['2008', '2011', '2012']

# Using find() it will find first occurrence
>>> parse = root.find('country')
>>> parse.attrib
{'name': 'Liechtenstein'}
>>> parse.find('year')
<Element year at 0x704030>
>>> parse.find('year').text
'2008'

# Example all the child element nodes of the country element
parse = root.xpath('//country/*')
>>> for tag in parse:
...     if tag.text is not None:      
...         print(tag.text)
        
1
2008
141100
4
2011
59900
68
2012
13600
MDRI Wrote:
f.write("%s\n" %(count))
Try not to use this old string formatting anymore
With f-string it look like this.
f.write(f"{count}\n")
Reply
#3
Thanks for your guidance.

I am using Eclipse with PyDev for Python . I am not able to get interactive output as you posted.

I need to add Print and run to see output. Is there a way to get interactive output with clipse with PyDev IDE.

Thanks for your guidance.
Reply
#4
(Jun-24-2020, 02:55 AM)MDRI Wrote: I am using Eclipse with PyDev for Python . I am not able to get interactive output as you posted.

I need to add Print and run to see output. Is there a way to get interactive output with clipse with PyDev IDE.
There is a Interactive Console in PyDev.

It's a important part of Python to do test of smaller code pies like this.
I often use a standalone like REPL like ptpython(used with code over) or IPython for this.
Can also use both in my main editor VS Code.

-i flag can good to know about.
Load any code to interactive console of choice.
# lxml_test.py
from lxml import etree

root = etree.parse(r'country.xml')
root = root.getroot()
So from command line eg cmder.
[Image: VCVAP5.png]
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  AttributeError: 'list' object has no attribute 'upper' Anldra12 4 4,887 Apr-27-2022, 09:27 AM
Last Post: Anldra12
  AttributeError: 'list' object has no attribute 'values' ilknurg 4 14,985 Jan-19-2022, 08:33 AM
Last Post: menator01
  Organizing list of objects by attribute scarney1988 3 2,227 Mar-11-2020, 03:55 PM
Last Post: scarney1988
  AttributeError: 'NoneType' object has no attribute 'n' in list of class objects jdrp 4 5,736 Jun-19-2018, 02:44 PM
Last Post: jdrp

Forum Jump:

User Panel Messages

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