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:
JavaScript
x
20
20
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!-- Data System -->
3
<process>
4
<!-- Student Name -->
5
<NAME source="hsfg" class="hshah" property="Name">
6
<VALUE type="string"></VALUE>
7
<VALUE type="None"></VALUE>
8
</NAME>
9
<!-- Exercise Number -->
10
<number source="hsfg" class="hgdgf" property="gagfa">
11
<VALUE type="string"></VALUE>
12
<VALUE type="None"></VALUE>
13
</number>
14
<!-- Exam ID -->
15
<id source="hsfg" class="gfdg" property="fadg">
16
<VALUE type="string"></VALUE>
17
<VALUE type="None"></VALUE>
18
</id>
19
</process>
20
This is the value that I need to update
JavaScript
1
6
1
<!-- Student Name -->
2
<NAME source="hsfg" class="hshah" property="Name">
3
<VALUE type="string"></VALUE>
4
<VALUE type="None"></VALUE>
5
</NAME>
6
become this:
JavaScript
1
6
1
<!-- Student Name -->
2
<NAME source="hsfg" class="hshah" property="Name">
3
<VALUE type="string">new value</VALUE>
4
<VALUE type="None"></VALUE>
5
</NAME>
6
My code:
JavaScript
1
7
1
read = ET.parse('test.xml').getroot()
2
parent = read.find('.//NAME[@property="Name"]')
3
change = parent.find('VALUE[@type="string"]')
4
change.text = 'new value'
5
tree = ET.ElementTree(read)
6
tree.write("test.xml")
7
The output of the test.xml file become this. the comment and <?xml version="1.0" encoding="UTF-8"?>
dissapeared.
JavaScript
1
18
18
1
<process>
2
3
<NAME source="hsfg" class="hshah" property="Name">
4
<VALUE type="string">new value</VALUE>
5
<VALUE type="None" />
6
</NAME>
7
8
<number source="hsfg" class="hgdgf" property="gagfa">
9
<VALUE type="string" />
10
<VALUE type="None" />
11
</number>
12
13
<id source="hsfg" class="gfdg" property="fadg">
14
<VALUE type="string" />
15
<VALUE type="None" />
16
</id>
17
</process>
18
BUT my expectation output, the structure and the comment still the same as before update the value like this:
JavaScript
1
20
20
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!-- Data System -->
3
<process>
4
<!-- Student Name -->
5
<NAME source="hsfg" class="hshah" property="Name">
6
<VALUE type="string">new value</VALUE>
7
<VALUE type="None"></VALUE>
8
</NAME>
9
<!-- Exercise Number -->
10
<number source="hsfg" class="hgdgf" property="gagfa">
11
<VALUE type="string"></VALUE>
12
<VALUE type="None"></VALUE>
13
</number>
14
<!-- Exam ID -->
15
<id source="hsfg" class="gfdg" property="fadg">
16
<VALUE type="string"></VALUE>
17
<VALUE type="None"></VALUE>
18
</id>
19
</process>
20
Advertisement
Answer
- Use
ET.XMLParser
to preserve comments - Use
encoding
andxml_declaration
arguments inwrite()
function to write xml declaration Try the following code:
JavaScript
1
10
10
1
import xml.etree.ElementTree as ET
2
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))
3
4
read = ET.parse('newXml.xml', parser=parser).getroot()
5
parent = read.find('.//NAME[@property="Name"]')
6
change = parent.find('VALUE[@type="string"]')
7
change.text = 'new value'
8
tree = ET.ElementTree(read)
9
tree.write("test.xml", encoding='utf-8', xml_declaration=True)
10
you can also avoid variable read
and just use tree
:
JavaScript
1
9
1
import xml.etree.ElementTree as ET
2
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))
3
4
tree = ET.parse('newXml.xml', parser=parser)
5
parent = tree.find('.//NAME[@property="Name"]')
6
change = parent.find('VALUE[@type="string"]')
7
change.text = 'new value'
8
tree.write("test.xml", encoding='utf-8', xml_declaration=True)
9