0

I am new to Python and trying to automate a task. I have spent two days reading the docs, looked into various other similar questions, but now, I've hit a wall and can't move forward.

I feel Python docs are not well documented on Elementtree module. Maybe it is just me. Also, I know I can use other modules. But please direct me with only Elementtree. Please help me guide forward.

The task is to parse XML and use Elementtree to replace all tag's attribute value. In web-server-parm, I need to replace ALL links which contains "http://api-stg.link.com." For ex...

FROM

"ServerAddr="http://api-stg.link.com/dataapi/v2/exchangerates/"

TO

"ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/exchangerates/".

XML test.xml

<?xml version="1.0" encoding="utf-8"?>
<ConfigRoot>
  <max-layer layer="5"/>
  <enabled-cache status="0"/>
  <server type="fgrfreefr">
    <web-server-parm mode="QA" ServerAddr="http://api-stg.link.com/dataapi/v2/securities?response=complex&amp;limit=9999999" timedOut="10000" X-API-UserId="54456464561" X-API-ProductId="ADS" ApiKey="fgggdfvdffdgdfg"/>
    <web-server-parm mode="UAT" ServerAddr="http://api-uat.link.com/dataapi/v2/securities?response=complex&amp;limit=9999999" timedOut="10000" X-API-UserId="gdfsgvhdgjfjuhgdyejhgsfegtb" X-API-ProductId="ADS" ApiKey="@gggf-fsffff@"/>
  </server>
  <server type="vfffdg">
    <web-server-parm mode="QA" ServerAddr="http://api-stg.link.com/dataapi/v2/exchangerates/" timedOut="10000" X-API-UserId="gsfsftfdfrfefrferf" X-API-ProductId="ADS" ApiKey="fgvdgggdfgttggefr"/>
    <web-server-parm mode="UAT" ServerAddr="http://api-uat.link.com/dataapi/v2/exchangerates/" timedOut="10000" X-API-UserId="gdfdagtgdfsgtrsdfsg" X-API-ProductId="ADS" ApiKey="@hdvfddfdd"/>
  </server>
</ConfigRoot>

Task.py This is what I have so far

import xml.etree.ElementTree as ET 
# import XML, SubElement, Element, tostring

#----------------------------------------------------------------------
def parseXML(xml_file):
    """
    Parse XML with ElementTree
    """
    tree = ET.ElementTree(file=xml_file)
    root = tree.getroot()

    # get the information via the children!

    print "Iterating using getchildren()"

    node = root.getchildren()
    for server_addr in node:
        node_children = server_addr.getchildren()
        for node_child in node_children:
            print "_________passed__________"
            print "%s=%s" % (node_child.attrib, node_child.text)
            test = node_child.findtext("http://api-stg.link.com/dataapi/v2/exchangerates/")
            if test is None:
                continue
            tests = test.text
            print tests

# #----------------------------------------------------------------------
if __name__ == "__main__":
    parseXML("test/test.xml")
1
  • Are you literally replacing ServerAddr="http://api-stg.link.com/dataapi/v2/exchangerates/ with ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/exchangerates/? If so, you could consider just doing a replace: new_xml.replace('ServerAddr="http://api-stg.link.com/dataapi/v2/exchangerates/', 'ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/exchangerates/') Commented Aug 12, 2016 at 21:48

1 Answer 1

2

Consider using iter() across the elements with a conditional if replace:

import xml.etree.ElementTree as ET 

#----------------------------------------------------------------------
def parseXML(xml_file):
    """
    Parse XML with ElementTree
    """
    tree = ET.ElementTree(file=xml_file)
    root = tree.getroot()

    # get the information via the children!
    print("Iterating using getchildren()")

    for serv in root.iter('server'):
        for web in serv.iter('web-server-parm'):
                if 'http://api-stg.link.com' in web.get('ServerAddr'):
                    web.set('ServerAddr', web.get('ServerAddr').\
                        replace("http://api-stg.link.com", "http://api-DATA-stg.link.com"))

    print(ET.tostring(root).decode("UTF-8"))

    tree.write("ConfigRoot_py.xml")

# #----------------------------------------------------------------------
if __name__ == "__main__":
    parseXML("ConfigRoot.xml")

Output

<ConfigRoot>
  <max-layer layer="5" />
  <enabled-cache status="0" />
  <server type="fgrfreefr">
    <web-server-parm ApiKey="fgggdfvdffdgdfg" ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/securities?response=complex&amp;limit=9999999" X-API-ProductId="ADS" X-API-UserId="54456464561" mode="QA" timedOut="10000" />
    <web-server-parm ApiKey="@gggf-fsffff@" ServerAddr="http://api-uat.link.com/dataapi/v2/securities?response=complex&amp;limit=9999999" X-API-ProductId="ADS" X-API-UserId="gdfsgvhdgjfjuhgdyejhgsfegtb" mode="UAT" timedOut="10000" />
  </server>
  <server type="vfffdg">
    <web-server-parm ApiKey="fgvdgggdfgttggefr" ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/exchangerates/" X-API-ProductId="ADS" X-API-UserId="gsfsftfdfrfefrferf" mode="QA" timedOut="10000" />
    <web-server-parm ApiKey="@hdvfddfdd" ServerAddr="http://api-DATA-stg.link.com/dataapi/v2/exchangerates/" X-API-ProductId="ADS" X-API-UserId="gdfdagtgdfsgtrsdfsg" mode="UAT" timedOut="10000" />
  </server>
</ConfigRoot>
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you @Parfait! However, I have a giant XML that has a variation of links. I would not only like to edit http link with "exchange rates" but also with "securities."
In your current output, it only changes the second block of server.
But in your post, you specified replacing only this: http://api-stg.link.com/dataapi/v2/exchangerates/ which shows only once in your posted XML.
Yup that was my bad for not being clear. Do you know how I can fix this issue?
See updated script using str.replace(), replacing "http://api-stg.link.com" stem with "http://api-DATA-stg.link.com".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.