XMLファイルをコピーする(1)


復習と勉強がてらにXMLファイルをコピーするという単純な処理を様々な言語でどのように実現できるかやってみました.

前提として、XMLファイルはコメントや処理命令を含まないごく単純なものとします.ネームスペースも使用しません.今回使ったのはBeginning XMLで使用しているサンプルで以下のようなものです.

[MusicLibrary.xml]
<?xml version="1.0" encoding="utf-8"?>
<musicLibrary>
  <cd id="1">
    <title>Parallel Lines</title>
    <year>2001</year>
    <artist>Blondie</artist>
    <genre>New Wave</genre>
  </cd>
  <cd id="2">
    <title>Bat Out of Hell</title>
    <year>2001</year>
    <artist>Meatloaf</artist>
    <genre>Rock</genre>
  </cd>
  <cd id="3">
    <title>Abbey Road</title>
    <year>1987</year>
    <artist>The Beatles</artist>
    <genre>Rock</genre>
  </cd>
  <cd id="4">
    <title>The Dark Side of the Moon</title>
    <year>1994</year>
    <artist>Pink Floyd</artist>
    <genre>Rock</genre>
  </cd>
  <cd id="5">
    <title>Thriller</title>
    <year>2001</year>
    <artist>Michael Jackson</artist>
    <genre>Pop</genre>
  </cd>
</musicLibrary>

※ なんとPink FloydのThe Dark Side of the Moonが入っています.なかなか作者の趣味を感じさせられます.

まず最初はXSLTです.ご存知のようにXSLTでは、以下のスタイルシートで簡単に入力XMLファイルを出力側にコピーできます.

[style.xsl]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"

<xsl:output method="xml" indent="no" encoding="UTF-8" byte-order-mark="no"  omit-xml-declaration="no"/>

<!-- すべての要素にマッチするテンプレート-->
<xsl:template match="*">
    <!--自分をコピーし-->
    <xsl:copy>
        <!--属性もコピーする-->
        <xsl:copy-of select="@*"/>
        <!--下位ノードを処理する-->
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

適切にCLASSPATHを設定して、次のコマンドラインを使ってSaxonを実行します.

java net.sf.saxon.Transform -t -xsl:style.xsl -o:MusicLibrary_out.xml -s:MusicLibrary.xml

すると次のようにXML宣言の箇所だけ改行の有無が違ったファイルが出力されます.

<?xml version="1.0" encoding="UTF-8"?><musicLibrary>

あとの部分はまったく同じです.

このスタイルシートは実に簡単ですが、ちゃんとXMLファイルのすべての要素、属性、テキストを全部なめて処理します.要素は<xsl:copy>でコピーされ、属性は<xsl:copy-of select="@*"/>でコピーされます.テキストノードはデフォルトテンプレートが適用され自動的に出力にコピーされます.たった一つのテンプレートにもかかわらずなかなか奥深いです.

しかしXSLTではたった一個のテンプレートでコピーできてしまうのですが、一般のプログラミング言語ではそう簡単ではありません.まずJavaでやってみたいと思います.