6

次のxmlドキュメントがあります。

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

node2いつフィルターをかけたいのかa1="x2"。ユーザーは、テストおよびフィルターで除外する必要のあるxpathおよび属性値を提供します。私はBeautifulSoupのようなPythonのいくつかのソリューションを見ましたが、それらは複雑すぎてテキストの大文字小文字を保持していません。いくつかのものを除外して、以前と同じドキュメントを維持したいと思います。

シンプルで簡潔なソリューションをお勧めできますか?これは、見た目からはそれほど複雑であってはなりません。実際のxmlドキュメントは上記ほど単純ではありませんが、考え方は同じです。

4

1 に答える 1

7

これは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、標準ライブラリにはないが、より強力な構文を持つを使用します。

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要素がその子の1つであるかどうかを確認し、そうである場合は削除します。

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)
于 2010-05-19T23:13:55.407 に答える