给定一个lxml元素xml
,我通过调用c.getnext()
来迭代其所有子元素{text
和tail
集。在
让我用下面的例子来说明addnext()
和{
>>> import lxml.etree
>>> s = "<p>This is <b>bold</b> and this is italic text.</p>"
# Create a new lxml element.
>>> xml = lxml.etree.fromstring(s)
# Let's look at the element, its child, and all the texts and tails.
>>> lxml.etree.tostring(xml)
b'<p>This is <b>bold</b> and this is italic text.</p>'
>>> xml.text
'This is '
>>> xml.tail
>>> xml[0].text
'bold'
>>> xml[0].tail
' and this is italic text.'
到目前为止还不错,这正是我所期望的(关于lxml表示的更多信息,请参见here)。在
现在我想把单词“italic”包装成标记,就像“bold”被包装成<b>
标记一样。为此,我首先找到“italic”子字符串开始的索引:
然后创建一个新的lxml元素:
# Create a new element and inspect it.
>>> new_c = lxml.etree.fromstring("<i>italic</i>")
>>> new_c.text
'italic'
>>> new_c.tail
>>>
要将这个新元素正确地插入到xml树中,我必须将原始的xml[0].tail
字符串拆分为两个子字符串,并从中删除“italic”:
>>> new_c.tail = xml[0].tail[idx+len("italic"):]
>>> xml[0].tail = xml[0].tail[:idx]
现在一切都准备好了,把新元素插入到xml
元素中,这就是我现在困惑的地方。在给定的子元素new_c
之后插入新的子元素xml[0]
,结果不同,Element API没有给我任何新的信息:
# Adds the element as a following sibling directly after this element.
# Note that tail text is automatically discarded when adding at the root level.
>>> xml[0].addnext(new_c)
>>> lxml.etree.tostring(xml)
b'<p>This is <b>bold</b><i>italic</i> text. and this is </p>'
以及
# Inserts a subelement at the given position in this element
>>> xml.insert(1 + xml.index(xml[0]), new_c)
>>> lxml.etree.tostring(xml)
b'<p>This is <b>bold</b> and this is <i>italic</i> text.</p>'
这两个调用似乎处理tail
的方式不同(请参阅关于tail
的addnext()
的注释)。即使将注释考虑在内,文本也不会从<b>
中丢弃,而是附加到<i>
之后,根级别的处理方式也不会与下一级有任何不同(即,可以通过将s
中的原始XML包装到另一个<foo>
标记中观察到完全相同的行为)。在
我错过了什么?在
编辑关于lxml邮件列表的相关讨论是here。在
tail
只存在于lxml
的级别上;在libxml2
中,它是一个文本节点,就像它在DOM中一样。主要原因是解析格式良好的XML(http://lxml.de/tutorial.html#elements-contain-text)时的便利性:{afs>努力从源代码维护所有抽象的函数。E、 g.
index()
只统计元素/注释/entityrefs/PI节点,而树操作例程似乎总是会移动节点的尾部。但是,由于这个概念它的应用似乎有不一致之处。这看起来像是一个错误(如果一致性是一个目标的话也是一个bug)。我将与维护人员讨论最后一条语句,以澄清库关于tails的预期行为。在
elem.addnext(nextelem)
在XML级别进行操作,即直接在元素之后添加内容,将任何尾部文本移到新插入的元素后面。这样做是为了使新元素成为一个直接跟在后面的同级元素。在parent.insert(where,elem)
的工作方式与父元素只是etree.Element
的列表一样。它将新元素放入列表中,而不会对etree.元素实例。parent.append(elem)
也可以这样工作,或者任何其他的列表操作。在因此,这些函数在元素树上有两个不同的视图。在
尾部从b元素移动到c元素,以保持除了插入元素之外的XML文档不变。在
现在,如果插入的元素已经有尾部,addnext用于插入元素及其后面的文本。直接在XML元素之后,而不是在带有tail的etree元素之后。在
^{pr2}$相关问题 更多 >
编程相关推荐