Modify xml using python

I have an xml file already generated by python and it looks like this. It has multiple items.

xml_screenshot

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle"  xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
    <title>title-name-xyz</title>
    <link>http://dist.stage.xyzgauri.com/qa/partner/mac.xml</link>
    <description>Most recent changes</description>
    <language>en</language>

<item>
<title>Version 3.0.22.4</title>
<sparkle:releaseNotesLink>
    https://dist.stage.xyzgauri.com.com/qa/partner/mac_notes.html
</sparkle:releaseNotesLink>
<pubDate>Thu, 12 Nov 2015 04:38:23 -0000</pubDate>
<enclosure
    url="https://dist.stage.xyzgauri.com/qa/sandisk/InstallCloud.3.0.22.4.pkg"
    sparkle:version="3.0.22.4"
    sparkle:shortVersionString="3.0.22"
    openlength="30455215"
    type="application/octet-stream"
    sparkle:dsaSignature="MCwCFHvf7peesvwR0AhRbZxTViLarxcjfd758mHPbnOW6wA=="
    sparkle:status="live"
/>

<item>
<title>Version 3.0.10.4</title>
<sparkle:releaseNotesLink>
    http://dist.stage.xyzgauri.com/qa/partner/mac_notes.html
</sparkle:releaseNotesLink>
<pubDate>Tue, 03 Nov 2015 04:31:18 -0000</pubDate>
<enclosure
    url="http://dist.stage.xyzgauri.com/qa/partner/InstallCloud.3.0.10.4.pkg"
    sparkle:version="3.0.10.4"
    sparkle:shortVersionString="3.0.10"
    openlength="29709636"
    type="application/octet-stream"
    sparkle:dsaSignature="MCwCFDPvLPr7lYkrx5L5XCDbhXYqrFkGzLtLePK6ng=="
    sparkle:status="live"
/>

I need to use python to change the sparkle:status from "live" to "expired" for the older version 3.0.10.4. This xml is later pushed to S3. I am a newbie to python and hence wondering how to implement this. I can even create a whole new jenkins jobs to get this xml and modify it and then push to S3. Any help is appreciated. Thanks.

Answers


Consider an XSLT solution using lxml package where you can avoid any looping through all elements as may be required of an XPath solution. The script here runs an identity transform to copy all nodes and attributes as is and then runs a template specifically on all instances of the attribute @sparkle:status where its sibling in attribute set @sparkle:version='3.0.10.4'. Note too I had to declare the sparkle namespace in XSLT's header.

Below loads the XSLT script as a string but you can parse it from external file (saved in .xsl or .xslt format) like you do your XML file.

import lxml.etree as ET

# LOAD XML LAND XSL
dom = ET.parse('Input.xml')

xslstr='''<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                         xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
          <xsl:output version="1.0" encoding="UTF-8" indent="yes" />

            <!-- Identity Transform -->
            <xsl:template match="@*|node()">
              <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
              </xsl:copy>
            </xsl:template>

            <xsl:template match="enclosure[@sparkle:version='3.0.10.4']/@sparkle:status">    
              <xsl:attribute name="sparkle:status">expired</xsl:attribute>    
            </xsl:template>

          </xsl:transform>'''  

xslt = ET.fromstring(xslstr)

# TRANSFORM XML 
transform = ET.XSLT(xslt)
newdom = transform(dom)    

# SAVE OUTPUT
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True,  xml_declaration=True)
print(tree_out.decode("utf-8"))

xmlfile = open('Output.xml','wb')
xmlfile.write(tree_out)
xmlfile.close()

Need Your Help

Native JDK code to copy files

java file streaming copy buffer

Is there a native JDK code to copy files(buffers, streams, or whatever)?