如何替换树中的元素? (ElementTree的/降价)

时间:2014-01-05 07:22:05

标签: python elementtree

如何在元素树中迭代期间替换元素?我正在为markdown编写一个树处理器,并希望包装一个元素。

<pre class='inner'>...</pre>

应该成为

<div class='wrapper'><pre class='inner'>...</pre></div>

我使用getiterator('pre')来查找元素,但我不知道如何包装它。问题点是用新的包装器替换找到的元素,但保留现有元素作为子包。

4 个答案:

答案 0 :(得分:5)

这有点棘手。首先,您需要按this previous question

中所述获取父元素
parent_map = dict((c, p) for p in tree.getiterator() for c in p)

如果您可以使用lxml进行降价,这会更容易一些 - 我相信lxml元素已经了解他们的父母。

现在,当您从迭代中获取元素时,您也可以获得父元素:

for elem in list(tree.getiterator('pre')):
    parent = parent_map[elem]
    wrap_elem(parent, elem)

请注意,我已经将树中的迭代器转换为列表 - 我们不希望在迭代它时修改树。那可能很麻烦。

最后,您可以移动元素:

def wrap_elem(parent, elem)
    parent_index = list(parent).index(elem)
    parent.remove(elem)
    new_elem = ET.Element('div', attrib={'class': 'wrapper'})
    parent.insert(parent_index, new_elem)
    new_elem.append(elem)

*请注意,我没有完全测试此代码...如果您发现任何错误,请告诉我。

答案 1 :(得分:1)

根据我的经验,您可以使用以下方法获得您想要的东西:
xml.etree.ElementTree.SubElement(我将其称为ET.Subelementhttp://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.SubElement

以下是步骤:
在迭代之前,您应首先获取这些迭代元素的父元素,将其存储到变量parent中。

然后,
1,将元素<pre class='inner'>...</pre>存储到变量temp

2,将新的子元素div添加到parent

div = ET.SubElement(parent, 'div')

并设置div

的属性
div.set('class','wrapper')

3,将步骤1中的元素添加为div

的子元素
ET.SubElement(div, temp)  

4,删除步骤1中的元素:

parent.remove(temp)

答案 2 :(得分:0)

另一个对我有用的解决方案,类似于lyfing。 将元素复制到temp中;使用想要的外部标记重新标记原始元素并清除它,然后将副本附加到原始标记中。

import copy

temp = copy.deepcopy(elem)
elem.tag = "div"
elem.set("class","wrapper")
elem.clear()
elem.append(temp)

答案 3 :(得分:0)

类似的东西适用于一个:

library(ggplot2)
df = data.frame(
x<-runif(10),
y<-runif(10)
)    

g = ggplot(df,aes(x=x,y=y))+geom_point()+theme_bw()
ggsave(g,file="Plot1.png")
g = g + geom_hline(yintercept=mean(y))
ggsave(g,file="Plot2.png")

类似的事情适用于许多人:

for i, element in enumerate(parent):
    if is_the_one_you_want_to_replace(element):
        parent.remove(element)
        parent.insert(i, new_element)
        break