如何在minidom中禁用“输出转义”

时间:2011-01-17 05:54:19

标签: python xml

我正在尝试使用xml.dom.minidom从头开始构建xml文档。在我尝试使用®(注册商标)符号制作文本节点之前,一切进展顺利。我的目标是当我最终点击print mydoc.toxml()时,此特定节点实际上将包含®符号。

首先我尝试了:

import xml.dom.minidom as mdom
data = '®'

给出了相当明显的错误:

  File "C:\src\python\HTMLGen\test2.py", line 3
SyntaxError: Non-ASCII character '\xae' in file C:\src\python\HTMLGen\test2.py on line 3, but no encoding declared; see http://www.python.or
g/peps/pep-0263.html for details

我当然也尝试使用开头行注释方法将我的python脚本的编码更改为'utf-8',但这没有帮助。

所以我想

import xml.dom.minidom as mdom

data = '®'  #Both accepted xml encodings for registered trademark
data = '®'

text = mdom.Text()
text.data = data

print data
print text.toxml()

但是因为当我打印text.toxml()时,&符号被转义,我得到了这个输出:

®
®

我的问题是,是否有人知道我可以强制不在输出中转义&符号的方式,以便我可以将我的特殊字符引用传递给XML文档?

基本上,对于此节点,我希望print text.toxml()以愉快和合作的方式生成®®的输出!

编辑1

顺便说一句,如果minidom实际上没有这个容量,我很高兴使用你可以推荐的另一个模块。

编辑2

正如Hugh所说,我尝试使用data = u'®'(同时也使用数据# -*- coding: utf-8 -*- Python源代码)。这几乎有助于它实际上导致®符号本身输出到我的xml。这实际上不是我要找的结果。正如您现在可能已经猜到的那样(也许我之前应该已经指定过),这个xml文档恰好是一个HTML页面,需要在浏览器中运行。因此,在文档中使用®会导致浏览器中的垃圾(®准确无误!)。

我也尝试过:

data = unichr(174)
text.data = data.encode('ascii','xmlcharrefreplace')
print text.toxml()

但当然这导致同样的原始问题,所有发生的事情是&符号被.toxml()转义。

我的理想情况是逃避&符号的某种方式,以便XML打印功能不会代表我为文档“逃避”(换句话说,实现我最初的目标是®®出现在文档中。

似乎很快我将不得不求助于正则表达式!

编辑2a

或许不是。似乎让我的html元信息正确<META http-equiv="Content-Type" Content="text/html; charset=UTF-8">可能会有所帮助,但我不确定它是如何适应xml结构的......

3 个答案:

答案 0 :(得分:3)

两个有用的选项,一个有转义&#174;而另一个没有。你想要转义的原因并不是很明显......对于非CJK字符来说,它是6个字节而不是2个或3个字节。

import xml.dom.minidom as mdom
text = mdom.Text()
# Start with unicode
text.data = u'\xae'

f = open('reg1.html', 'w')
f.write("header saying the file is ascii")
uxml = text.toxml()
bxml = uxml.encode('ascii', 'xmlcharrefreplace')
f.write(bxml)
f.close()

f = open('reg2.html', 'w')
f.write("header saying the file is UTF-8")
xml = text.toxml(encoding='UTF-8')
f.write(xml)
f.close()

答案 1 :(得分:2)

如果我理解正确,您真正想要的是能够从unicode对象(例如u'®'u'\u00ae')创建文本节点,然后{{1}输出编码为实体的unicode字符(例如toxml())。但是,查看minidom.py的来源,似乎minidom不支持输出上的实体编码,除了&#174;&"和{{1}的特殊情况}。

但是,您也会询问可能有用的替代模块。有几种可能的候选者,但ElementTree(xml.etree)似乎做了适当的编码。例如,如果您从this blog post by Doug Hellmann获取第一个示例,则替换:

<

... with:

>

...并运行脚本,您应该看到输出包含:

child_with_tail.text = 'This child has regular text.'

只需将import语句替换为:

,您也可以在该示例中使用lxml implementation of ElementTree
child_with_tail.text = u'This child has regular text \u00ae.'

更新:替代answer from John Machin采用了在minidom的This child has regular text&#174;. 输出上运行from lxml.etree import Element, SubElement, Comment, tostring 的好方法,它将任何非ASCII字符转换为等效的XML数字字符引用。

答案 2 :(得分:0)

默认unescape:

from xml.sax.saxutils import unescape
unescape("&lt; &amp; &gt;")

结果是,

'< & >'

而且,更多的是:

unescape("&apos; &quot;", {"&apos;": "'", "&quot;": '"'})

点击此处查看详情https://wiki.python.org/moin/EscapingXml