My 1st XML contain values as:
<Price>
<Id>100</Id>
<Id>102</Id>
<Id>104</Id>
<Id>103</Id></Price>
These value of Price ID which is present as child element needs to be searched in 2nd XML which has format as:
<List>
<Item>
<Number>1</Number>
<Price>
<Id>100</Id>
<Next_Item>
<Name>Apple</Name>
<Necessary/>
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<Necessary/>
</Next_Item>
<Price>
</Item>
<Item>
<Number>2</Number>
<Price>
<Id>102</Id>
<Next_Item>
<Name>Apple</Name>
<Necessary/>
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<Necessary/>
</Next_Item>
<Price>
</Item>
Upon finding the equivalent Price tag I need to change the child tag to -->
<List>
<Item>
<Number>1</Number>
<Price>
<Id>100</Id>
<Next_Item>
<Name>Apple</Name>
<!--<Necessary/>-->
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<!--<Necessary/>-->
</Next_Item>
<Price>
</Item>
<Item>
<Number>2</Number>
<Price>
<Id>102</Id>
<Next_Item>
<Name>Apple</Name>
<!--<Necessary/>-->
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<!--<Necessary/>-->
</Next_Item>
<Price>
</Item>
My Code:
from xml.etree import ElementTree as et
tree = et.parse('Sample.xml')
root = tree.getroot()
for Price in root:
print({x.tag for x in root.findall(Price.tag "/*")})
tree.find('.//Necessary').text = '<Necessary/>'
tree.find('.//Necessary').text = '<!--Necessary-->'
tree.write('Output1.xml')
In my code I am not able to find value from another file to my 2nd file and I am not able to change format of all the equivalent Ids to <!--Necessary-->
I would be grateful if anyone can help me.
CodePudding user response:
This requires a number of steps, described below. Note that your 2nd xml in the question is not well formed, because of various unclosed tags - see changes below.
from lxml import etree
#I prefer using lxml, because of its better xpath support, though this can be modified to work with ElementTree as well.
xml1 = """<Price>
<Id>100</Id>
<Id>102</Id>
<Id>104</Id>
<Id>103</Id>
</Price>
"""
xml2= """<List>
<Item>
<Number>1</Number>
<Price>
<Id>100</Id>
<Next_Item>
<Name>Apple</Name>
<Necessary/>
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<Necessary/>
</Next_Item>
</Price>
</Item>
<Item>
<Number>2</Number>
<Price>
<Id>102</Id>
<Next_Item>
<Name>Apple</Name>
<Necessary/>
</Next_Item>
<Next_Item>
<Name>Orange</Name>
<Necessary/>
</Next_Item>
</Price>
</Item>
</List>
"""
doc = etree.XML(xml1)
doc2 = etree.XML(xml2)
#find the value of each Id in xml1:
for id in doc.xpath('//Id/text()'):
#find the corresponding value in xml2:
target = doc2.xpath(f'//Item/Price[./Id/text()="{id}"]')
if len(target)>0:
#select "Necessary" elements which need to be commented out:
to_comm = target[0].xpath('.//Next_Item/Necessary')
#comment out each of those: see https://stackoverflow.com/a/44504935/9448090
for tc in to_comm:
tc.getparent().replace(tc, etree.Comment(etree.tostring(tc)))
print(etree.tostring(doc2).decode())
The output should be your expected output. You can then save it to a file.