gpt4 book ai didi

python - 如何防止 lxml remove 方法删除两个元素之间的文本

转载 作者:数据小太阳 更新时间:2023-10-29 03:01:04 26 4
gpt4 key购买 nike

我正在使用 lxml 和 python 2.7 来解析 xml 文件。我需要在某个时候使用 remove 方法删除一个元素,但非常奇怪的是它也删除了它后面的一些文本。

输入的 xml 是:

<ce:para view="all">Web and grid services <ce:cross-refs refid="BIB10 BIB11">[10,11]</ce:cross-refs>, where they can provide rich service descriptions that can help in locating suitable services.</ce:para>

然后我需要将 cross-refs 元素扩展为多个 cross-ref 并使用单独的 refid。所以输出应该是这样的:

<ce:para view="all">Web and grid services <ce:cross-ref refid="BIB10">[10]</ce:cross-ref><ce:cross-ref refid="BIB11">[11]</ce:cross-ref>, where they can provide rich service descriptions that can help in locating suitable services.</ce:para>

这是带有一些缩写的 python 代码:

xpath = "//ce:cross-refs"
cross_refs = tree.xpath(xpath, namespaces={'ce': 'http://www.elsevier.com/xml/common/dtd'})
for c in cross_refs:
c_parent = c.getparent()
c_values = c.text.strip("[]")
...
ref_ids = c.attrib['refid'].strip().split()
i = 0
for r in ref_ids:
...
tag = et.QName(CE, 'cross-ref')
exploded_cross_refs = et.Element(tag, refid=r, nsmap=NS_MAP)
exploded_cross_refs.text = "[" + c_values[i] + "]"
c.addprevious(exploded_cross_refs)
i += 1
c_parent.remove(c)

获取cross-refs元素,扩展refid值和元素文本值,然后创建新的cross-ref元素并添加它们在原始 cross-refs 之前,最后我想删除旧的 cross-refs 元素,我的问题就在这里:当我删除这个元素时,结束标记之间的文本并且下一个元素也被删除,所以最终结果是这样的:

<ce:para view="all">Web and grid services <ce:cross-ref refid="BIB10">[10]</ce:cross-ref><ce:cross-ref refid="BIB11">[11]</ce:cross-ref></ce:para>

请注意,最后一个 cross-refpara 元素之间的文本已被删除!我该如何解决这个问题?

最佳答案

或者,特别是在需要删除某个父元素中不是所有元素的情况下,我们可以创建简单的方法,将尾部附加到前一个元素(如果有),或者附加它否则,在元素实际被删除之前到父文本:

def remove_preserve_tail(element):
if element.tail:
prev = element.getprevious()
parent = element.getparent()
if prev is not None:
prev.tail = (prev.tail or '') + element.tail
else:
parent.text = (parent.text or '') + element.tail
parent.remove(element)

演示:

>>> from lxml import etree
>>> raw = '''<root>
... foo
... <div></div>has tail and no prev
... <br/><div></div>has tail and prev
... <br/>
... <div>no tail, whitespaces only</div>
... </root>'''
...
>>> root = etree.fromstring(raw)
>>> divs = root.xpath("//div")
>>> for div in divs:
... remove_preserve_tail(div)
...
>>> print etree.tostring(root)
<root>
foo
has tail and no prev
<br/>has tail and prev
<br/>

</root>

关于python - 如何防止 lxml remove 方法删除两个元素之间的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37046511/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com