@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

[XSLT]同一階層のElementのグループ化

1
投稿者投稿内容
aiaru
会議室デビュー日: 2009/02/10
投稿数: 7
投稿日時: 2009-02-25 18:40
お世話になっております。


XSLTにて、同一階層にあるElementのグループ化について良い方法をご存じでしたらご教授いただけませんでしょうか?

[やりたいこと]
Aから次のAまでElementを1つのグループにする

#XML
<ROOT>
 <A>A1</A>
 <B>B1</B>
 <C>C1</C>
 <A>A2</A>
 <C>C2</C>
 <A>A3</A>
 <A>A4</A>
 <B>B2</B>
</ROOT>


#結果の想定
<ROOT>
 <GROUP>
  <A>A1</A>
  <B>B1</B>
  <C>C1</C>
 </GROUP>
 <GROUP>
  <A>A2</A>
  <C>C2</C>
 </GROUP>
 <GROUP>
  <A>A3</A>
 </GROUP>
 <GROUP>
  <A>A4</A>
  <B>B2</B>
 </GROUP>
</ROOT>
nari
会議室デビュー日: 2008/05/29
投稿数: 7
投稿日時: 2009-02-26 11:20
こんなかんじでどうでしょうか?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:element name="ROOT">
<xsl:apply-templates select="ROOT/A"/>
</xsl:element>
</xsl:template>

<xsl:template match="ROOT/*">
<xsl:param name="isOutGroup" select="1"/>
<xsl:choose>
<xsl:when test="$isOutGroup='1'">
<xsl:element name="GROUP">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1]">
<xsl:with-param name="isOutGroup" select="0"/>
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:when test="name()!='A'">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1]">
<xsl:with-param name="isOutGroup" select="0"/>
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
aiaru
会議室デビュー日: 2009/02/10
投稿数: 7
投稿日時: 2009-02-26 16:10
nariさん。

あ、なるほど。
matchを使っての再帰とかもできるんですね。(そりゃそうですよね。)
再帰 = call-template のイメージがあったので勉強になりました。



<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" />
<xsl:template match="/">
<xsl:element name="ROOT">
<xsl:for-each select="ROOT/A">
<GROUP>
<xsl:copy-of select="." />
<xsl:call-template name="func">
<xsl:with-param name="node" select="following-sibling::*[1]" />
</xsl:call-template>
</GROUP>
</xsl:for-each>
</xsl:element>
</xsl:template>

<xsl:template name="func">
<xsl:param name="node" />
<xsl:if test="name($node)='B' or name($node)='C'">
<xsl:copy-of select="$node" />
<xsl:call-template name="func">
<xsl:with-param name="node" select="$node/following-sibling::*[1]" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
1

スキルアップ/キャリアアップ(JOB@IT)