'How to modify element text in XML using python
Would you give me some advice how to modify element text in XML using python? if I want to insert other text in front of text of the first BBB element, which part should i change at the code below?
Please don't use fromstring and other modules(example lxml).
This is sample XML below.
<?xml version="1.0"?>
<data>
<AAA>
<CCC>
<BBB>This</BBB> ----> the first BBB element
</CCC>
<CCC>
<BBB>is</BBB>
</CCC>
<CCC>
<BBB>test1</BBB>
</CCC>
</AAA>
<AAA>
<CCC>
<BBB>This is test</BBB>
</CCC>
</AAA>
</data>
and it's code what i'm am trying below.
import xml.etree.ElementTree as ET
import re
tree = ET.parse("C:\\test\\python test\\data_text.xml")
root = tree.getroot()
for AAA in root.findall('AAA'):
for CCC in AAA.findall('CCC'):
for BBB in CCC.findall('BBB')[0]:
BBB_text = '11111' + BBB.text
print(BBB_text)
tree.write('C:\\test\\python test\\output.xml')
As far as i know, for BBB in CCC.findall('BBB')[0]:
[0] means find only the first BBB, but i guess it's wrong.
and this is the result that i want.
<?xml version="1.0"?>
<data>
<AAA>
<CCC>
<BBB>11111This</BBB> ----> the first BBB element
</CCC>
<CCC>
<BBB>is</BBB>
</CCC>
<CCC>
<BBB>test1</BBB>
</CCC>
</AAA>
<AAA>
<CCC>
<BBB>This is test</BBB>
</CCC>
</AAA>
</data>
Solution 1:[1]
ElementTree supports a limited sub-set of XPath.
You can use
bbb = tree.find("./AAA/CCC/BBB")
if bbb:
# do something
to get the very first such node in the tree, or
for bbb in tree.iterfind("./AAA/CCC/BBB"):
# do something
to iterate over all of them.
Solution 2:[2]
Well you can do it like this:
for a in tree:
for c in a:
for b in c:
b.text = '11111' + b.text
break
break
break
Solution 3:[3]
Disclaimer: XPath answer from @Tomalak is way more elegant!
After some tests, it looks like CCC.findall('BBB')[0] works fine.
Since you want the first BBB tag within the document and not within each AAA tag, I would loose the for loops and modify the bit from my comment. I got this:
import xml.etree.ElementTree as ET
import re
tree = ET.parse("data_text.xml")
root = tree.getroot()
AAA = root.find('AAA')
CCC = AAA.find('CCC')
BBB = CCC.find('BBB')
BBB.text = '11111' + BBB.text
print(BBB.text)
tree.write('output.xml')
Seems to do the trick. You may need to check the validity of AAA, BBB and CCC to avoid crashes if the XML does not contain such tags.
Hope this helps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Neuron |
| Solution 2 | zipa |
| Solution 3 | Neuron |
