【问题标题】:Python ElementTree unescapes HTML entitiesPython ElementTree 取消转义 HTML 实体
【发布时间】:2014-09-01 11:38:18
【问题描述】:

我编写了一个将 XML 解析为逗号分隔格式的简单脚本。一个样品 XML 源代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<users>
<row Id="-1" Reputation="1" CreationDate="2010-08-10T15:50:26.953" DisplayName="Community" LastAccessDate="2010-08-10T15:50:26.953" Location="on the server farm" AboutMe="&lt;p&gt;Hi, I'm not really a person.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I'm a background process that helps keep this site clean!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I do things like&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Randomly poke old unanswered questions every hour so they get some attention&lt;/li&gt;&#xA;&lt;li&gt;Own community questions and answers so nobody gets unnecessary reputation from them&lt;/li&gt;&#xA;&lt;li&gt;Own downvotes on spam/evil posts that get permanently deleted&lt;/li&gt;&#xA;&lt;li&gt;Own suggested edits from anonymous users&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;http://meta.stackexchange.com/a/92006&quot;&gt;Remove abandoned questions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;" Views="0" UpVotes="3732" DownVotes="2275" AccountId="-1" />
</users>

gist

解析器的相关代码是这样的:

import xml.etree.cElementTree as cetree

def get_data_c(fn, columns):
    res = ''
    cols = columns.split(',')

    for c in cols:
        res = res + c + ','

    res = res[:-1] + '\n'
    yield res

    for event, elem in cetree.iterparse(fn):
        res = ''
        if elem.tag == "row":
            for c in cols:
                if c in elem.attrib:
                    res = res + elem.attrib[c] + ','
                else:
                    res = res + ','
            res = res[:-1] + '\n'
            yield res
            elem.clear()

gist 的完整脚本。

我的问题是当我得到AboutMe 属性的值时,cElementTree 正在取消转义该属性中包含的 HTML。理想情况下,我想 将格式保持为转义的 HTML,并简单地将其包装在引号中以输出 文件。但是我得到的是未转义的字符串,如此处所示 gist。我怎么告诉 cElementTree 保持属性的原始值而不是变换 转换成 HTML?

编辑 2014-09-01 12:49 PST:根据下面 Tomalak 的回答,这就是我用来获得我正在寻找的行为的原因:

def escape_str(html_str):
    s = html.escape(html_str)
    return s.replace('\n', '&#xA;')

我基本上是将调用包装起来以获取转义周围的属性值 上面的功能。像这样:

res = res + '"' + escape_str(elem.attrib[c]) + '",'

【问题讨论】:

  • 可能重复 stackoverflow.com/questions/5153693/…。简而言之,您可以使用cdata 属性来完成此操作
  • @MaNKuR 请提供代码示例。
  • 一般来说,我建议将代码保留在问题中,以避免在外部链接失效时出现碎片。您可以链接到 Gists 作为备份,但我强烈建议您直接在此处发布大约六行相关的 Python 和 XML 行。
  • @Tomalak 完成,代码现在与问题内联。
  • +1 创造性地解决它并分享解决方案。请问您为什么坚持使用 HTML 转义值?我不知何故看不到它的用途是什么......

标签: python xml python-3.x elementtree


【解决方案1】:

属性中没有转义的 HTML。

属性中有 HTML,这正是您检索其值时得到的内容。

比较:

<row AboutMe="&lt;b&gt; This is HTML &lt;/b&gt;" />

Attribute value: "<b> This is HTML </b>"

和:

<row AboutMe="&amp;lt;b&amp;gt; This is escaped HTML &amp;lt;/b&amp;gt;" />

Attribute value: "&lt;b&gt; This is escaped HTML &lt;/b&gt;"

你的错误是当正确的事情发生时你期待错误的事情发生。 cElementTree 绝对不会 逃避任何事情。它为您逐字提供属性。

【讨论】:

  • 感谢您的澄清。如何在不将 &amp;lt;b&amp;gt; 转换为 &lt;b&gt; 标记的情况下从属性值中获取原始文本?
  • 您不能,因为 XML 不包含该值。 XML 包含"&lt;b&gt;",这是您可以从中获得的唯一内容。不要将 XML 视为文本文件。它不是。 XML 是数据结构的序列化表示。序列化过程有一定的含义,例如字符串"&lt;b&gt;"变成"&amp;lt;b&amp;gt;"。反序列化(即“解析”)逆转了这一点。不要让这让你感到困惑。您只能从 XML 文档中获取其中的实际内容。 (提示:如果你想对该字符串进行 XML 编码,可以使用相应的函数。)
  • 看来我需要在将值写入 CSV 文件之前实际转义 HTML。
  • 是的,这就是您真正需要做的。这样看:您需要根据 CSV 规则将数据序列化为 CSV。 HTML 转义不一定是 CSV 序列化规则的一部分。 "enclose value in double quotes, escape contains double quotes" 之类的东西更可能是正确的。查看csv 模块以及它如何处理包含空格、引号和可能的换行符的数据。
猜你喜欢
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
相关资源
最近更新 更多