1

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.