lxml使用简单的自定义解析器引发TypeError

时间:2013-07-08 19:09:21

标签: python xml-parsing lxml

我编写了以下简单的解析器(在稍微复杂的程序中展示问题),它从DBLP xml database中的所有条目中提取标题。

from lxml import etree

class DBLPTarget(object):
    def __init__(self, outfile):
        self.inField = False
        self.outfile = outfile

    def start(self, tag, attrib):
        if tag == 'title':
            self.inField = True

    def end(self, tag):
        if self.inField and tag == 'title':
            self.inField = False            

    def data(self, data):
        if self.inField:
            self.outfile.write('%s\n' % data)

    def close(self):
        pass

outfile = open('dblp-selected.txt', 'w')
parser = etree.XMLParser(target = DBLPTarget(outfile), load_dtd=True)
infile = 'dblp.xml'
results = etree.parse(infile, parser)
outfile.close()

print("Done.")

在dblp.xml文件上运行此代码后,它会暂停一段时间(生成大约72K的内容),然后引发以下错误消息。

Traceback (most recent call last):
  File "C:/Users/je24621/Desktop/dblp-example2.py", line 30, in <module>
    results = etree.parse(infile, parser)
  File "lxml.etree.pyx", line 3197, in lxml.etree.parse (src\lxml\lxml.etree.c:65042)
  File "parser.pxi", line 1571, in lxml.etree._parseDocument (src\lxml\lxml.etree.c:93101)
  File "parser.pxi", line 1600, in lxml.etree._parseDocumentFromURL (src\lxml\lxml.etree.c:93388)
  File "parser.pxi", line 1500, in lxml.etree._parseDocFromFile (src\lxml\lxml.etree.c:92445)
  File "parser.pxi", line 1047, in lxml.etree._BaseParser._parseDocFromFile (src\lxml\lxml.etree.c:89329)
  File "parsertarget.pxi", line 160, in lxml.etree._TargetParserContext._handleParseResultDoc (src\lxml\lxml.etree.c:100233)
  File "parsertarget.pxi", line 154, in lxml.etree._TargetParserContext._handleParseResultDoc (src\lxml\lxml.etree.c:100143)
  File "lxml.etree.pyx", line 294, in lxml.etree._ExceptionContext._raise_if_stored (src\lxml\lxml.etree.c:9383)
TypeError: function takes exactly 5 arguments (1 given)

作为参考,我在Windows 7(不是选择)上使用Python 3.2.5和lxml 3.2.1进行此操作。我该如何修复/调试它?

2 个答案:

答案 0 :(得分:1)

我不知道你看到的实际问题是什么。我尝试使用lxml 3.2.1和Python 3.3.1以及今天的libxml2快照和Apple提供的2.7.8版本,在这两种情况下,由于DTD无效,它会立即失败。

只需移除load_dtd=True就可以完成所有工作,输出为3.8M。它显然无法正确理解DTD中指定的自定义元素和实体。您不依赖于这些元素,但实体是一个问题。例如,您可以获得替换字符,而不是将&auml;替换为ä

所以,似乎有四种方法可以解决这个问题:

  1. 弄清楚如何让lxml对您的DTD满意。
  2. 找到一个与破碎的DTD一起使用的其他解析器。
  3. 将DTD嵌入到XML文件中(如this example中所示)。
  4. 不要使用DTD,而是预先解析数据。由于您实际需要的唯一内容是自定义实体,因此您只需使用其定义替换每个实体即可。当然,你不会以这种方式得到验证......但是你无论如何都没有通过验证。

答案 1 :(得分:0)

对于任何感兴趣的人,这个问题都没有解决,只是看起来库中有一个错误。相反,我使用正则表达式手动解析xml。