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 中做到这一点。

顺便说一句,我确信有人会问为什么我不直接告诉它我想要包含 Cs 的 As。问题是,除了 B 或 C 之外,A 还可以包含 20 种左右的东西,所以我必须指定一个包含 C 或 D 或...或 Z 的 A。这需要更多的工作而不是指定一种人工智能不想要的。

问题删除包含特定元素的 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)]将选择A文档中不包含节点B作为子节点的所有节点。这些选定的节点将被删除。

该表达式也可以写为//A[not(child::B)]更明确一点。

相关内容