以UTF-8格式打印lxml错误日志中的消息

2 投票
1 回答
2780 浏览
提问于 2025-04-18 02:16

我在学习Python(2.7版本),现在有个任务要用lxml库来检查XML文档是否符合XSD模式(可以参考这个链接:http://lxml.de/)。我有两个文件,像这样:

$ cat 1.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<a>
  <b>Привет мир!</b>
</a>

还有一个:

$cat 2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="a" type="AType"/>
  <xs:complexType name="AType">
    <xs:sequence>
      <xs:element name="b" type="xs:decimal" />
   </xs:sequence>
  </xs:complexType>
</xs:schema>

这看起来应该很简单,但我不太明白如何用lxml处理utf-8编码(我之前从没接触过编码方面的内容)。我做了一些简单的步骤:

>>> from lxml import etree
>>> schema = etree.parse("/tmp/qwerty/2.xsd")
>>> xmlschema = etree.XMLSchema(schema)
>>> try:
    document = etree.parse("/tmp/qwerty/1.xml")
    print "Parse complete!"
except etree.XMLSyntaxError, e:
    print e

Parse complete!
>>> xmlschema.validate(document)
False
>>> xmlschema.error_log

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    xmlschema.error_log
  File "xmlerror.pxi", line 286, in lxml.etree._ListErrorLog.__repr__ (src/lxml/lxml.etree.c:33216)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 85-90: ordinal not in range(128)

但是我无法从.error_log中获取所有的异常信息。

有没有什么方法可以用编码/解码的方法来检查这个问题(成功地)?或者有没有解决方案(不使用其他库,我指的是标准的Python方法),或者我是否需要使用StringIO(但该怎么做呢)?

我明白我的问题与“Привет мир!”和xs:decimal有关——这些只是一些简短的例子。抱歉我的英语不好。谢谢你。

1 个回答

5

你需要用 utf-8 编码你的错误日志中的错误信息。可以试试下面的方法:

代码:

from lxml import etree

schema = etree.parse("2.xsd")
xmlschema = etree.XMLSchema(schema)

try:
    document = etree.parse("1.xml")
    print "Parse complete!"
except etree.XMLSyntaxError, e:
    print e

print xmlschema.validate(document)
for error in xmlschema.error_log:
    print "ERROR ON LINE %s: %s" % (error.line, error.message.encode("utf-8"))

结果:

Parse complete!
False
ERROR ON LINE 4: Element 'b': 'Привет мир!' is not a valid value of the atomic type 'xs:decimal'.
[Finished in 1.3s]

相关的文档可以在 这里 找到。

如果这对你有帮助,请告诉我们。

撰写回答