我有以下有效的代码:
import xml.etree.ElementTree as etree
def get_path(self):
parent = ''
path = self.tag
sibs = self.parent.findall(self.tag)
if len(sibs) > 1:
path = path + '[%s]'%(sibs.index(self)+1)
current_node = self
while True:
parent = current_node.parent
if not parent:
break
ptag = parent.tag
path = ptag + '/' + path
current_node = parent
return path
etree._Element.get_path = get_path
etree._Element.parent = None
class XmlDoc(object):
def __init__(self):
self.root = etree.Element('root')
self.doc = etree.ElementTree(self.root)
def SubElement(self, parent, tag):
new_node = etree.SubElement(parent, tag)
new_node.parent = parent
return new_node
doc = XmlDoc()
a1 = doc.SubElement(doc.root, 'a')
a2 = doc.SubElement(doc.root, 'a')
b = doc.SubElement(a2, 'b')
print etree.tostring(doc.root), '\n'
print 'element:'.ljust(15), a1
print 'path:'.ljust(15), a1.get_path()
print 'parent:'.ljust(15), a1.parent, '\n'
print 'element:'.ljust(15), a2
print 'path:'.ljust(15), a2.get_path()
print 'parent:'.ljust(15), a2.parent, '\n'
print 'element:'.ljust(15), b
print 'path:'.ljust(15), b.get_path()
print 'parent:'.ljust(15), b.parent
这导致此输出:
<root><a /><a><b /></a></root>
element: <Element a at 87e3d6c>
path: root/a[1]
parent: <Element root at 87e3cec>
element: <Element a at 87e3fac>
path: root/a[2]
parent: <Element root at 87e3cec>
element: <Element b at 87e758c>
path: root/a/b
parent: <Element a at 87e3fac>
现在这与原始代码发生了巨大的变化,但我不允许分享它。
这些功能并不太低效,但是从 cElementTree 切换到 ElementTree 时性能会急剧下降,这是我所期望的,但从我的实验来看,猴子修补 cElementTree 似乎是不可能的,所以我不得不切换。
我需要知道的是是否有一种方法可以向 cElementTree 添加方法,或者是否有更有效的方法来执行此操作,以便我可以恢复一些性能。
只是为了让您知道,我正在考虑作为最后的手段来实现选定的静态类型并使用 cython 进行编译,但由于某些原因,我真的不想这样做。
谢谢参观。
编辑:很抱歉错误地使用了术语后期绑定。有时我的词汇量有待改进。我的意思是“猴子补丁”。
编辑:@Corley Brigman,Guy:非常感谢您的回答确实解决了这个问题,但是(我应该在原始帖子中说明这一点)我在使用 lxml 之前完成了这个项目,这是一个很棒的库,可以进行编码轻而易举,但由于新的要求(这需要作为名为 Splunk 的产品的插件来实现),这将我与 Splunk 附带的 python 2.7 解释器联系在一起,并消除了添加第三方库的可能性,但 django 除外。