我正在尝试在大型XML文档(约2000行)的子节点的特定子节点处插入元素,这是我的代码:
import xml.etree.cElementTree as ET
class Kapow_commands:
tree = ET.parse('location/of/xml/file')
root = tree.getroot()
seq_id = 39
def __init__(self):
pass
def append(self, block):
node_num=0
for node in Kapow_commands.root[13][1]:
node_num=node_num+1
if node.get('class') == 'End':
node.attrib['id'] = str(Kapow_commands.seq_id + 1)
print(node.attrib)
print(node_num)
Kapow_commands.root[13][1].insert(node_num -1, block)
block = ET.Element("test")
Kapow_commands().append(block)
此代码在特定节点上扫描XML文件以查找class ='End',然后在该元素id上加1并在其前面插入另一个元素。但是,当我运行此命令时,似乎会创建一个无限循环,因为它不会停止在此位置插入元素。有谁知道为什么会这样?或关于如何在所需位置正确插入此元素的任何想法?
答案 0 :(得分:0)
我有一个类似的问题。
解决方案是将要添加的元素初始化到循环中。
因此,在您的情况下,我将传递一个名称作为参数,并使代码如下所示:
def append(self, blockName): # here comes the name
node_num=0
for node in Kapow_commands.root[13][1]:
block = ET.Element(name) # and there goes the init
node_num=node_num+1
if node.get('class') == 'End':
node.attrib['id'] = str(Kapow_commands.seq_id + 1)
print(node.attrib)
print(node_num)
Kapow_commands.root[13][1].insert(node_num -1, block)
对于我来说,它成功了。不幸的是,我不知道这种魔术背后的原因。
答案 1 :(得分:0)
修复
如您的注释中所述,在插入新元素之后插入break
语句可解决无限循环的问题。
代码为什么会产生无限循环
至于为什么我们得到一个无限循环,我们需要了解当我们在python中调用for循环时会发生什么。从docs中我们看到一个for循环在您的可迭代对象(在本例中为Kapow_commands.root[13][1]
)上创建了一个迭代器,该迭代器在我们中断它,序列为空或迭代器引发时终止StopIteration异常。实际上,如果我们扩展for node in Kapow_commands.root[13][1]:
,我们将得到类似
iterator = iter(Kapow_commands.root[13][1])
while True:
try:
node = iterator.__next__()
# Body of for loop
except StopIteration:
break
神奇的地方就在这里。让我们用“ End” End Node
类来调用该节点。如果当前节点为End Node
,则执行Kapow_commands.root[13][1].insert(node_num -1, block)
。这会将block
插入到可迭代对象的当前位置中,这意味着可迭代对象中的下一项再次变为End Node
。在for循环的下一次迭代中,iterator.__next__()
给我们End Node
,我们回到了开始的地方,产生了无限循环。