0

I'm trying to replace the attribute value in my XML file using Element Tree in python. As a result XML file declaration <?xml version='1.0'?> is removed.

Python version is 2.7.13 and from doc its mentioned that "Changed in version 2.7: The ElementTree API is updated to 1.3." In turn from this we can understand that

tree.write("file.xml", xml_declaration=True)

will add the declaration but I'm unable to add the declaration itself from the above statement.

Like mentioned in other references :

tree.write("file.xml",xml_declaration=True, encoding='UTF-8') writes the version along with the encoding parameter but I'm not expecting this in the XML file.

Any insights just to add the XML declaration with version number would be great! Thanks in advance.

1 Answer 1

1

Because that is a bit of a sophisticated rendering beyond elementTree, consider XSLT, the special-purpose language designed to transform XML files. Python can run XSLT 1.0 scripts with third-party module, lxml, or via command line to an external .exe like Unix's (Mac/Linux) xsltproc.

Specifically, the below XSLT script runs the Identity Transform to copy document as is and removes encoding from header declaration and retains version.

XSLT (save as .xsl file, a special .xml file)

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

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

    <xsl:template match="/">
        <xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0"?>]]>&#xa;</xsl:text>
          <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

</xsl:stylesheet>

Python (using lxml)

import lxml.etree as et

... 
# LOAD XSL
xsl = et.parse('xslt_script.xsl')

# TRANSFORM ORIGINAL tree
transform = et.XSLT(xsl)
result = transform(tree)

# PRINT RESULT TO SCREEN
print(result)

# OUTPUT RESULT TO FILE
with open('output.xml', 'wb') as f:
    f.write(result)

Python (using command line to xsltproc)

from subprocess import Popen

...
tree.write("file.xml", xml_declaration=True)

proc = Popen(['xsltproc -o output.xml xslt_script.xsl file.xml'], 
             shell=True, cwd='/path/to/working/directory',
             stdin=None, stdout=None, stderr=None)
Sign up to request clarification or add additional context in comments.

Comments

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.