我正在使用Python的elementtree模块来编写一些XML(我正在使用Python 2.7和3.2).我的某些元素的文本字段包含数字字符引用.
但是,一旦我使用elementtree的字符串将字符引用中的所有“&”号替换为& amp; amp;.显然,elementtree或基础分析器无法识别此处的&符号是数字字符引用的一部分.
经过一番搜索,我发现:elementtree and entities
但是,我也不热衷于此,因为在我当前的代码中,我预见这可能最终会导致自身的问题.除此之外,我对此几乎没有发现,所以也许我只是忽略了一些明显的东西?
以下简单的测试代码说明了该问题(已使用Python 2.7和3.2进行了测试):
import sys
import xml.etree.ElementTree as ET
def main():
# Text string that contains numeric character reference
someText = "Ström"
# Create element object
testElement = ET.Element('rubbish')
# Add someText to element's text attribute
testElement.text = someText
# Convert element to xml-formatted text string
testElementAsString = ET.tostring(testElement,'ascii', 'xml')
print(testElementAsString)
# Result: ampersand replaced with '&': <rubbish>Str&#246;m</rubbish>
main()
如果有人有任何想法或建议,那就太好了!
解决方法:
您需要解码输入中的字符引用.这是一个将解码数字字符引用和html命名引用的函数.它接受一个字节字符串作为输入并返回unicode.以下代码适用于Python 2.7或3.x.
import re
try:
from htmlentitydefs import name2codepoint
except ImportError:
# Must be Python 3.x
from html.entities import name2codepoint
unichr = chr
name2codepoint = name2codepoint.copy()
name2codepoint['apos']=ord("'")
EntityPattern = re.compile('&(?:#(\d+)|(?:#x([\da-fA-F]+))|([a-zA-Z]+));')
def decodeEntities(s, encoding='utf-8'):
def unescape(match):
code = match.group(1)
if code:
return unichr(int(code, 10))
else:
code = match.group(2)
if code:
return unichr(int(code, 16))
else:
code = match.group(3)
if code in name2codepoint:
return unichr(name2codepoint[code])
return match.group(0)
return EntityPattern.sub(unescape, s.decode(encoding))
someText = decodeEntities(b"Ström")
print(someText)
当然,如果您可以避免以字符串开头的字符引用作为开始,那会使您的生活更加轻松.