xml_grep は、要素を含む要素を除外します。

xml_grep は、要素を含む要素を除外します。

他の要素を含むXMLファイルからすべての要素を削除しようとしています。これは私がやろうとしている作業の非常に単純化されたバージョンです。 XMLファイルがあるとしましょう。

<RootEl>
   <A>
      <B/>
   </A>
   <A>
      <C/>
   </A>
 </RootEl>

Bを含むAのみを保持するには、次のコマンドラインを使用できます。

xml_grep -root A -cond B < TheFile.xml

しかし、逆にBを含まないAだけを維持したい場合は、パニックになります。上記のようなコマンドです。

xml_grep -root A -exclude B < TheFile.xml

私にください

<RootEl>
   <A>

   </A>
   <A>
      <C/>
   </A>
 </RootEl>

そして私が望むもの

<RootEl>
   <A>
      <C/>
   </A>
 </RootEl>

私が使用すると、同じ不要な答えが得られます。

xml_grep -root A -exclude A/B < TheFile.xml

または

xml_grep -exclude A/B < TheFile.xml

Pythonでこれを行う方法を見つけることができ、xsltでも可能だと思います。しかし、xml_grepでこれを行う方法があればと思います。

ちなみに、なぜ私はCを含めることを望んでいると言わないのか、誰かが尋ねると確信しています。問題は、AがBまたはCに加えて20個程度を含む可能性があるため、C、D、または...またはZを含むAを指定する必要があることです。これには、望ましくないAIを指定するよりも多くの作業が必要です。

質問特定の要素を含むXMLノードの削除基本的には同じ質問をしますが、答えなしでxml_grepを使用します。 xml_grepがかなり人気があり、このような目的で作られているようですので、誰かがこのような答えを出すことができることを願っています。

答え1

使用xmlstarlet:

$ xmlstarlet ed -d '//A[not(B)]' file.xml
<?xml version="1.0"?>
<RootEl>
  <A>
    <B/>
  </A>
</RootEl>

XPATH式は、子ノードとして含まれていない文書のすべてのノードを//A[not(B)]選択します。選択したノードが削除されます。AB

//A[not(child::B)]この表現はより明示的に書くこともできます。

関連情報