Xml

xml_grep 排除包含元素的元素

  • February 17, 2019

我正在嘗試從包含某個其他元素的 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。這需要更多的工作而不是指定一種 AI 不想要的。

刪除包含特定元素的 XML 節點的問題基本上提出了相同的問題,但使用 xml_grep 沒有答案。我希望有人可以提出這樣的答案,因為 xml_grep 似乎相當受歡迎並且是為這樣的目的而建構的……幾乎。

使用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)]更明確的形式。

引用自:https://unix.stackexchange.com/questions/495214