Text-Processing

如何在 XML 文件中取消標記嵌入在指定標記中的標記字元鏈

  • May 7, 2022

在 XML 文件中取消標記嵌入在指定標記中的標記字元鏈的 xmlstarlet 命令是什麼?

範例:搜尋每個出現的 tag <b>,只有在 tag 內才需要刪除<c> ... </c>

  • 輸入範例:
<c>This is <b>an example</b>. <a>This is <b>a test;</b></a></c>
  • 期望的輸出:
<c>This is an example. <a>This is <b>a test;</b></a></c>

為了概括起見,我保留範例中的第二句話,即

<a>This is <b>a test;</b></a>

但如果這是一個問題,則可以忽略。

這可以通過--update將節點的值複製//c/b到其父節點中--delete來完成,然後刪除現在不需要的b節點。

這類似於我在之前對您的問題的一個答案中採用的方法,在該方法中,我首先創建了一個內部xmlstarlet變數,該變數包含我們需要處理的所有節點的集合,然後再處理這些節點。我們這樣做是為了更輕鬆地訪問同一組節點以進行更新和刪除操作。在上一個答案中,這是neccesary,但在這裡它只是為了便於閱讀。

xmlstarlet ed \
   --var 'path' '//c/b' \
   --update '$path/../text()[1]' --expr 'concat(., $path/text())' \
   --delete '$path' file.xml

這裡值得注意的是,更新的目標不是b節點的父節點,而是父節點的第一個文本值, text()[1]。範例文件中節點父節點的第一個文本值//c/b是字元串This is 。第二文本值.b節點之後。如果我們最後選擇沒有[1],我們最終會得到

<?xml version="1.0"?>
<c>This is an example. an example<a>This is <b>a test;</b></a></c>

也就是說,該字元串an example將被插入到c節點的兩個文本值之後。

現在,相反,我們得到

<?xml version="1.0"?>
<c>This is an example. <a>This is <b>a test;</b></a></c>

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