У меня есть следующий код, который работает:Есть ли лучший способ дать элементы Knowlege своих родителей и в xml.etree.ElementTree XPath
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, я думаю, но по определенным причинам я действительно не хочу этого делать.
Спасибо, что посмотрели.
EDIT: Извините за неправильное использование термина позднего связывания. Иногда мой словарь оставляет желать лучшего. Я имел в виду «обезглавливание обезьян».
EDIT: @Corley Brigman, Guy: Большое спасибо за ваши ответы, которые решают вопрос, однако (и я должен был указать это в исходном сообщении). Я завершил этот проект, прежде чем использовать lxml, который является замечательным библиотека, которая сделала кодирование легким, но из-за новых требований (это должно быть реализовано как аддон к продукту под названием Splunk), который связывает меня с интерпретатором python 2.7, поставляемым с Splunk, и исключает возможность добавления сторонних библиотек, за исключением Джанго.
Когда вы говорите, «позднее связывание», вы на самом деле со ссылкой на обезьяну -patching 'etree._Element' с помощью дополнительного метода? – user4815162342
@ user4815162342 Благодарим вас за исправление. Я задал вопрос, потому что ты прав. – iLoveTux
Хм, вам нужно что-то другое. Вы пытались просто вывести класс из cElementTree.Element/SubElement? Если вы вызываете 'etree.parse' и т. Д., То необходимо использовать патч для обезьян. Но если вы сами генерируете элементы, я бы подумал, что это будет просто. Если вы используете _se_, используя синтаксический анализ, вы можете получить лучшую производительность, разрешив cElementTree его синтаксический анализ, а затем создайте свое собственное параллельное дерево (используя его элементы) с новыми типами + добавленные узлы. Я не знаю, как это повлияло на это. –