用python过滤xml

2024-05-08 07:28:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下xml文档:

<node0>
    <node1>
      <node2 a1="x1"> ... </node2>
      <node2 a1="x2"> ... </node2>
      <node2 a1="x1"> ... </node2>
    </node1>
</node0>

我想在a1="x2"时过滤掉node2。用户提供需要测试和筛选的xpath和属性值。我在python中查看了一些类似于BeautifulSoup的解决方案,但是它们太复杂了,不能保留文本的大小写。我想把文件和以前一样,过滤掉一些东西。

你能推荐一个简单明了的解决方案吗?从外表上看,这不应该太复杂。实际的xml文档并不像上面那么简单,但其思想是相同的。


Tags: 文件用户文档文本属性a1xml解决方案
1条回答
网友
1楼 · 发布于 2024-05-08 07:28:04

它使用标准库中的xml.etree.ElementTree

import xml.etree.ElementTree as xee
data='''\
<node1>
  <node2 a1="x1"> ... </node2>
  <node2 a1="x2"> ... </node2>
  <node2 a1="x1"> ... </node2>
</node1>
'''
doc=xee.fromstring(data)

for tag in doc.findall('node2'):
    if tag.attrib['a1']=='x2':
        doc.remove(tag)
print(xee.tostring(doc))
# <node1>
#   <node2 a1="x1"> ... </node2>
#   <node2 a1="x1"> ... </node2>
# </node1>

它使用lxml,它不在标准库中,但具有a more powerful syntax

import lxml.etree
data='''\
<node1>
  <node2 a1="x1"> ... </node2>
  <node2 a1="x2"> ... </node2>
  <node2 a1="x1"> ... </node2>
</node1>
'''
doc = lxml.etree.XML(data)
e=doc.find('node2/[@a1="x2"]')
doc.remove(e)
print(lxml.etree.tostring(doc))

# <node1>
#   <node2 a1="x1"> ... </node2>
#   <node2 a1="x1"> ... </node2>
# </node1>

编辑:如果node2更深入地隐藏在xml中,则可以遍历所有标记,检查每个父标记,查看node2元素是否是其子元素之一,如果是,则删除它:

仅使用xml.etree.ElementTree:

doc=xee.fromstring(data)
for parent in doc.getiterator():
    for child in parent.findall('node2'):
        if child.attrib['a1']=='x2':
            parent.remove(child)

使用lxml:

doc = lxml.etree.XML(data)
for parent in doc.iter('*'):
    child=parent.find('node2/[@a1="x2"]')
    if child is not None:
        parent.remove(child)

相关问题 更多 >