XML ファイルの階層内での検索と置換

XML ファイルの階層内での検索と置換

ディレクトリ全体に約350個のXMLファイルがあります/abc。alt属性の値が「何とか何とか':

<image alt="blah blah" src="../webcontent/filename.png">
    <caption>
        Figure 1.1: Typical Components of Blah Blah
    </caption>
</image>

属性の値を(改行を削除して)altで囲まれた内容に置き換えます。caption

<image alt="Figure 1.1: Typical Components of Blah Blah" src="../webcontent/filename.png">
    <caption>
        Figure 1.1: Typical Components of Blah Blah
    </caption>
</image>

Ubuntu または Windows でスクリプトを実行したり、任意のテキスト編集ツールを使用したりしても構いません。

改行とインデントが一貫していると想定するのは安全ではありません。また、すべての画像にキャプションがあるわけではありません。パス内のすべての XML ドキュメントは整形式です。

この置換をインプレースでスクリプト化する簡単な方法はありますか? 単一のファイルで機能するものであれば、再帰的に実行するように拡張できます。

答え1

単一のファイルの場合、次の XSLT スタイルシートで十分です。

<t:transform version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform">
  <t:template match="node()|@*">
    <t:copy>
      <t:apply-templates select="node()|@*"/>
    </t:copy>
  </t:template>
  <t:template match="image/@alt[. = 'blah blah']">
    <t:attribute name="alt" select="normalize-space(../caption)"/>
  </t:template>
</t:transform>

複数のファイルを処理するには、シェルスクリプト、Antスクリプトなどからスタイルシートを複数回呼び出すことができます(またはxmlshを参照)。または、SaxonなどのXSLT 2.0プロセッサを使用している場合は、collection()関数を使用してXSLT自体でスクリプト化できます。

答え2

以下も使用できますxmlstarlet:

xmlstarlet ed -u '//image/@alt[.= "blah blah"]' -x "normalize-space(../caption/text())"

関連情報