1

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

我在 linux 上使用 Python3.3(但我在 windows 上也有同样的问题)。

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

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

这当然不是全部,只是一个例子。所以现在我想让标签'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 中不再需要,但我不再那么确定了,所以我试了一下。

4

2 回答 2

1
  1. 使用 ElementTree 编写 XML 文档的正确方法是:

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

  2. 如果为 指定编码write(),则必须使用XML 标准定义的内容unicode不是编码,而是标准。

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

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

于 2013-11-07T15:40:22.177 回答
1

这里似乎有几层混乱。

先取较低层: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>
于 2013-11-07T16:14:45.997 回答