2

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>
2
  • I see BBB_text = '11111' + BBB.text. Shouldn't it be BBB.text = '11111' + BBB.text ? Does print(BBB_text) prints the correct text ? Commented May 29, 2018 at 12:46
  • if i delete [0], no error when print(BBB_text) but it inserts '11111' to all texts of BBB. Commented May 29, 2018 at 12:49

4 Answers 4

3

You do not need to iterate all the tags if you just need to update a single tag.

Try:

import xml.etree.ElementTree as ET

tree = ET.parse(filename)
root = tree.getroot()                                                

for AAA in root.findall('AAA'):
    if AAA.find('CCC'):
        BBB = AAA.find('CCC').find('BBB')
        BBB.text = '33333' + BBB.text

tree.write('C:\\test\\python test\\output.xml')
Sign up to request clarification or add additional context in comments.

8 Comments

Does this do the right thing when there are multiple <BBB> to be found?
Updated snippet...Do you want just the first BBB tag or all first BBB tags?
Ah sorry. actually ultimatey i was trying to do for all first BBB tags.
Use the first snippet
Rakesh, i have one more question. your code looks great but what does BBB = AAA.find('CCC').find('BBB') AttributeError: 'NoneType' object has no attribute 'find' this error mean
|
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.

1 Comment

Thanks for your opinion
0

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

Comments

0

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.

1 Comment

Thanks for your help!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.