2

I have an XML file then need to update some value. My XML file contains the comment. I would like to keep the comment after writing the XML, but it disappeared.

Here is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Data System -->
<process>
     <!-- Student Name -->
     <NAME source="hsfg" class="hshah" property="Name">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </NAME>
     <!-- Exercise Number -->
     <number source="hsfg" class="hgdgf" property="gagfa">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </number>
     <!-- Exam ID -->
     <id source="hsfg" class="gfdg" property="fadg">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </id>
</process>

This is the value that I need to update

<!-- Student Name -->
     <NAME source="hsfg" class="hshah" property="Name">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </NAME>

become this:

<!-- Student Name -->
     <NAME source="hsfg" class="hshah" property="Name">
          <VALUE type="string">new value</VALUE>
          <VALUE type="None"></VALUE>
     </NAME>

My code:

read = ET.parse('test.xml').getroot()
parent = read.find('.//NAME[@property="Name"]')
change = parent.find('VALUE[@type="string"]')
change.text = 'new value'
tree = ET.ElementTree(read)
tree.write("test.xml")

The output of the test.xml file become this. the comment and <?xml version="1.0" encoding="UTF-8"?> dissapeared.

<process>
     
     <NAME source="hsfg" class="hshah" property="Name">
          <VALUE type="string">new value</VALUE>
          <VALUE type="None" />
     </NAME>
     
     <number source="hsfg" class="hgdgf" property="gagfa">
          <VALUE type="string" />
          <VALUE type="None" />
     </number>
     
     <id source="hsfg" class="gfdg" property="fadg">
          <VALUE type="string" />
          <VALUE type="None" />
     </id>
</process>

BUT my expectation output, the structure and the comment still the same as before update the value like this:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Data System -->
<process>
     <!-- Student Name -->
     <NAME source="hsfg" class="hshah" property="Name">
          <VALUE type="string">new value</VALUE>
          <VALUE type="None"></VALUE>
     </NAME>
     <!-- Exercise Number -->
     <number source="hsfg" class="hgdgf" property="gagfa">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </number>
     <!-- Exam ID -->
     <id source="hsfg" class="gfdg" property="fadg">
          <VALUE type="string"></VALUE>
          <VALUE type="None"></VALUE>
     </id>
</process>

1 Answer 1

3
  1. Use ET.XMLParser to preserve comments
  2. Use encoding and xml_declaration arguments in write() function to write xml declaration Try the following code:
import xml.etree.ElementTree as ET
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))

read = ET.parse('newXml.xml', parser=parser).getroot()
parent = read.find('.//NAME[@property="Name"]')
change = parent.find('VALUE[@type="string"]')
change.text = 'new value'
tree = ET.ElementTree(read)
tree.write("test.xml", encoding='utf-8', xml_declaration=True)

you can also avoid variable read and just use tree:

import xml.etree.ElementTree as ET
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))

tree = ET.parse('newXml.xml', parser=parser)
parent = tree.find('.//NAME[@property="Name"]')
change = parent.find('VALUE[@type="string"]')
change.text = 'new value'
tree.write("test.xml", encoding='utf-8', xml_declaration=True)
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.