【问题标题】:Avoid writing < character to XML in python避免在python中将<字符写入XML
【发布时间】:2019-03-13 12:05:23
【问题描述】:

我正在尝试像这样将此文本值写入 XML 标记

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

每当我将此值设置为该标签的文本时。它像这样生成它

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

我需要尽量避免代码中出现转义字符

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

如何避免它像这样写入 xml 文件?我需要避免在 XML 中转义字符。

这是我的完整代码:

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")

这与How to output CDATA using ElementTree 不同,在某种程度上,我在创建元素时遇到了这个问题,不能在创建 xml 后美化/删除。

【问题讨论】:

  • 显示您的代码。
  • 查看更新后的问题
  • 不熟悉您使用的库,但您可能需要设置 HTML 属性而不是文本。
  • 我用 .html 尝试过,这是错误:AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'html'

标签: python xml python-2.7 elementtree


【解决方案1】:

如果是我,我会使用lxml's CDATA class

但是,如果您想坚持使用 ElementTree,可以重新定义 ET._escape_cdata 并确保文本在转义之前不以 &lt;![CDATA[ 开头并且不以 ]]&gt; 结尾.

示例...

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 输出(test.xml;为了便于阅读而打印得很漂亮)

<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>

更新: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)

【讨论】:

  • 谢谢。我有“以及在输出 XML 中。你能帮我解决这个问题吗?
  • 嗨,我遇到了这个错误 TypeError: escape_cdata() 只需要 1 个参数(给定 2 个)
  • @AhsanMukhtar - 你能用你正在尝试的代码更新你的问题吗?另外,你用的是什么版本的python?
  • 我使用的是 Python 2.7
  • @AhsanMukhtar - 我会尝试用 2.7 重现。我上面的代码是用 3.7 测试的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 2015-03-25
  • 2018-07-19
  • 2023-03-09
  • 1970-01-01
  • 2016-05-14
  • 2011-03-25
相关资源
最近更新 更多