转义字符串以在XML中使用

Ram*_*hum 31 python xml security escaping

我正在使用Python xml.dom.minidom来创建XML文档.(逻辑结构 - > XML字符串,而不是相反.)

如何让它逃脱我提供的字符串,这样他们就无法搞砸XML?

mba*_*hau 68

像这样的东西?

>>> from xml.sax.saxutils import escape
>>> escape("< & >")   
'&lt; &amp; &gt;'
Run Code Online (Sandbox Code Playgroud)

  • 这不会处理报价的转义. (11认同)
  • 正是我想要的。我的大多数XML处理都是使用lxml完成​​的,我想知道是否(再)导入另一个XML模块是否会被污染?lxml中是否有等效项?(似乎找不到一个。) (2认同)
  • >>> from xml.sax.saxutils import quoteattr >>> quoteattr('value contains"double-quote \'和撇号')'"value包含&一个双引号和一个撇号"' (2认同)
  • 这将导致现有的转义字符格式错误。例如,&amp;&变为&amp; amp;&amp; (2认同)
  • 回复:“这将导致现有的转义字符格式错误” - 这是错误的。现有的转义不会变得畸形,而是双重转义。这是预期的正确行为:如果您的输入同时包含转义和未转义的此类字符,那么要么它是无效输入,要么您希望逐字显示转义的字符,如文本“在 HTML 中,&amp; 使用 &amp; 进行编码”,其中最终的“&amp;”应以此形式显示给用户。这里需要双重逃逸。 (2认同)

And*_*ikh 12

你的意思是你做这样的事情:

from xml.dom.minidom import Text, Element

t = Text()
e = Element('p')

t.data = '<bar><a/><baz spam="eggs"> & blabla &entity;</>'
e.appendChild(t)
Run Code Online (Sandbox Code Playgroud)

然后你将得到很好的转义XML字符串:

>>> e.toxml()
'<p>&lt;bar&gt;&lt;a/&gt;&lt;baz spam=&quot;eggs&quot;&gt; &amp; blabla &amp;entity;&lt;/&gt;</p>'
Run Code Online (Sandbox Code Playgroud)


K L*_*K L 12

xml.sax.saxutils.escape只有逃跑&,<>默认,但它确实提供了一个entities参数,还逃避其他字符串:

from xml.sax.saxutils import escape

def xmlescape(data):
    return escape(data, entities={
        "'": "&apos;",
        "\"": "&quot;"
    })
Run Code Online (Sandbox Code Playgroud)

xml.sax.saxutils.escapestr.replace()内部使用,因此您也可以跳过导入并编写自己的函数,如MichealMoser的答案所示.


Mic*_*ser 11

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

所以这是另一个:

def escape( str ):
    str = str.replace("&", "&amp;")
    str = str.replace("<", "&lt;")
    str = str.replace(">", "&gt;")
    str = str.replace("\"", "&quot;")
    return str
Run Code Online (Sandbox Code Playgroud)

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

  • 最好避免使用关键字 `str` 作为变量名。 (5认同)
  • 你忘记了 `str = str.replace("'", "'")`。 (5认同)
  • 此外,`str = str.replace("\"", """)` 的替代方案是 `str = str.replace('"', """)`,我认为它更具可读性,因为反斜杠 (\\) 对我来说看起来格格不入。 (2认同)
  • 如果您不从此处复制粘贴,您应该注意到第一个替换是与符号(“&amp;”)。如果这不是第一个语句,您将替换其他语句的&符号...... (2认同)

use*_*028 11

安德烈·弗拉索夫斯基赫接受的答案是对OP最完整的答案。但这个主题出现在最频繁的搜索中,python escape xml我想对本文中讨论的三种解决方案进行时间比较,并提供我们选择部署的第四个选项,因为它提供了增强的性能。

\n

所有四个都依赖于本机 python 数据处理或 python 标准库。这些解决方案按性能从最慢到最快的顺序提供。

\n

选项 1 - 正则表达式

\n

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

\n
import re\ntable = {\n    "<": "&lt;",\n    ">": "&gt;",\n    "&": "&amp;",\n    "'": "&apos;",\n    '"': "&quot;",\n}\npat = re.compile("({})".format("|".join(table)))\n\ndef xmlesc(txt):\n    return pat.sub(lambda match: table[match.group(0)], txt)\n\n>>> %timeit xmlesc('<&>"\\'')\n1.48 \xc2\xb5s \xc2\xb1 1.73 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

选项 2 -- xml.sax.saxutils

\n

该解决方案使用 pythonxml.sax.saxutils库。

\n
from xml.sax.saxutils import escape\ndef xmlesc(txt):\n    return escape(txt, entities={"'": "&apos;", '"': "&quot;"})\n\n>>> %timeit xmlesc('<&>"\\'')\n832 ns \xc2\xb1 4.3 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

选项 3 - str.replace

\n

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

\n
def xmlesc(txt):\n    txt = txt.replace("&", "&amp;")\n    txt = txt.replace("<", "&lt;")\n    txt = txt.replace(">", "&gt;")\n    txt = txt.replace('"', "&quot;")\n    txt = txt.replace("'", "&apos;")\n    return txt\n\n>>> %timeit xmlesc('<&>"\\'')\n503 ns \xc2\xb1 0.725 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

选项 4 - str.translate

\n

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

\n
table = str.maketrans({\n    "<": "&lt;",\n    ">": "&gt;",\n    "&": "&amp;",\n    "'": "&apos;",\n    '"': "&quot;",\n})\ndef xmlesc(txt):\n    return txt.translate(table)\n\n>>> %timeit xmlesc('<&>"\\'')\n352 ns \xc2\xb1 0.177 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n