XSLT基礎編: xsl:copyで元のXMLデータの要素や属性をコピーする

2005年03月27日(日)更新


XMLデータのノードのコピー

たけち: 今回は、xsl:copy要素を勉強しよう。

さらら: xsl:copy? 前回教えてもらったxsl:copy-ofとは違うの?

たけち: うん。xsl:copy-ofは、変換前のXMLデータの要素を、その子要素や属性を含めて、そのまま変換後のXMLデータやHTMLデータなどの要素として出力するんだったね。

さらら: えぇ。

たけち: xsl:copyは、カレントノードだけをコピーするんだよ。

さらら: あっ、そうなの。

たけち: じゃあまず、xsl:copyの書き方をみておこうね。そのあとで使い方を少し見てみるね。

さらら: はい。

xsl:copyの書き方
■xsl:copyの書き方


サンプルXMLデータ: flowers.xml

さらら: use-attribute-setsってなぁに。。。

たけち: えっとね。。。。今回は気にしないでおいて。あとできちんと学んでみたいからね。

さらら: うっ、うん。。。じゃあ、copyってどう使うのかしら?

たけち: そうだね。それじゃあ、簡単な例でxsl:copyの使い方をみてみようね。

さらら: うん。

たけち: 前回と同じフライトデータの例でやってみるね。

【flights.xml】

【flights.xml】 XMLファイル: フライトスケジュールのデータ

<?xml version="1.0" encoding="Shift_JIS"?>
<?xml-stylesheet type="text/xsl" href="flights.xsl"?>
<flights>

<route airline="BOB" from="羽田" to="出雲">

<table border="1" width="300">
<tr><th bgcolor="silver">便名</th>
<th bgcolor="silver">発時刻</th>
<th bgcolor="silver">着時刻</th></tr>
<tr><td>1271</td><td align="right">8:00</td><td align="right">9:30</td></tr>
<tr><td>1273</td><td align="right">10:25</td><td align="right">11:55</td></tr>
<tr><td>1275</td><td align="right">13:15</td><td align="right">14:45</td></tr>
<tr><td>1277</td><td align="right">16:55</td><td align="right">18:25</td></tr>
<tr><td>1279</td><td align="right">18:30</td><td align="right">20:00</td></tr>
</table>

</route>

</flights>


xsl:copyを使ったスタイルシート例

さらら: xsl:copy-ofでやつた例と同じXMLデータね。

たけち: うん。で、ここでは、xsl:copy-ofでやった結果と同じ表示をするXSLTスタイルシートを作ってみよう。それで、xsl:copy-ofxsl:copyの使い方の違いも分かるしね。

さらら: あっ、そうね。

たけち: じゃあ、さっそくスタイルシートを先に見てもらおうかな。

【flights.xslt】

【flights.xslt】 XSLTファイル: xsl:copy要素を含んでいます

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml">

<xsl:template match="/">
    <html>
    <head>
    <title>XSLスタイルシートサンプル xsl:copy</title>
    </head>

    <head><title>xsl:copy使用例: ソースXMLデータのtable要素をコピー</title></head>
    <body>
        <p>■xsl:copy使用例: ソースXMLデータのtable要素をコピー</p>

        <xsl:apply-templates />

        <p align="right">以上です。</p>
    </body>
    </html>
</xsl:template>

<xsl:template match="route">
    <p>【航空会社: <xsl:value-of select="@airline" /> 
        <xsl:value-of select="@from" />発、<xsl:value-of select="@to" />着】</p>
        <xsl:apply-templates />
</xsl:template>

<!-- table要素以下をコピー出力します。 -->

<xsl:template match="table | tr | th | td">
    <xsl:copy>

        <xsl:for-each select="@*">
            <xsl:copy />
        </xsl:for-each>

        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

さらら: xsl:copy要素でまるごとコピーしたときとは、ずいぶん違うわね。

たけち: そうだね。少し詳しく見てみようね。

さらら: はい。

たけち: コピーをしているのは次のテンプレート部分だね。

xsl:copy要素を使ってtable要素以下をコピーしているテンプレート部分

<xsl:template match="table | tr | th | td">
    <xsl:copy>

        <xsl:for-each select="@*">
            <xsl:copy />
        </xsl:for-each>

        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

たけち: table要素とそれ以下の要素ノードについては、<xsl:template match="table | tr | th | td"><xsl:apply-templates />とで選択しているよね。

さらら: はぁ〜。。。match="table | tr | th | td"って、tableか、trか、thか、td要素ノード、ってことなのよね。

たけち: そうそう。

さらら: なるほど。。。<xsl:apply-templates />が無いと、table要素がコピーされるだけなのね。

たけち: そうなんだね。

さらら: じゃあ。<xsl:for-each select="@*">から</xsl:for-each>では、何をしているの?

たけち: それぞれの要素ノードの属性ノードをコピーしているんだよ。

さらら: えっ?

たけち: あっ、ごめん。ちゃんと言ってなかったけど、xsl:copyではカレントノードだけをコピーするものだから、たとえば、要素ノードの場合、その属性ノードはコピーしないんだよ。

さらら: あっ、そうなんだ。。。

たけち: <xsl:for-each select="@*">で、カレントノードのすべての属性についてxsl:copyしているんだ。


flights.xmlをIEで表示する

さらら: スタイルシートの内容はだいたい分かったから、これでちゃんと表示できるか、やっぱり見てみたいわ。

たけち: そうだね。いつものようにXLSTファイルを適用して、IEて表示してみよう。

さらら: えぇ。

フライトデータのXMLファイル flights.xml(上記説明のXSL適用)

flights.xmlをIEで表示
■flights.xmlをIEで表示

さらら: なるほどね。だいたいの使い方がイメージできたけど。。。

たけち: う〜ん。そうだね。やっぱり、いくつかスタイルシートを作ってみないとね。じゃあ、今回はここまでね。

さらら: はい。ありがとう。

→さらに続きます。・・・ (^ ^;