我是堆叠溢出的新手,所以对任何人都“嗨”,我希望有人可以帮我解决我的问题......
最近我开始玩lxml.objectify并且偶然发现以下行为,我发现这很奇怪。 如果我只是创建一个像这样的小xml字符串:
from lxml import objectify
objroot = objectify.fromstring("<root>somerootvalue<child1/><child2/><child3/><child4><subchild1/><subchild2/></child4><child5><subchild1/><subchild2/></child5></root>")
objroot.child4 = True
objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
输出只是:Foo Bar true
如果我更改元素的值/文本,则按:
from lxml import objectify
objroot = objectify.fromstring("<root>somerootvalue<child1/><child2/><child3/><child4><subchild1/><subchild2/></child4><child5><subchild1/><subchild2/></child5></root>")
objroot.child4 = True
objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
objroot.child4 = False
objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
输出符合预期: Foo Bar真的, Foo Baz假
但是,如果我只是更改objroot.child4的值并调用print语句,我收到以下错误:
from lxml import objectify
objroot = objectify.fromstring("<root>somerootvalue<child1/><child2/><child3/><child4><subchild1/><subchild2/></child4><child5><subchild1/><subchild2/></child5></root>")
objroot.child4 = True
objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
objroot.child4 = False
objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
objroot.child4 = True
print(objroot.child4.subchild1,objroot.child4.subchild2,objroot.child4)
File "src\lxml\lxml.objectify.pyx", line 450, in lxml.objectify._lookupChildOrRaise (src\lxml\lxml.objectify.c:6586)
AttributeError: no such child: subchild1
虽然我希望最后一个输出是“Foo Bar true”,但我得到了“没有这样的孩子错误”。 所以看来child4后面的树的剩余部分已被切断了?这是一个理想的行为,如果是的话,我怎样才能更改树中间元素的文本而不删除其余部分?
感谢您的帮助!
答案 0 :(得分:1)
一旦我们深入挖掘它,实际上并没有那种奇怪的行为。使用grep -Ff file1 file2
的效果并不像您可能认为的那样。我们可以使用root.element.subelement....
打印出xml树的状态并检查结构。
etree
这看起来是正确的。那么当我们打电话给from lxml import objectify, etree
objroot = objectify.fromstring("<root>somerootvalue<child1/><child2/><child3/><child4><subchild1/><subchild2/></child4><child5><subchild1/><subchild2/></child5></root>")
print(etree.tostring(objroot, pretty_print=True)
#output:
<root>somerootvalue
<child1/>
<child2/>
<child3/>
<child4><subchild1/><subchild2/></child4>
<child5><subchild1/><subchild2/></child5>
</root>
时会发生什么? API允许您执行此操作,但它不仅仅是添加文本。相反,它用文本替换objroot.child4 = True
下的所有内容。因此子元素被删除。我们可以使用:
child4
因此,它已将objroot.child4 = True
print(etree.tostring(objroot, pretty_print=True)
#output:
<root>somerootvalue
<child1/>
<child2/>
<child3/>
<child4 xmlns:py="..." py:pytype="bool">true</child4>
<child5><subchild1/><subchild2/></child5>
</root>
的值设置为child4
,但它已删除了子元素。之后,当您使用以下设置子元素的值时:
True
它实际上在objroot.child4.subchild1 = "Foo"
objroot.child4.subchild2 = "Bar"
下创建每个子元素,然后动态设置值。