感谢alecxe,我找到了解决方案。如果我们有多个item1-item5元素的实例(请参阅我对他的答案的评论以便更好地理解),他的回答对于所描述的案例完全适用,但不起作用(即使是他的更新)。
无论如何,我发现了另一种解决方案(我认为这是更简单,更符合Python):
from lxml.etree import fromstring, tostring
data = """<FirstLevel>
<item1>Val1</item1>
<item2>Val2</item2>
<item3>Val3</item3>
<item4>Val4</item4>
<item5>Val5</item5>
<item1>Val1</item1>
<item2>Val2</item2>
<item3>Val3</item3>
<item4>Val4</item4>
<item5>Val5</item5>
</FirstLevel>
"""
tree = fromstring(data)
item1_list = tree.findall("item1")
for item1 in item1_list:
next_node = item1.getnext()
while next_node.tag != "item5":
tree.remove(next_node)
next_node = item1.getnext()
print(tostring(tree))
还有一个从alecxe评论这对我的作品来了一个解决方案:
从lxml.etree import fromstring,tostring
data = """<FirstLevel>
<item1>Val1</item1>
<item2>Val2</item2>
<item3>Val3</item3>
<item4>Val4</item4>
<item5>Val5</item5>
<item1>Val1</item1>
<item2>Val2</item2>
<item3>Val3</item3>
<item4>Val4</item4>
<item5>Val5</item5>
<item1>Val1</item1>
<item2>Val2</item2>
<item3>Val3</item3>
<item4>Val4</item4>
<item5>Val5</item5>
</FirstLevel>
"""
tree = fromstring(data)
node_start = "item1"
node_end = "item5"
parent = tree.xpath("//FirstLevel")[0]
# Remove first section
for node in parent.xpath("*[(preceding-sibling::item1)[1] and (following-sibling::item5)[3]]"):
parent.remove(node)
# Remove second section
for node in parent.xpath("*[(preceding-sibling::item1)[2] and (following-sibling::item5)[2]]"):
parent.remove(node)
# Remove last section
for node in parent.xpath("*[(preceding-sibling::item1)[3] and (following-sibling::item5)[last()]]"):
parent.remove(node)
print(tostring(tree))
我找到了正确的索引来把我n preceding-
和following-sibling
通过尝试多个值,但仍然没有真正得到它的逻辑,但它至少对我有效。
在Python中,读取文件通常要容易得多,删除所需的部分然后重写文件。它可能与您使用的模块idk不同。 –
感谢您的快速回答。在我的情况下,访问该文件很困难,因为它在更大的用例中存在,但是如果我找不到其他解决方案,我会考虑它:) – filaton