4

I have the following xml file. I need to automate find/replace some strings in a bunch of files for different environment. I am using python 2.7. I need to pass the environment name and read the xml into a dictionary or array, which I can then use to find/replace the strings. I have tried using ElementTree, but unsure how to build dict containing old/new texts for each environment. Any suggestions please..

     <?xml version="1.0" encoding="utf-8" ?>
    <Config>
    <Environment env="Support">
      <sitedir path="d:\Support_463\REST Elements\Sites"/>
      <workflowdir path="d:\Support_463\REST 
    Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-supp"/>
        <text old="yhz" new="vr"/>
        <text old="ax7" new="sh66^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-suppx"/>
        <text old="yhsxz" new="v*&9r"/>
        <text old="ax7" new="(()&4fg"/>
      </workflowreplacements>
</Environment>
<Environment env="Test">
      <sitedir path="d:\Test_463\REST Elements\Sites"/>
      <workflowdir path="d:\Test_463\REST Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-test"/>
        <text old="yhz" new="vxxAr"/>
        <text old="ax7" new="s8%6^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-testx"/>
        <text old="yhsxz" new="vr"/>
        <text old="ax7" new="$%^"/>
      </workflowreplacements>
</Environment>
<!--<Environment env="Preprod">
      <sitedir path=""/>
      <workflowdir path=""/>
      <sitereplacements>
        <text old="" new=""/>
        <text old="" new=""/>
        <text old="" new=""/>
      </sitereplacements>
      <workflowreplacements>
        <text old="" new=""/>       
        <text old="" new=""/>
        <text old="" new=""/>
      </workflowreplacements>-->
</Environment>

1
  • You never close the <Config> tag, so this is not valid XML. Commented Feb 26, 2018 at 11:47

2 Answers 2

6

The simplest way to convert your XML to dictionary is by using the xmltodict module.

Example:

import xmltodict
s = """<?xml version="1.0" encoding="utf-8" ?>
    <Config>
    <Environment env="Support">
      <sitedir path="d:\Support_463\REST Elements\Sites"/>
      <workflowdir path="d:\Support_463\REST 
    Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-supp"/>
        <text old="yhz" new="vr"/>
        <text old="ax7" new="sh66^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-suppx"/>
        <text old="yhsxz" new="v9r"/>
        <text old="ax7" new="(()4fg"/>
      </workflowreplacements>
</Environment>
<Environment env="Test">
      <sitedir path="d:\Test_463\REST Elements\Sites"/>
      <workflowdir path="d:\Test_463\REST Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-test"/>
        <text old="yhz" new="vxxAr"/>
        <text old="ax7" new="s8%6^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-testx"/>
        <text old="yhsxz" new="vr"/>
        <text old="ax7" new="$%^"/>
      </workflowreplacements>
</Environment>
</Config>
"""
print xmltodict.parse(s)

Output:

OrderedDict([(u'Config', OrderedDict([(u'Environment', [OrderedDict([(u'@env', u'Support'), (u'sitedir', OrderedDict([(u'@path', u'd:\\Support_463\\REST Elements\\Sites')])), (u'workflowdir', OrderedDict([(u'@path', u'd:\\Support_463\\REST      Elements\\Sites\\Resources\\Workflows')])), (u'sitereplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-supp')]), OrderedDict([(u'@old', u'yhz'), (u'@new', u'vr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'sh66^')])])])), (u'workflowreplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-suppx')]), OrderedDict([(u'@old', u'yhsxz'), (u'@new', u'v9r')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'(()4fg')])])]))]), OrderedDict([(u'@env', u'Test'), (u'sitedir', OrderedDict([(u'@path', u'd:\\Test_463\\REST Elements\\Sites')])), (u'workflowdir', OrderedDict([(u'@path', u'd:\\Test_463\\REST Elements\\Sites\\Resources\\Workflows')])), (u'sitereplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-test')]), OrderedDict([(u'@old', u'yhz'), (u'@new', u'vxxAr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u's8%6^')])])])), (u'workflowreplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-testx')]), OrderedDict([(u'@old', u'yhsxz'), (u'@new', u'vr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'$%^')])])]))])])]))])
Sign up to request clarification or add additional context in comments.

1 Comment

Nice concise answer. Too many people on similar questions overcomplicating matters. Works perfectly.
0

You can use xml.etree.ElementTree as ET.

Check below link for more details

https://docs.python.org/2/library/xml.etree.elementtree.html

19.7.1.3. Finding interesting elements & 19.7.1.4. Modifying an XML File

2 Comments

this is a comment, not an answer
Thanks for the responses. I can now use ElementTree successfully to read this. However, am struggling with using xpath for case sensitive values xmlEl = root.find('.//Environment[@env="%s"]' %env). I would need to convert @env to lowercase and then use find.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.