Re: [xsl] small grouping task

Subject: Re: [xsl] small grouping task
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Feb 2009 14:46:36 -0500
At 2009-02-26 11:30 -0800, Fred Christian wrote:
I have a grouping task I am having trouble wrapping my mind around.

In fact it isn't a "grouping" issue as we've been talking about grouping today, if I've interpreted your need correctly.


I need to change some <input>'s into <li>'s but the <input>'s don't wrap what the <li>'s have to.

But is the only element you want <span/>?


Want to give it a try?

Thank you for supplying the data. That helps make it quick.


Below you will find two solutions, one making the assumption that each list item is only a single span (in XSLT 1 or XSLT 2), the other making the assumption that each list item is all of the content (except <br/>) that follows each <input/> element (in XSLT 2).

I hope this helps.

. . . . . . . . . . Ken

T:\ftemp>type fred.xml
<div>
<p>text</p>
{surronding xhtml}
<p class="problem">{some xhtml with no inputs}
  <input type="radio" /> <span class="p">a</span><br />
  <input type="radio" /> <span class="p">b</span><br />
  <input type="radio" /> <span class="p">c</span><br />
  <input type="radio" /> <span class="p">d</span><br />
{some xhtml with no inputs}
</p>
{surronding xhtml}
</div>

T:\ftemp>call xslt fred.xml fred.xsl
<?xml version="1.0" encoding="utf-8"?>
<div>

   <p>text</p>
{surronding xhtml}
<ul class="m">
      <li class="m">
         <span class="p">a</span>
      </li>
      <li class="m">
         <span class="p">b</span>
      </li>
      <li class="m">
         <span class="p">c</span>
      </li>
      <li class="m">
         <span class="p">d</span>
      </li>
   </ul>
{surronding xhtml}
</div>
T:\ftemp>type fred.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="p[@class = 'problem' and input]">
  <!--start the list-->
  <ul class="m">
    <!--find the members of the list, assuming one item per member-->
    <xsl:for-each select="span">
      <li class="m">
        <xsl:apply-templates select="."/>
      </li>
    </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>type fred2.xml
<div>
<p>text</p>
{surronding xhtml}
<p class="problem">{some xhtml with no inputs}
  <input type="radio" /> <span class="p">a</span>ABC<br />
  <input type="radio" /> <span class="p">b</span>DEF<br />
  <input type="radio" /> <span class="p">c</span>GHI<br />
  <input type="radio" /> <span class="p">d</span>JKL<br />
{some xhtml with no inputs}
</p>
{surronding xhtml}
</div>

T:\ftemp>call xslt2 fred2.xml fred2.xsl
<?xml version="1.0" encoding="UTF-8"?>
<div>
   <p>text</p>
{surronding xhtml}
<ul class="m">
      <li class="m">
         <span class="p">a</span>ABC
  </li>
      <li class="m">
         <span class="p">b</span>DEF
  </li>
      <li class="m">
         <span class="p">c</span>GHI
  </li>
      <li class="m">
         <span class="p">d</span>JKL
{some xhtml with no inputs}
</li>
   </ul>
{surronding xhtml}
</div>
T:\ftemp>type fred2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="p[@class = 'problem' and input]">
  <!--start the list-->
  <ul class="m">
    <!--find the members of the list, assuming multiple items per member-->
    <xsl:for-each-group select="node()" group-starting-with="input">
      <xsl:if test="self::input"><!--found a group with an input-->
        <li class="m">
          <!--copy everything except <br/> elements-->
          <xsl:apply-templates select="current-group()[position()>1]
                                                      [not(self::br)]"/>
        </li>
      </xsl:if>
    </xsl:for-each-group>
  </ul>
</xsl:template>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>rem Done!



--
XQuery/XSLT training in Prague, CZ 2009-03 http://www.xmlprague.cz
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread