Reputation: 13
I am trying to find all ancestors of node.
my xml,
xmldata="""
<OrganizationTreeInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/YSM.PMS.Web.Service.DataTransfer.Models">
<Name>Parent</Name>
<OrganizationId>4345</OrganizationId>
<Children>
<OrganizationTreeInfo>
<Name>A</Name>
<OrganizationId>123</OrganizationId>
<Children>
<OrganizationTreeInfo>
<Name>B</Name>
<OrganizationId>54</OrganizationId>
<Children/>
</OrganizationTreeInfo>
</Children>
</OrganizationTreeInfo>
<OrganizationTreeInfo>
<Name>C</Name>
<OrganizationId>34</OrganizationId>
<Children>
<OrganizationTreeInfo>
<Name>D</Name>
<OrganizationId>32323</OrganizationId>
<Children>
<OrganizationTreeInfo>
<Name>E</Name>
<OrganizationId>3234</OrganizationId>
<Children/>
</OrganizationTreeInfo>
</Children>
</OrganizationTreeInfo>
</Children>
</OrganizationTreeInfo>
</Children>
"""
for e.g. If I input value of OrganizationId as 3234 , then output should be like,
{'parent':4345,'C':34,'D':32323,'E':3234 }
Here is my try,
root = ET.fromstring(xmldata)
for target in root.xpath('.//OrganizationTreeInfo/OrganizationId[text()="3234"]'):
d = {
dept.find('Name').text: int(dept.find('OrganizationId').text)
for dept in target.xpath('ancestor-or-self::OrganizationTreeInfo')
}
print(d)
But it is not giving any output. I am unable to find out whats wrong with it.
Upvotes: 0
Views: 1853
Reputation: 10223
You are not getting correct answer because of namespace
xmlns="http://schemas.datacontract.org/2004/07/YSM.PMS.Web.Service.DataTransfer.Models"
Following code with namespace:
code:
import lxml.etree as ET
root = ET.fromstring(xmldata)
result = {}
count = 1
namespaces1={'xmlns':'http://schemas.datacontract.org/2004/07/YSM.PMS.Web.Service.DataTransfer.Models',}
for target in root.xpath('.//xmlns:OrganizationTreeInfo/xmlns:OrganizationId[text()="3234"]',\
namespaces=namespaces1):
result[count] = {}
for dept in target.xpath('ancestor-or-self::xmlns:OrganizationTreeInfo', namespaces=namespaces1):
result[count][dept.find('xmlns:Name', namespaces=namespaces1).text] = int(dept.find('xmlns:OrganizationId', namespaces=namespaces1).text)
count += 1
import pprint
pprint.pprint(result)
Output:
:~/workspace/vtestproject/study$ python test1.py
{1: {'C': 34, 'D': 32323, 'E': 3234, 'Parent': 4345}}
Replace xmlns=
string with other temp string.
code:
import lxml.etree as ET
new_xmldata = xmldata.replace("xmlns=", "xmlnamespace=")
root = ET.fromstring(new_xmldata)#, namespace="{http://schemas.datacontract.org/2004/07/YSM.PMS.Web.Service.DataTransfer.Models}")
result = {}
count = 1
for target in root.xpath('.//OrganizationTreeInfo/OrganizationId[text()="3234"]'):
result[count] = {}
for dept in target.xpath('ancestor-or-self::OrganizationTreeInfo'):
result[count][dept.find('Name').text] = int(dept.find('OrganizationId').text)
count += 1
import pprint
pprint.pprint(result)
Output:
:~/workspace/vtestproject/study$ python test1.py
{1: {'C': 34, 'D': 32323, 'E': 3234, 'Parent': 4345}}
Upvotes: 1