我正在尝试使用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结构的......
答案 0 :(得分:3)
两个有用的选项,一个有转义®
而另一个没有。你想要转义的原因并不是很明显......对于非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不支持输出上的实体编码,除了®
,&
,"
和{{1}的特殊情况}。
但是,您也会询问可能有用的替代模块。有几种可能的候选者,但ElementTree(xml.etree)似乎做了适当的编码。例如,如果您从this blog post by Doug Hellmann获取第一个示例,则替换:
<
... with:
>
...并运行脚本,您应该看到输出包含:
child_with_tail.text = 'This child has regular text.'
只需将import语句替换为:
,您也可以在该示例中使用lxml implementation of ElementTreechild_with_tail.text = u'This child has regular text \u00ae.'
更新:替代answer from John Machin采用了在minidom的This child has regular text®.
输出上运行from lxml.etree import Element, SubElement, Comment, tostring
的好方法,它将任何非ASCII字符转换为等效的XML数字字符引用。
答案 2 :(得分:0)
默认unescape:
from xml.sax.saxutils import unescape
unescape("< & >")
结果是,
'< & >'
而且,更多的是:
unescape("' "", {"'": "'", """: '"'})