Home > OS >  Find value from one XML to another XML file using Python
Find value from one XML to another XML file using Python

Time:10-13

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.

  • Related