指定されたいくつかのタグの特定の文字列をXMLファイルのタグに含まれる他の文字列に置き換える方法

指定されたいくつかのタグの特定の文字列をXMLファイルのタグに含まれる他の文字列に置き換える方法

一部の指定タグの特定の文字列を、XMLファイルのタグに含まれる他の文字列に置き換える必要があります。

が表示されるすべての項目を検索し、タグ内(他のタグ内)がある場合にのみ、次のようにan example置き換える必要があります。<b>a test</b><a> ... </a>

  • 入力例:
    <c>This is an example. <a>This is an example;</a></c>
    
  • 希望の出力:
    <c>This is an example. <a>This is <b>a test;</b></a></c>
    

ベストアンサー1

あなたが望むようです

  1. XMLドキュメントのノード値an example;からテキストを削除し、/c/a
  2. /c/a名前付きノードにb値を持つ子ノードを追加しますa test;

xmlstarletシェルでこれを簡単に実行できます。

xmlstarlet ed -u '/c/a' -x 'substring-before(text(), "an example;")' file.xml |
xmlstarlet ed -s '/c/a' -t elem -n 'b' -v 'a test;'

xmlstarlet質問のサンプル文書への最初の呼び出しは、ノード/c/a値からいくつかのテキストを削除して出力を生成します。

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

2番目の呼び出しはこの修正された文書を取得し、ノードを導入して次のように生成します/c/a/b

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

これらのxmlstarlet呼び出しは単一のコマンドにまとめることができます。以下では--inplace、元の文書の内部編集にも長いオプションを使用しました(これは説明のためのものであるため、--inplace変換が機能していることを確認するには、まず実行せずに実行する必要があります)。

xmlstarlet ed --inplace \
    --update  '/c/a' -x 'substring-before(text(), "an example;")' \
    --subnode '/c/a' -t elem -n 'b' -v 'a test;' file.xml

上記の内容を一般化して、aテキストを含むノードで2つの編集を行いますan example;(質問で実際に必要なものです)。

xmlstarlet ed \
    --var paths '//a[contains(text(), "an example;")]'  \
    --update  '$paths' -x 'substring-before(text(), "an example;")' \
    --subnode '$paths' -t elem -n 'b' -v 'a test;' file.xml 

ここで唯一の新しいことは、編集したいすべてのノードのパスを最初に内部変数に保存することです$paths。次に--update、これらのパスを参照して変更します--subnode

おすすめ記事