【问题标题】:Elementtree and Unicode or UTF-8 confusionElementtree 与 Unicode 或 UTF-8 混淆
【发布时间】:2013-11-19 07:52:36
【问题描述】:

好吧,我现在有点失落。我对 unicode(或 utf-8 ?)有一些问题

我在 linux 上使用 Python3.3(但我在 windows 上遇到了同样的问题)。

我尝试用 Elementtree 创建一个 XML 文件。

    item = ET.Element("item")
    item_title = Et.SubElement(item, "title")

这当然不是全部,只是一个例子。 所以现在我想让标签“标题”有这样的文字(用随机内容替换##Content##,没关系):

    # Thats how I create the text for the tag
    item.title.text = u'<![CDATA[##CONTENT##]>'

    # This is how I want it to look like
    <title><![CDATA[##CONTENT##]></title>

    # Thats what I get
    <title>&lt;![CDATA[##CONTENT##]&gt;</title>

    # These are some of the things I tried for writing it to an xml file
    ET.ElementTree(item).write(myOutputFile, encoding="unicode")
    myOutputFile.write(ET.tostring(item, encoding='unicode', method='xml')))
    myOutputFile.write(str(ET.tostring(item, encoding='utf-8', method='xml'))) 
    myOutputFile.write(str(ET.tostring(item)

    # Oh and thats how I open the file for writing
    myOutputFile = codecs.open(HereIsMyFile, 'w', encoding='utf-8')

我尝试搜索并发现了一些类似的听起来问题(我尝试过的一些东西已经来自 SO),但似乎没有一个有效。他们更改了输出中的一些内容,但从未显示 。 我还注意到,如果我使用 utf-8,我必须在写入文件时使用 str()。这也让我对 unicode 和 utf-8 的区别感到困惑,我试图阅读一些关于此的内容,但这并没有真正帮助我解决实际问题。

此时,我真的不知道在哪里寻找我的错误,我很想知道在哪里寻找。 这是我写入文件的方式吗?我怎么打开它? 还是 Elementtree 导致了错误? (我没有尝试其他东西,比如 lxml,因为好吧,我猜这意味着要重写很多东西)。

我希望你能帮助我,如果有什么不清楚的地方,我会试着解释得更好一点!

编辑:哦,我也尝试在没有编解码器的情况下打开文件,因为我在某处读到它在 Python3.x 中不再需要,但我不再那么确定了,所以我试了一下。

【问题讨论】:

  • 1.你得到什么错误?
  • 如果您引用“或者是 Elementtree 导致错误”,我可能必须纠正自己,我没有从 python 得到实际错误,但文件中的输出不是如何我希望它看起来像。

标签: python xml unicode utf-8


【解决方案1】:
  1. 使用 ElementTree 编写 XML 文档的正确方法是:

    使用 codecs.open(HereIsMyFile, 'w', encoding='utf-8'): root.write(myOutputFile)

  2. 如果为write() 指定编码,则必须使用what the XML standard definesunicode 不是编码,而是标准。

  3. ElementTree 不支持 CDATA。您看到的效果是 ElementTree 注意到节点的 text 中的特殊字符并将其转义;没有办法阻止这种情况。

    此答案包含 CDATA 元素的实现:How to output CDATA using ElementTree

【讨论】:

  • 感谢您的快速回答,使用 CDATA 链接中的解决方案帮助我在快速测试中解决了我的 问题!
【解决方案2】:

这里似乎有几层混乱。

先走低层:UTF-8等编码将Unicode字符转换成字节。你的问题是你生成的 XML 中的字符不是你想要的,与这些字符如何存储为字节无关,所以那里没有什么可以修复的。

其次,您似乎从这一行中期待错误的东西:

item.title.text = u'<![CDATA[##CONTENT##]>'

这告诉 ElementTree 您希望在已解析文档中包含该文本。考虑一下:

item.title.text = u'I <3 ASCII art.'

ElementTree 不会将其直接存储在标记中:它会将其转换为

<title>I &lt;3 ASCII art.</title>

同样:

item.title.text = u"This </title> isn’t the end of the title"

变成

<title>This &lt;/title&gt; isn&#8217;t the end of the title</title>

希望您能看到它的价值:无论您在其中放置什么文本,它都不会破坏元素标记,或者确实以任何方式影响它。

请注意,由于这种自动转换,您很可能根本不需要 CDATA 部分

如果出于某种原因你这样做了,你可以通过明确说明来做到这一点(使用 lxml.etree):

title = lxml.etree.Element('title')
title.text = lxml.etree.CDATA('###CONTENT###')
print(lxml.etree.tostring(title))

输出:

<title><![CDATA[###CONTENT###]]></title>

【讨论】:

  • 非常感谢!对于迟到的回复,我们深表歉意。我今天将尝试您的解决方案,因为它看起来比我现在使用的更好。可悲的是,我确实需要 CDATA :( 非常好的解释!
猜你喜欢
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 2020-01-28
  • 2016-05-03
  • 2014-02-13
  • 2013-02-02
  • 2017-07-02
  • 1970-01-01
相关资源
最近更新 更多