代码之家  ›  专栏  ›  技术社区  ›  Ram Rachum

在XML中使用转义字符串

  •  40
  • Ram Rachum  · 技术社区  · 16 年前

    xml.dom.minidom 创建XML文档。(逻辑结构->XML字符串,而不是相反。)

    7 回复  |  直到 8 年前
        1
  •  12
  •   Andrey Vlasovskikh    16 年前

    像这样?

    >>> from xml.sax.saxutils import escape
    >>> escape("< & >")   
    '&lt; &amp; &gt;'
    
        2
  •  63
  •   mbarkhau    15 年前

    xml.sax.saxutils不转义引号字符(“)

    所以这里是另一个:

    def escape( str_xml: str ):
        str_xml = str_xml.replace("&", "&amp;")
        str_xml = str_xml.replace("<", "&lt;")
        str_xml = str_xml.replace(">", "&gt;")
        str_xml = str_xml.replace("\"", "&quot;")
        str_xml = str_xml.replace("'", "&apos;")
        return str_xml
    

    如果你查找它,那么xml.sax.saxutils只会替换字符串

        3
  •  11
  •   K L    9 年前

    xml.sax.saxutils.escape & , < ,以及 > 默认情况下,但它确实提供了 entities

    from xml.sax.saxutils import escape
    
    def xmlescape(data):
        return escape(data, entities={
            "'": "&apos;",
            "\"": "&quot;"
        })
    

    用途 str.replace() 在内部,因此您也可以跳过导入并编写自己的函数,如MichealMoser的答案所示。

        4
  •  8
  •   twasbrillig    9 年前

    你是说你做了这样的事情:

    from xml.dom.minidom import Text, Element
    
    t = Text()
    e = Element('p')
    
    t.data = '<bar><a/><baz spam="eggs"> & blabla &entity;</>'
    e.appendChild(t)
    

    然后,您将得到转义良好的XML字符串:

    >>> e.toxml()
    '<p>&lt;bar&gt;&lt;a/&gt;&lt;baz spam=&quot;eggs&quot;&gt; &amp; blabla &amp;entity;&lt;/&gt;</p>'
    
        5
  •  4
  •   johndodo    12 年前

    安德烈·弗拉索夫斯基(Andrey Vlasovskikh)的公认答案是OP的最完整答案。但这个话题是最常见的搜索 python escape xml 我想对讨论的三种解决方案进行时间比较 在本文中,我们还提供了第四个选项,由于它提供了增强的性能,我们选择部署它。

    这四个都依赖于原生python数据处理或python标准库。解决方案是按照从最慢到最快的性能顺序提供的。

    选项1-正则表达式

    此解决方案使用python正则表达式库。它的性能最慢:

    import re
    table = {
        "<": "&lt;",
        ">": "&gt;",
        "&": "&amp;",
        "'": "&apos;",
        '"': "&quot;",
    }
    pat = re.compile("({})".format("|".join(table)))
    
    def xmlesc(txt):
        return pat.sub(lambda match: table[match.group(0)], txt)
    
    >>> %timeit xmlesc('<&>"\'')
    1.48 µs ± 1.73 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    仅供参考:s是微秒的符号,即100万分之一秒。另一个实现的完成时间以纳秒(ns)为单位,即十亿分之一秒。

    此解决方案使用python xml.sax.saxutils 图书馆。

    from xml.sax.saxutils import escape
    def xmlesc(txt):
        return escape(txt, entities={"'": "&apos;", '"': "&quot;"})
    
    >>> %timeit xmlesc('<&>"\'')
    832 ns ± 4.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    选项3-str.replace

    此解决方案使用字符串 replace() 方法。在幕后,它实现了与python类似的逻辑 xml.sax.saxutils saxutils代码有一个for循环,这会降低一些性能,使这个版本稍微快一些。

    def xmlesc(txt):
        txt = txt.replace("&", "&amp;")
        txt = txt.replace("<", "&lt;")
        txt = txt.replace(">", "&gt;")
        txt = txt.replace('"', "&quot;")
        txt = txt.replace("'", "&apos;")
        return txt
    
    >>> %timeit xmlesc('<&>"\'')
    503 ns ± 0.725 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    选项4-str.translate

    这是最快的实施方式。它使用字符串 translate() 方法。

    table = str.maketrans({
        "<": "&lt;",
        ">": "&gt;",
        "&": "&amp;",
        "'": "&apos;",
        '"': "&quot;",
    })
    def xmlesc(txt):
        return txt.translate(table)
    
    >>> %timeit xmlesc('<&>"\'')
    352 ns ± 0.177 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)