複数のファイルがあるheredoc内の変数

複数のファイルがあるheredoc内の変数

XMLコンテンツを含むHeredocがあり、次のような他のファイルのコンテンツを追加しました。

bar文書:

<bar>
  $baz
</bar>

スクリプト:

bar=$(cat bar.xml)

# this would be the ideal, of course it doesn't work
baz=$(cat baz.xml)
#

cat << EOF > out.xml
<foo>
  $bar
</foo>
EOF

出力out.xml

<foo>
  <bar>
    $baz
  </bar>
</foo>

次に、次に3番目のファイルを追加したいと思いますbar

baz文書:

<baz>baz<baz>

だから最終的な内容out.xmlは次のようになります。

<foo>
  <bar>
    <baz>baz</baz>
  </bar>
</foo>

このワークフローでは、(大きな)xmlファイルをそれぞれ独自のコンポーネントを持つコンポーネントに分割できると想定しています。

master (heredoc) xml
  ^^^
  second xml
    ^^^
    third xml

できるだけ簡単にしたいので、どこから始めるべきかわかりません。助けてくれてありがとう。

ベストアンサー1

XML文書を結合する慣用的な方法は、以下を使用することです。XSLT。まず、いくつかの設定は次のとおりです。

$ cd "$(mktemp --directory)"
$ echo '<foo/>' > ./foo.xml
$ echo '<bar/>' > ./bar.xml
$ echo '<baz/>' > ./baz.xml

次に、ファイルの内容をソースファイルの要素に挿入し、ファイルの残りの部分をそのままコピーするXSLTファイルを作成します。

$ cat > ./insert.xslt <<'EOF'
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
>     <xsl:template match="@* | node()">
>         <xsl:copy>
>             <xsl:apply-templates select="@* | node()"/>
>             <xsl:if test="name() = $element">
>                 <xsl:copy-of select="document($file)"/>
>             </xsl:if>
>         </xsl:copy>
>     </xsl:template>
> </xsl:stylesheet>
> EOF

これで、どのファイルでも別のファイルに挿入できます。

$ xsltproc --output ./bar-insert.xml --stringparam file ./baz.xml --stringparam element bar ./insert.xslt ./bar.xml
$ cat ./bar-insert.xml
<?xml version="1.0"?>
<bar><baz/></bar>

繰り返して最終ファイルを生成しましょう。

$ xsltproc --output ./foo-insert.xml --stringparam file ./bar-insert.xml --stringparam element foo ./insert.xslt ./foo.xml
$ cat ./foo-insert.xml
<?xml version="1.0"?>
<foo><bar><baz/></bar></foo>

これの利点は、インデント、空の要素の縮小など、すべてのXMLファイルを処理できることです。


複数回参照される場合は、ファイルを複数回挿入することもできます。たとえば、people.xmlが与えられた場合:

<people>
    <managers>
        <name>Jane Doe</name>
        <reports>
            <insert/>
        </reports>
    </managers>
    <interns>
        <insert/>
    </interns>
</people>

とinsert.xml:

<name>Abe Lincoln</name>

これで、次の2つの場所にinsert.xmlを簡単に配置できます。

$ xsltproc --stringparam file ./insert.xml --stringparam element insert ./insert.xslt ./people.xml 
<?xml version="1.0"?>
<people>
    <managers>
        <name>Jane Doe</name>
        <reports>
            <insert><name>Abe Lincoln</name></insert>
        </reports>
    </managers>
    <interns>
        <insert><name>Abe Lincoln</name></insert>
    </interns>
</people>

おすすめ記事