こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

XSLTの処理について

いつもお世話になっております。
XMLの動作についての質問です。以下のようなXMLファイルがあったとします。それに対して、その下のようなXSLファイルがあり、変換させると、結果XMLができます。
そこでわからないのは、test.xslの中ほどで、<xsl:template match="book/title/price">という風にXPath式でbook/title/priceと指定しているのに、結果には<title>の値も出力されます。なぜでしょうか。
自分のイメージとしては、<title>の値は出力されず<price>の値だけが出力されるのじゃないのかなっていう感じです。さらに<newTag>に<title>の値が挟まれていないのもなぜなのかわかりません。
お分かりになる方よろしくお願いします。もし参考文献に良いサイトや本がありましたらそちらも紹介をお願いします。

<<<test.xml>>>
<?xml version="1.0" encoding="Shift_JIS"?>
<books>
 <book>
  <title>
   XMLとは
   <price>2000</price>
  </title>
 </book>
 <book>
  <title>
   XML概論
   <price>1800</price>
  </title>
 </book>
 <book>
  <title>
   XMLマスター
   <price>4000</price>
  </title>
 </book>
</books>


<<<test.xsl>>>
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 <answer>
  <xsl:apply-templates select="books/book"/>
 </answer>
</xsl:template>

<xsl:template match="book/title/price">
 <newTag>
  <xsl:value-of select="."/>
 </newTag>
</xsl:template>
</xsl:stylesheet>


<<<結果.xml>>>
<?xml version="1.0" encoding="utf-8" ?>
<answer>
XMLとは
<newTag>2000</newTag>
XML概論
<newTag>1800</newTag>
XMLマスター
<newTag>4000</newTag>
</answer>

投稿日時 - 2008-04-16 17:20:18

QNo.3952529

すぐに回答ほしいです

質問者が選んだベストアンサー

うん。誤解しまくっているね。
まずは「ビルトインテンプレート」について学ぼう。

http://okwave.jp/qa3362718.html #2リンク先

apply-templatesでselectしているのは
複数のbook要素ノードからなるノードセットだね。

<xsl:apply-templates select="books/book"/>

最初のbook要素はprice要素じゃないから
以下のテンプレートにマッチしない
<xsl:template match="book/title/price">

よってビルトインテンプレートを適用する。

book要素の最初の子は(空白文字類からなる)テキストノード。これはそのまま。

次にtitle要素。だけどこれもprice要素じゃないからやっぱりテンプレートにマッチしない

よってtitle要素にもビルトインテンプレートを適用する

title要素の最初の子はテキストノードだからそのまま出力。
●XMLとは
title要素の次の要素はprice要素。ここでやっと,テンプレートにマッチするから適用していく。
テキストノード

newTag要素開始タグ
●<newTag>
テキストノード

と続いて・・・
xsl:value-of要素のselectはマッチしているprice要素を基準に考えられるからprice要素そのもの。

xsl:value-of要素が出力する内容は
http://www.w3.org/TR/xslt#value-of
に従いstring関数にオブジェクトを指定した(string-value)のと同じ内容の文字列。

http://www.w3.org/TR/xpath#function-string

http://www.w3.org/TR/xpath#element-nodes
Element Nodeのstring-valueはその要素の子のstring-valueを全てつなげたもの。

price要素の子はテキストノードだけで,それはそのテキストノードの文字列そのものである。
http://www.w3.org/TR/xpath#section-Text-Nodes
●2000

テキストノード

newTag終了タグ
●</newTag>
テキストノード

テンプレートおしまい。

次の要素はprice要素の次のノードだからテキストノード。

でtitle要素への適用終わり。
title要素の次はやっぱりテキストノード

book要素への適用終わり。

テンプレートをbooks要素の子の次(二番目の)のbook要素に適用する。
この前のテキストノードはselectしてないから当然選ばれない。
・・・・(以下略)

だから出力結果は正しいです。

======================
これがもし,
<xsl:apply-templates select="books/book"/>
ではなく
<xsl:apply-templates select="books/book/title/price"/>
だったら、出力結果は

<?xml version="1.0" encoding="utf-8"?>
<answer>
<newTag>2000</newTag>
<newTag>1800</newTag>
<newTag>4000</newTag>
</answer>

となります。

========================
ところで,多分サンプルの都合だと思うけど
普通はこういう構造にするよね・・・・
<?xml version="1.0" encoding="Shift_JIS"?>
<books>
<book>
<title>XMLとは</title>
<price>2000</price>
</book>
</books>


#よく調べてないけど改行とかは無視されるのかも。
xml:spaceとか使うのかなあ?

投稿日時 - 2008-04-16 18:43:58

補足

回答ありがとうございます。
現在ある試験用の本を読んで勉強しているのですが、おはずかしながら全く分かっていないですね(汗)最初のリンク先で紹介されているXML関連のサイトの方が詳しいような気がしたり・・・。この先が心配です。
でして、現在リンク先のサイトを見ていますので、ある程度見終わったら改めてお礼の方を書かさせていただきたいと思います。
もう少しお待ちください。

投稿日時 - 2008-04-16 21:49:31

お礼

回答ありがとうございました。
回答に書いてあることが理解できました。
この調子だとまたこちらで投稿させていただくことになりそうです。その時にはまたよろしくお願いします。(この先が不安だ・・・

投稿日時 - 2008-04-17 17:50:47

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問