How to find and update XML file content using python

Viewed 83

for example

 <managedObject class="New" distName="MB-85404/TB-85404/ST-4/a" version="xL20A_1911_002" operation="open">
          <p name="a">320ms</p>
          <p name="b">enabled</p>
          <p name="c">640ms</p>
          <p name="d">320ms</p>
          <p name="e">640ms</p>
          <p name="f">1280ms</p>
          <p name="g">6</p>
    </managedObject>
<managedObject class="new" distName="AL-76867/MB-85404/TB-85404/ST-4/b" version="xL20A_1911_002" operation="open">
          <p name="h">320ms</p>
          <p name="i">enabled</p>
          <p name="j">640ms</p>
          <p name="k">320ms</p>
          <p name="l">640ms</p>
          <p name="a">1280ms</p>
          <p name="l">6</p>
    </managedObject>
<managedObject class="New" distName="MB-85404/TB-85404/ST-4/c" version="xL20A_1911_002" operation="open">
          <p name="a">320ms</p>
          <p name="p">enabled</p>
          <p name="q">640ms</p>
          <p name="r">320ms</p>
          <p name="s">640ms</p>
          <p name="t">1280ms</p>
          <p name="u">6</p>
    </managedObject>

Here in this example first I want to update (distName="MB-85404/TB-85404/ST-4/[a or b or c]") to (distName="MB-85409/TB-85409/ST-4/[a or b or c]")

after doing this to whole XML file .

after doing this I want to update the values of tag name="a" for which <managedObject class="New" distName="MB-85409/TB-85409/ST-4/[a or b or c] >

How can I do this , I have an XML file of 40000+ lines.

EDIT1

with open("C:/files/abcd.xml", "w+") as file:
    xml_data = file.read()
    xml_data.replace("85409","85904")
    file.write("outPuta.xml")

EDIT2

soup = bs(content,"xml")
    loc = re.compile(r'[A-Z]+-+[0-9]+/+SMOD+-+[1-9]')
    for i in soup.find_all('managedObject', distName=loc):
        locat=i.find('p',{'name':'moduleLocation'})
        locat.string="3444 South texas"

By this code I am trying to find distname which matched with regex loc, and inside managedObject, i trying finding tag <p name="moduleLocation" 4444 New York> and I want to update "4444 New York" to "3444 South texas" and this is giving me below mentioned error

locat.string="3444 South texas"
AttributeError: 'NoneType' object has no attribute 'string'
1 Answers

I hope I understood your question right, this will find all distName="MB-85404/TB-85404/ST-4/[a or b or c]" tags and replace 85404 for 85409 and update <p name="a"> tag:

import re
from bs4 import BeautifulSoup


xml_data = ''' <managedObject class="New" distName="MB-85404/TB-85404/ST-4/a" version="xL20A_1911_002" operation="open">
          <p name="a">320ms</p>
          <p name="b">enabled</p>
          <p name="c">640ms</p>
          <p name="d">320ms</p>
          <p name="e">640ms</p>
          <p name="f">1280ms</p>
          <p name="g">6</p>
    </managedObject>
<managedObject class="new" distName="AL-76867/MB-85404/TB-85404/ST-4/b" version="xL20A_1911_002" operation="open">
          <p name="h">320ms</p>
          <p name="i">enabled</p>
          <p name="j">640ms</p>
          <p name="k">320ms</p>
          <p name="l">640ms</p>
          <p name="a">1280ms</p>
          <p name="l">6</p>
    </managedObject>
<managedObject class="New" distName="MB-85404/TB-85404/ST-4/c" version="xL20A_1911_002" operation="open">
          <p name="a">320ms</p>
          <p name="p">enabled</p>
          <p name="q">640ms</p>
          <p name="r">320ms</p>
          <p name="s">640ms</p>
          <p name="t">1280ms</p>
          <p name="u">6</p>
    </managedObject>'''

soup = BeautifulSoup('<data>' + xml_data + '</data>', 'xml')

r = re.compile(r'^MB-85404/TB-85404/ST-4/(?:a|b|c)')

for o in soup.find_all('managedObject', distName=r):
    o['distName'] = o['distName'].replace('85404', '85409')
    p = o.find('p', {'name':'a'})
    p.string = 'UPDATED ' + p.string

soup.data.unwrap()
print(soup)

Prints:

<?xml version="1.0" encoding="utf-8"?>
 <managedObject class="New" distName="MB-85409/TB-85409/ST-4/a" operation="open" version="xL20A_1911_002">
<p name="a">UPDATED 320ms</p>
<p name="b">enabled</p>
<p name="c">640ms</p>
<p name="d">320ms</p>
<p name="e">640ms</p>
<p name="f">1280ms</p>
<p name="g">6</p>
</managedObject>
<managedObject class="new" distName="AL-76867/MB-85404/TB-85404/ST-4/b" operation="open" version="xL20A_1911_002">
<p name="h">320ms</p>
<p name="i">enabled</p>
<p name="j">640ms</p>
<p name="k">320ms</p>
<p name="l">640ms</p>
<p name="a">1280ms</p>
<p name="l">6</p>
</managedObject>
<managedObject class="New" distName="MB-85409/TB-85409/ST-4/c" operation="open" version="xL20A_1911_002">
<p name="a">UPDATED 320ms</p>
<p name="p">enabled</p>
<p name="q">640ms</p>
<p name="r">320ms</p>
<p name="s">640ms</p>
<p name="t">1280ms</p>
<p name="u">6</p>
</managedObject>

EDIT: To change 85404 to 85409 in every distName=, you can do this:

for o in soup.find_all('managedObject', {'distName': True}):
    o['distName'] = o['distName'].replace('85404', '85409')

EDIT2: To replace the whole file:

with open("C:/files/abcd.xml", "r") as f_in:
    xml_data = f_in.read()

with open("C:/files/output.xml", "w") as f_out:
    f_out.write(xml_data.replace("85409","85904"))
Related