質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

Q&A

解決済

1回答

759閲覧

XSLTのfor-each-groupのスタート条件が有効にならない

UG_ito_Pcorp

総合スコア13

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

0グッド

0クリップ

投稿2020/04/07 02:37

編集2020/04/07 09:07

XSLTのfor-each-groupのスタート条件(group-starting-with)についてご教授ください。
for-each-groupを使用して、階層を付けた2つのtopicを生成したいと思います。
下記のサンプルソース(A)を変換テーブル(A)で変換して、アウトプット(A)を取得しました。

試したこと

サンプルソース(A):

<topic id=""> <title>Guitar maker</title> <body> <p outputclass="title1">Imported guitar</p> <p outputclass="body">Martin</p> <p outputclass="body">Gibson</p> <p outputclass="title1">Japanese guitar</p> <p outputclass="body">Yamaha</p> <p outputclass="body">Morris</p> </body> </topic>

XSLT(A):

<xsl:template match="title"> <map> <xsl:value-of select="."/> </map> </xsl:template> <xsl:template match="body"> <xsl:for-each-group select="p" group-starting-with="p[@outputclass='title1']"> <topic> <xsl:choose> <xsl:when test="current-group()[self::p[@outputclass='title1']]"> <title> <xsl:value-of select="."/> </title> <body> <xsl:apply-templates select="current-group()"/> </body> </xsl:when> </xsl:choose> </topic> </xsl:for-each-group> </xsl:template> <xsl:template match="node()"> <xsl:choose> <xsl:when test="@outputclass!='title1'"> <p><xsl:value-of select="."/></p> </xsl:when> </xsl:choose> </xsl:template>

アウトプット(A):

<map>Guitar maker</map> <topic> <title>Imported guitar</title> <body> <p>Martin</p> <p>Gibson</p> </body> </topic> <topic> <title>Japanese guitar</title> <body> <p>Yamaha</p> <p>Morris</p> </body> </topic>

不具合の内容

ここまでは良かったのですが、ソースが以下のような場合(B)、グループのスタート条件を変更しても、同様の結果が得られません。

サンプルソース(B)

<topic id=""> <title>Guitar maker</title> <body> <para> <prop outputclass="title1"/> <p>Imported guitar</p> </para> <para> <prop outputclass="body"/> <p>Martin</p> </para> <para> <prop outputclass="body"/> <p>Gibson</p> </para> <para> <prop outputclass="title1"/> <p>Japanese guitar</p> </para> <para> <prop outputclass="body"/> <p>Yamaha</p> </para> <para> <prop outputclass="body"/> <p>Morris</p> </para> </body> </topic>

XSLT(B):

<xsl:template match="body"> <xsl:for-each-group select="para" group-starting-with="para/prop[@outputclass='title1']"> <topic> <xsl:choose> <xsl:when test="current-group()[self::para/prop[@outputclass='title1']]"> <title> <xsl:value-of select="./p"/> </title> <body> <xsl:apply-templates select="current-group()/p"/> </body> </xsl:when> </xsl:choose> </topic> </xsl:for-each-group> </xsl:template> <xsl:template match="p"> <xsl:choose> <xsl:when test="../prop/@outputclass!='title1'"> <p><xsl:value-of select="."/></p> </xsl:when> </xsl:choose> </xsl:template>

残念なアウトプット(B):

<map>Guitar maker</map> <topic> <title>Imported guitar</title> <body> <p>Martin</p> <p>Gibson</p> <p>Yamaha</p> <p>Morris</p> </body> </topic>

ネットで公開されていたサンプルを見様見真似で流用しています。
思い通りのグループ化がされていないようなので、「<xsl:for-each-group select="para" group-starting-with="para/prop[@outputclass='title1']">」のスタート指定がNGなのでしょうか。

サンプルソース(B)から、アウトプット(A)の結果が得られるように、XSLT(B)のダメな部分をご指摘ください。
そもそも、「for-each-group」では無理な変換であれば、別途の方法をご教授ください。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  • グループ 2 個になるような @group-starting-with にする
  • 各グループの先頭 item で、自分以外に xsl:apply-templates する

ということで:

xml

1<xsl:stylesheet exclude-result-prefixes="#all" version="3.0" 2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 4 <xsl:output indent="yes" /> 5 6 <xsl:template as="element(map)" match="title"> 7 <map> 8 <xsl:apply-templates /> 9 </map> 10 </xsl:template> 11 12 <xsl:template as="element(topic)+" match="body"> 13 <xsl:for-each-group group-starting-with="para[prop[@outputclass = 'title1']]" select="para"> 14 <topic> 15 <title> 16 <xsl:value-of select="p" /> 17 </title> 18 <body> 19 <xsl:apply-templates select="current-group() except ." /> 20 </body> 21 </topic> 22 </xsl:for-each-group> 23 </xsl:template> 24 25 <xsl:template as="element(p)" match="p"> 26 <p> 27 <xsl:apply-templates /> 28 </p> 29 </xsl:template> 30 31</xsl:stylesheet>

投稿2020/04/08 07:35

編集2020/04/08 07:36
OACleaner

総合スコア63

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

UG_ito_Pcorp

2020/04/08 09:55

ご回答、ありがとうございます。 問題、解決いたしました。 回答中にいくつか知らない記述方法がありましたが、これから勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問