Python 在lxml树上迭代时向节点添加深度
我想为每个节点添加一个深度,为此我提出了以下递归函数:Python 在lxml树上迭代时向节点添加深度,python,recursion,tree,lxml,Python,Recursion,Tree,Lxml,我想为每个节点添加一个深度,为此我提出了以下递归函数: import lxml.html def add_depth(node, depth = 0): node.depth = depth print(node.tag, node.depth) for n in node.iterchildren(): add_depth(n , depth + 1) html = """<html> <body>
import lxml.html
def add_depth(node, depth = 0):
node.depth = depth
print(node.tag, node.depth)
for n in node.iterchildren():
add_depth(n , depth + 1)
html = """<html>
<body>
<div>
<a></a>
<h1></h1>
</div>
</body>
</html>"""
tree = lxml.html.fromstring(html)
add_depth(tree)
for x in tree.iter():
print(x)
if not hasattr(x, 'depth'):
print('this should not happen', x)
突然,它确实起作用了。这段代码创建了一个巨大的列表,列出了所有元素及其旁边的深度(因此我可以对其进行排序)。即使在对原始树进行迭代时,这一次它们也有深度。但这一点效率都不高,我也不明白
@Maximoo
tree.depth = 0
for x in tree.iter():
if x.getparent() is not None:
x.depth = x.getparent().depth + 1
AttributeError: 'HtmlElement' object has no attribute 'depth'
这里有几个问题
- 首先,您试图使递归函数具有 更新原始树的副作用。我不认为这是错误的 可能
- 第二,您不想使用Python属性,您需要
使用使用
访问的xml属性x.attrib
tree.attrib['depth'] = '0'
for x in tree.iter():
if 'depth' not in x.attrib:
x.attrib['depth'] = str(int(x.getparent().attrib['depth']) + 1)
print(lxml.html.tostring(tree).decode())
<html depth="0">
<body depth="1">
<div depth="2">
<a depth="3"></a>
<h1 depth="3"></h1>
</div>
</body>
</html>
tree.attrib['depth']=“0”
对于树中的x.iter():
如果x.attrib中没有“深度”:
x、 attrib['depth']=str(int(x.getparent().attrib['depth'])+1)
打印(lxml.html.tostring(tree.decode())
好吧,我已经看到了attrib
(并且还看到它需要是一个字符串,而不是整数),但是我不想实际编辑“html”键values.Oh。如果您只想让节点具有Python属性,可以将代码更改为justx.depth
试试。。。那是不起作用的东西!看看问题中的maxymoo注释部分。我认为设置node.depth
不起作用的原因是树在某些其他数据结构中保存DOM,并且只在迭代时生成节点元素的副本。因此,修改节点
不会修改树
本身。
tree.attrib['depth'] = '0'
for x in tree.iter():
if 'depth' not in x.attrib:
x.attrib['depth'] = str(int(x.getparent().attrib['depth']) + 1)
print(lxml.html.tostring(tree).decode())
<html depth="0">
<body depth="1">
<div depth="2">
<a depth="3"></a>
<h1 depth="3"></h1>
</div>
</body>
</html>