いちばん失敗した人決定戦

XML初心者のものです。

要素の中に要素を生成するXSLを作ったのですが、
生成されません。

XMLは
- <item no="1">
<title>プログラムの基礎</title>
<creator>Heinemeier Hansson</creator>
<publisher>オーム社</publisher>
- <keywords>
<keyword>プログラミング</keyword>
<keyword>ソフトウェア</keyword>
<keyword>入門</keyword>
</keywords>
</item>

となっており、

XSLは
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<list>
<xsl:apply-templates select="books/item/keywords/keyword"/>
</list>
</xsl:template>

<xsl:template match="keyword">
<category>
<xsl:value-of select="."/>
<xsl:apply-templates select="books/item/title"/>
</category>
</xsl:template>
<xsl:template match="title">
<title>
<xsl:value-of select="."/>
</title>
</xsl:template>
</xsl:stylesheet>


としています。
生成されるXMLは、
<list>
<category>プログラムの基礎</category>
</list>

となり、<title>が入りません。
解決策を教えてくださいm(_ _)m

A 回答 (9件)

No7の方法は表記的には合っているけれど正しくないよ。


理由は item が複数有った場合正しい node を参照できていない可能性が有るから。

>で、どうやって解決したらよいのでしょうか??
見えないと判ったんだから見える所から持ってくるか、見える所から投げるか、って形に書き換えるしかないよ。
つまり
A. match="item" の段階を作ってそこで生成する形に変更するか
B. 現状の形で keyword で投げる時に title も渡すか
C. rootで全部処理しちゃうか
のどれか。


Bで要りそうなもの
http://www.infoteria.com/jp/contents/xml-data/RE …
http://www.google.co.jp/search?q=xslt%20with-par …

Cで要りそうなもの
http://www.infoteria.com/jp/contents/xml-data/RE …


因みに「つまりどういうソース?」と聞かれてもそれは丸投げになっちゃうから答えてあげられない。
    • good
    • 0

またまた挑戦です。



・ 複数のitemとkeywordsに対処したつもりです。

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

<xsl:template match="books">
<xsl:for-each select="item">
<xsl:for-each select="keywords">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>

<xsl:template match="keywords">
<xsl:for-each select="keyword">
<category>
<xsl:value-of select="."/>
<title>
<xsl:value-of select="../../title"/>
</title>
</category>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
    • good
    • 0

XSLを書き直してみました。



------------------------------------------------------
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<list>
<xsl:apply-templates select="books/item/keywords"/>
</list>
</xsl:template>

<xsl:template match="keywords">
<xsl:for-each select="keyword">
<category>
<xsl:value-of select="."/>
<title>
<xsl:value-of select="/books/item/title"/>
</title>
</category>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

------------------------------------------------------
    • good
    • 0

ごめん よく見ると book じゃなくて books だね・・・・・

    • good
    • 0

><xsl:template match="title">


>が実行されないかわからないのです。
><xsl:apply-templates select="books/item/title"/>
>がCの関数に飛ばす文と同じように思っており、

Cなら判るんだね。
なら

----------------------------------
- <item no="1">
<title>プログラムの基礎</title>
<creator>Heinemeier Hansson</creator>
<publisher>オーム社</publisher>
- <keywords>
<keyword>プログラミング</keyword>
<keyword>ソフトウェア</keyword>
<keyword>入門</keyword>
</keywords>
</item>
----------------------------------
多分この親として<book>で囲ってあってitemが複数あるんだと思う。
これをちょっとCっぽい形にしてみようか

item[0]
{
 no = 1;
 title = { "プログラムの基礎" };
 creator = { "Heinemeier Hansson" };
 publisher = { "オーム社" };
 keywords =
 {
  keyword[0] = "プログラミング";
  keyword[1] = "ソフトウェア";
  keyword[2] = "入門";
 };
},
item[1]
{
 //...
};

若干違うんだけどこんな感じだと思ってくれたら大丈夫。
そんで xsl:template は
呼ばれて実行するのと適合で実行するのと2系統の実行の仕方が有って
今回のは後者の方法。
イベントを投げるとそのイベントが受け取れる関数が呼ばれるよね?
適合系の場合はこれに似ていて受け取れる「nodeName」であった場合に実行される。(matchの部分)

だとして


><xsl:template match="/">
有無を言わさずroot処理なのは判ると思う。
実際ここは必ず適合して実行される。

><xsl:template match="keyword">
これは投げた物、 nodeName が keyword なら実行される。

><xsl:template match="title">
同じく「投げた物が」 title なら実行される。
(正しくは投げた中にtitleが有ればそこを起点に実行される)

