3

I am trying to write this text value to the XML tag like this

 <Parameter name="name"><![CDATA[xyzvalue]]></Parameter>

Whenever, i am setting this value as text to this tag. It generates it like this

<Parameter name="name">&lt;![CDATA[xyzvalue]]&gt;</Parameter>

I need have tried to avoid unescape characters in the code

ET.SubElement(parameters, "Parameter", name="id").text = unescape("&lt;![CDATA[xyzvalue]]>")

How can i avoid it writing like this to the xml file ? I need to avoid escaping characters in the XML.

This is my complete code:

map = ET.Element("Map")

parameters = ET.SubElement(map, "Parameters")
ET.SubElement(parameters, "Parameter", name="bounds").text = "-180,-85.05112877980659,180,85.05112877980659"
ET.SubElement(parameters, "Parameter", name="center").text = "0,0,2"
ET.SubElement(parameters, "Parameter", name="format").text = "png"
ET.SubElement(parameters, "Parameter", name="minzoom").text = "0"
ET.SubElement(parameters, "Parameter", name="maxzoom").text = "22"
ET.SubElement(parameters, "Parameter", name="scale").text = "1"
ET.SubElement(parameters, "Parameter", name="metatile").text = "2"
ET.SubElement(parameters, "Parameter", name="id").text = unescape("&lt;![CDATA[xyzvalue]]>")
ET.SubElement(parameters, "Parameter", name="_updated").text = "1552288036000"
ET.SubElement(parameters, "Parameter", name="name").text = "<![CDATA[xyzvalue]]>"
ET.SubElement(parameters, "Parameter", name="tilejson").text = "<![CDATA[2.0.0]]>"
ET.SubElement(parameters, "Parameter", name="scheme").text = "<![CDATA[xyz]]>"

indent(map)
tree = ET.ElementTree(map)
tree.write("plotfinder_tiles.xml", xml_declaration=True, encoding='utf-8', method="xml")

This is different to How to output CDATA using ElementTree, in a way, that i have this issue at the Element creation not to prettify/ remove after xml has been created.

4
  • Show your code. Commented Mar 13, 2019 at 12:07
  • see the updated question Commented Mar 13, 2019 at 12:09
  • Not familiar with the library you're using, but you probably need to set the HTML property rather than text. Commented Mar 13, 2019 at 12:11
  • i tried it with .html, and this is the error : AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'html' Commented Mar 13, 2019 at 12:12

1 Answer 1

6

If it were me, I'd use lxml's CDATA class.

However, if you wanted to stick with ElementTree you could probably redefine ET._escape_cdata and make sure the text doesn't start with <![CDATA[ and doesn't end with ]]> before escaping.

Example...

Python 3.#

import xml.etree.ElementTree as ET


def escape_cdata(text):
    # escape character data
    try:
        if not text.startswith("<![CDATA[") and not text.endswith("]]>"):
            if "&" in text:
                text = text.replace("&", "&amp;")
            if "<" in text:
                text = text.replace("<", "&lt;")
            if ">" in text:
                text = text.replace(">", "&gt;")
        return text
    except (TypeError, AttributeError):
        ET._raise_serialization_error(text)


ET._escape_cdata = escape_cdata

map_elem = ET.Element("Map")

parameters = ET.SubElement(map_elem, "Parameters")
ET.SubElement(parameters, "Parameter", name="bounds").text = "-180,-85.05112877980659,180,85.05112877980659"
ET.SubElement(parameters, "Parameter", name="center").text = "0,0,2"
ET.SubElement(parameters, "Parameter", name="format").text = "png"
ET.SubElement(parameters, "Parameter", name="minzoom").text = "0"
ET.SubElement(parameters, "Parameter", name="maxzoom").text = "22"
ET.SubElement(parameters, "Parameter", name="scale").text = "1"
ET.SubElement(parameters, "Parameter", name="metatile").text = "2"
ET.SubElement(parameters, "Parameter", name="id").text = "<![CDATA[xyzvalue]]>"
ET.SubElement(parameters, "Parameter", name="_updated").text = "1552288036000"
ET.SubElement(parameters, "Parameter", name="name").text = "<![CDATA[xyzvalue]]>"
ET.SubElement(parameters, "Parameter", name="tilejson").text = "<![CDATA[2.0.0]]>"
ET.SubElement(parameters, "Parameter", name="scheme").text = "<![CDATA[xyz]]>"

tree = ET.ElementTree(map_elem)
tree.write("test.xml", xml_declaration=True, encoding='utf-8', method="xml")

XML Output (test.xml; pretty printed for readability)

<Map>
    <Parameters>
        <Parameter name="bounds">-180,-85.05112877980659,180,85.05112877980659</Parameter>
        <Parameter name="center">0,0,2</Parameter>
        <Parameter name="format">png</Parameter>
        <Parameter name="minzoom">0</Parameter>
        <Parameter name="maxzoom">22</Parameter>
        <Parameter name="scale">1</Parameter>
        <Parameter name="metatile">2</Parameter>
        <Parameter name="id"><![CDATA[xyzvalue]]></Parameter>
        <Parameter name="_updated">1552288036000</Parameter>
        <Parameter name="name"><![CDATA[xyzvalue]]></Parameter>
        <Parameter name="tilejson"><![CDATA[2.0.0]]></Parameter>
        <Parameter name="scheme"><![CDATA[xyz]]></Parameter>
    </Parameters>
</Map>

Update: Function for Python 2.7

def escape_cdata(text, encoding):
    # escape character data
    try:
        if not text.startswith("<![CDATA[") and not text.endswith("]]>"):
            if "&" in text:
                text = text.replace("&", "&amp;")
            if "<" in text:
                text = text.replace("<", "&lt;")
            if ">" in text:
                text = text.replace(">", "&gt;")
        return text.encode(encoding, "xmlcharrefreplace")
    except (TypeError, AttributeError):
        ET._raise_serialization_error(text)
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. I have &quot; as well in the output XML. Can you help me that, how can i solve this ?
Hi, I am having this error with it TypeError: escape_cdata() takes exactly 1 argument (2 given)
@AhsanMukhtar - can you update your question with the code you’re trying? Also, what version of python are you using?
I am using Python 2.7
@AhsanMukhtar - I will try to reproduce with 2.7. My code above was tested with 3.7.
|

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.