Search code examples
pythonpython-3.xxmlelementtreeprocessing-instruction

How to insert a processing instruction in XML file?


I want to add a xml-stylesheet processing instruction before the root element in my XML file using ElementTree (Python 3.8).

You find as below my code that I used to create XML file

import xml.etree.cElementTree as ET

def Export_star_xml( self ):
        star_element = ET.Element("STAR",**{ 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance' })
        element_node = ET.SubElement(star_element ,"STAR_1")
        element_node.text = "Mario adam"
        tree.write( "star.xml" ,encoding="utf-8", xml_declaration=True )

Output:

<?xml version="1.0" encoding="windows-1252"?>
<STAR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <STAR_1> Mario adam </STAR_1>
</STAR>    

Output Expected:

<?xml version="1.0" encoding="windows-1252"?>
<?xml-stylesheet type="text/xsl" href="ResourceFiles/form_star.xsl"?>
<STAR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <STAR_1> Mario adam </STAR_1>
</STAR>

Solution

  • I cannot figure out how to do this with ElementTree. Here is a solution that uses lxml, which provides an addprevious() method on elements.

    from lxml import etree as ET
    
    # Note the use of nsmap. The syntax used in the question is not accepted by lxml
    star_element = ET.Element("STAR", nsmap={'xsi': 'http://www.w3.org/2001/XMLSchema-instance'})
    element_node = ET.SubElement(star_element ,"STAR_1")
    element_node.text = "Mario adam"
    
    # Create PI and and insert it before the root element
    pi = ET.ProcessingInstruction("xml-stylesheet", text='type="text/xsl" href="ResourceFiles/form_star.xsl"')
    star_element.addprevious(pi)
    
    ET.ElementTree(star_element).write("star.xml", encoding="utf-8",
                                       xml_declaration=True, pretty_print=True)
    

    Result:

    <?xml version='1.0' encoding='UTF-8'?>
    <?xml-stylesheet type="text/xsl" href="ResourceFiles/form_star.xsl"?>
    <STAR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <STAR_1>Mario adam</STAR_1>
    </STAR>