match="/" でのカレント
node = {root : {"book" : {"item","item",...} } , ...};
そこの中で投げてる場所
><xsl:apply-templates select="books/item/keywords/keyword"/>
これを受けて match="keyword" が適合。そこでのカレント
node = { "keyword":"プログラミング" },{ "keyword":"ソフトウェア"},...;
(複数個のkeywordを投げられているのでその時によって keyword="プログラミング"→keyword="ソフトウェア" と値が変わる)

そこの中で投げてるのは
><xsl:apply-templates select="books/item/title"/>
今有るのは・・・
node = { "keyword":"プログラミング" },{ "keyword":"ソフトウェア"},...;



投げる物が無い、の意味、判りそう?
    • good
    • 0
この回答へのお礼

まさかとは思っていましたが、
やはり下っ端は上位にはいけないんですね…
すごく使え勝手が悪いですね><

で、どうやって解決したらよいのでしょうか??

お礼日時:2008/02/20 23:36

>違うんでしょうか?


合ってるよ。

カレントは keyword なんだけど
><xsl:apply-templates select="books/item/title"/>



→そんなものは無い が答え。
    • good
    • 0
この回答へのお礼

それは分かっているのですが、
なぜ
<xsl:template match="title">
<title>
<xsl:value-of select="."/>
</title>
</xsl:template>
が実行されないかわからないのです。
どうも
<xsl:apply-templates select="books/item/title"/>
がCの関数に飛ばす文と同じように思っており、
<xsl:template match="title">
がその関数だという考えがあるんですが、
XMLはどういう風になっているのか分からなくて

お礼日時:2008/02/20 19:13

「生成されるXMLは」が明示されていないようです。



一応、次のように仮定して試してみたいと思います。

・ xslに "books/item/keywords/keyword" とあるので、xmlにも文書要素として、booksを加えます。

--------------------------------------------------------------------------------
<books>
<item no="1">
<title>プログラムの基礎</title>
<creator>Heinemeier Hansson</creator>
<publisher>オーム社</publisher>
<keywords>
<keyword>プログラミング</keyword>
<keyword>ソフトウェア</keyword>
<keyword>入門</keyword>
</keywords>
</item>
</books>

--------------------------------------------------------------------------------

・ <category>はどこに表示したらよいかわからないので無視します。

・ <keyword>は最初のものだけと、全ての場合と、二つを取り上げます。

--------------------------------------------------------------------------------
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<title>
<xsl:value-of select="books/item/title"/>
</title>
<list>
<xsl:value-of select="books/item/keywords/keyword"/>
</list>
</xsl:template>
</xsl:stylesheet>

--------------------------------------------------------------------------------
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<title>
<xsl:value-of select="books/item/title"/>
</title>
<xsl:apply-templates select="books/item/keywords"/>
</xsl:template>

<xsl:template match="keywords">
<xsl:for-each select="keyword">
<list>
<xsl:value-of select="."/>
</list>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

--------------------------------------------------------------------------------
・ xslがツリーを辿っていく時、適用されるテンプレートを探しながらルートノードから順に下へと始めます。

・ 一度使われたテンプレートのノードの子孫は除かれていくと思います。
    • good
    • 0
この回答へのお礼

すいません。
生成したいXMLが明白でなかったですね。
生成したいXMLは
<list>
 <category>
 プログラミング
  <title>
   プログラミングの基礎
  </title>
 </category>
 <category>
 ソフトウェア
  <title>
  プログラミングの基礎
  </title>
 </category>
 <category>
 入門
  <title>
  プログラミングの基礎
  </title>
 </category>
</list>

としたかったんです。

お礼日時:2008/02/20 16:12

><xsl:apply-templates select="books/item/title"/>←ここ


ここでmatchしているのは
><xsl:template match="keyword">

>>>XMLは
中略
>>>- <keywords>
>>><keyword>プログラミング</keyword>

さて逆に質問になっちゃうんだけど
template match="keyword"
ここで保持されているカレントノードの中身、どうなってるか判るかな?
それが判るとなぜ投げられないのかが判るよ。

もし中身を補足してみるつもりなら
「判らない」じゃなく「こうかな?」で。

この回答への補足

そこでのカレントノードは
keywordだと思っていたんですが
違うんでしょうか?

補足日時:2008/02/20 16:13
    • good
    • 0

>となり、<title>が入りません。



><xsl:apply-templates select="books/item/keywords/keyword"/>
rootのmatchにはこれしかapplyが無いね。
titleを投げてる部分が無いんだけど・・・?

って事じゃないかな。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
titleは
<xsl:template match="keyword">
<category>
<xsl:value-of select="."/>
<xsl:apply-templates select="books/item/title"/>←ここ
</category>
</xsl:template>

のように投げているんですけど
それでもうまくいきません><

お礼日時:2008/02/20 03:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!