Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 向lxml中的几个子元素添加相同的元素_Python_Lxml - Fatal编程技术网

Python 向lxml中的几个子元素添加相同的元素

Python 向lxml中的几个子元素添加相同的元素,python,lxml,Python,Lxml,背景:我试图用从web服务端点检索的元数据充实XML报告。报告列出了文本模块和图形,每个图形都有几个分辨率。我无法为每个解决方案添加元数据 问题:问题简化了 from lxml import etree as ET myxml = """\ <report> <object id="foo"> <reportitems> <reportitem id="1"/> <re

背景:我试图用从web服务端点检索的元数据充实XML报告。报告列出了文本模块和图形,每个图形都有几个分辨率。我无法为每个解决方案添加元数据

问题:问题简化了

from lxml import etree as ET

myxml = """\
<report>
    <object id="foo">
        <reportitems>
            <reportitem id="1"/>
            <reportitem id="2"/>
            <reportitem id="3"/>
        </reportitems>
    </object>
</report>
"""

report = ET.fromstring(myxml)
test = ET.Element("test", foo="bar")

for r in report.findall("object/reportitems/reportitem"):
    r.append(test)
…然后我得到这个输出:

<report>
    <object id="foo">
        <reportitems>
            <reportitem id="1"/>
            <reportitem id="2"/>
            <reportitem id="3"><test foo="bar"/></reportitem>
        </reportitems>
    </object>
</report>
<report>
    <object id="foo">
        <reportitems>
            <reportitem id="1"><test1/></reportitem>
            <reportitem id="2"><test2/></reportitem>
            <reportitem id="3"><test3/></reportitem>
        </reportitems>
    </object>
</report>
为什么我不能将与子元素相同的元素添加到我迭代的许多元素中?

构造函数ET中的问题。它的元素每次调用只创建一个节点。您可以更改节点的父节点,但ET.元素将仅为一个。您可以在循环中多次创建ET.元素以避免此问题:

for r in report.findall("object/reportitems/reportitem"):
    node = ET.Element("test", foo="bar")
    r.append(node)

此行为在以下章节中描述:

还有另一个重要的情况,即 2.0及更高版本中的lxml与列表和 版本1.3或Python 2.7/3.2之前的原始ElementTree:

在本例中,最后一个元素移动到不同的位置, 而不是被复制,即自动从其 放置在不同位置时的上一个位置。在列表中, 对象可以同时出现在多个位置,并且 上面的赋值只是将项目引用复制到第一个 位置,以便两者包含完全相同的项目:

请注意,在原始ElementTree中,单个元素对象可以位于任意数量树中的任意位置, 允许与列表相同的复制操作。显而易见的 缺点是对此类元素的修改将适用于所有 它出现在树上的地方,可能是有意的,也可能不是有意的。 这种差异的好处是lxml.etree中的元素总是 只有一个父级,可以通过getparent查询 方法这在原始ElementTree中不受支持

如果要将元素复制到LXML.ETRE中的不同位置,请考虑 使用Python的复制模块创建独立的深度复制 标准库:


预期产量是多少?目前,您没有传递相同的元素:test1!=我所期望的是能够将相同的元素作为子元素添加到id分别为1、2和3的每个元素中。我添加了修改后的脚本,它成功地添加了不同的子元素,作为一个重要的元素?对比。是的,但我想OP会问为什么?试图在文档或源代码中找到实际的解释。。
for r in report.findall("object/reportitems/reportitem"):
    node = ET.Element("test", foo="bar")
    r.append(node)
>>> for child in root:
...     print(child.tag)
child0 child1 child2 child3
>>> root[0] = root[-1]  # this moves the element in lxml.etree!
>>> for child in root:
...     print(child.tag)
child3 child1 child2
>>> l = [0, 1, 2, 3]
>>> l[0] = l[-1]
>>> l
[3, 1, 2, 3]
>>> root is root[0].getparent()  # lxml.etree only!
True
>>> from copy import deepcopy

>>> element = etree.Element("neu")
>>> element.append( deepcopy(root[1]) )

>>> print(element[0].tag)
child1
>>> print([ c.tag for c in root ])
['child3', 'child1', 'child2']