使用自定义元素类在Python中解析xml

问题描述:

我想使用Python的xml.etree.ElementTree模块解析xml文档。但是,我希望生成的树对象中的所有元素都具有一些我定义的类方法。这表明创建了我自己的Python的元素类的子类,但是我在解析时使用我自己的元素子类而不是内置的类时遇到了问题。使用自定义元素类在Python中解析xml

例如,假设我希望树中的节点有一个名为custommethod()的新方法。要做到这一点,我创建一个元素的子类:

class MyElement(xml.etree.ElementTree._Element): 

    def custommethod(): 
     . . . 

现在,当我分析使用

tree = xml.etree.ElementTree.parse(source) 

我想在树中的所有元素有custommethod()方法的树。所以,

tree.getroot.custommethod() 

不应该失败。

但我不知道如何告诉解析器使用我的元素类 - 这甚至可能吗? Python文档中有一些关于将自定义分析器传递给.parse()的提示,但不是很多细节。

“潜入Python”一书对此主题有相当广泛的报道。本章在线。靠近底部的是steps explained to create a custom XML parser。不知道它是否能让你获得所需的信息,但也许这是一个很好的起点。

+1

感谢您的提示,我不知道这本书是免费提供的。 – user592838

+0

该链接似乎已经死亡。 – gerrit

+0

@gerrit,谢谢,我更新了链接,猜测它被移动了。请注意,整本书是免费提供的,并且有更多关于XML的章节。 – Abel

自定义XML解析器是定义的xml.etree.ElementTree.XMLParser具有四个功能的子类:

  1. start(self, tag, attrs)时调用的开口标签被发现。
  2. end(self, tag)找到结束标记时调用。
  3. data(self, data)找到数据时调用。
  4. close(self)在解析结束时调用。

您必须管理其他事物一样,如何创建节点的情况下,每个标签的深度等 注意,data(self, data)方法没有标签的说法。

+0

人们如何去做“管理其他”部分?我无法在SO或Python文档中找到任何相关文档,也没有找到相关的大量使用Google搜索的文档。我不期望整个教程或任何东西,但一些提示,或链接到文件或什么...? –

简单的自定义方法添加到_Element

>>> def customMethod(self): 
    print("Done!") 

>>> e._Element.customMethod=customMethod 
+0

这几乎工作。我想要做的事情之一是更改元素的标签,这意味着在函数中执行self.tag =“其他”。如果我这样做,我可以调用函数作为_Element的方法,但它只打印(“完成!”)而不更改标记。 – user592838

+0

分析树后分配一个新的自定义方法让我看,我发现这,这几乎是正确的事情:http://*.com/questions/962962/python-changing-methods-and-attributes-at-运行 – user592838

在创建TreeBuilder实例,这样您可以指定要使用的元素类:

from xml.etree import cElementTree as etree 

class MyCustomElement(etree.Element): 
    pass 

tb = etree.TreeBuilder(element_factory=MyCustomElement) 

编号:https://github.com/python/cpython/blob/master/Lib/xml/etree/ElementTree.py#L1370

Python3,Element类的猴子修补程序无法正常工作。我怀疑这是由于三个原因:

  1. 重写__class__/__dict等的内置类不起作用。
  2. ElementTree使用C做繁重工作。
  3. 用于解析的类是一个类实例化的Web。

解决方案:创建您自己的解析函数!上述

import xml.etree.ElementTree 
def parse(source): 
    """Parse wrapper to build a tree with the extended Node class""" 
    treebuilder = xml.etree.ElementTree.TreeBuilder(element_factory=MyElement) 
    parser = xml.etree.ElementTree.XMLParser(target=treebuilder) 
    tree = xml.etree.ElementTree.parse(source, parser) 
    return tree 

的示例使用您的MyElement类,而不是ElementTree.Element为树的每一个对象。