xsl-list
[Top] [All Lists]

Re: Converting siblings to children of a node.

2003-08-06 18:40:47
Hi: Shawn:

I am not sure if you are in position to be using XSLT 2.0 (Saxon 7 is the only processor i believe) but if you are - You may want to have a look at the for-each-group element, there are also some good examples on using this element on the XSLT 2.0 TR on www.w3.org.

Thanks
Mark

Shawn O. McKenzie wrote:

I have a source document something like:

<longdesc>
 <para style="Normal">This is a regular paragraph.</para>
 <para style="Normal">So is this but what follows is a list:</para>
 <para style="LS1">Item one</para>
 <para style="LS1">Item two</para>
 <para style="Normal">This is a regular paragraph.</para>
 <para style="Normal">This is a regular paragraph.</para>
 <para style="Normal">This is a regular paragraph.</para>
 <para style="Normal">What follows is a list:</para>
 <para style="LS1">Item one</para>
 <para style="LS1">Item two</para>
 <para style="LS1">Item three</para>
 <para style="Normal">This is a regular paragraph.</para>
</longdesc>

I would like to translate this to something like

<p>This is a regular paragraph.</p>
<p>So is this but what follows is a list:</p>
<ul>
  <li>Item one<li>
  <li>Item two<li>
</ul>
<p>This is a regular paragraph.</p>
<p>This is a regular paragraph.</p>
<p>This is a regular paragraph.</p>
<p>What follows is a list:</p>
<ul>
  <li>Item one<li>
  <li>Item two<li>
  <li>Item three<li>
</ul>
<p>This is a regular paragraph.</p>


I thought I could do this with something like:

      <xsl:if test="@style='LS1'">
        <xsl:if test="not(preceding-sibling::para/@style='LS1')">
          <ul>
            <li><xsl:value-of select="."/></li>
        </xsl:if>

<xsl:if test="preceding-sibling::para/@style='LS1' and following-sibling::para/@style='LS1'">
          <li><xsl:value-of select="."/></li>
        </xsl:if>

<xsl:if test="preceding-sibling::para/@style='LS1' and not(following-sibling::para/@style='LS1')">
            <li><xsl:value-of select="."/></li>
          </ul>
        </xsl:if>
      </xsl:if>

But of course that won't work. Then, I thought I could do it with recursion, passing the current para element as a variable:

<xsl:template match="para[(_at_)style='LS1']">
 <xsl:if test="not(preceding-sibling::para[(_at_)style='LS1'])">
   <xsl:variable name="node">
     <xsl:copy-of select="."/>
   </xsl:variable>
   <ul>
     <xsl:call-template name="list">
       <xsl:with-param name="listitem" select="$node"/>
     </xsl:call-template>
   </ul>
 </xsl:if>
</xsl:template>

<xsl:template name="list">
 <xsl:param name="listitem"/>
 <li><xsl:value-of select="$listitem"/></li>
 <xsl:if test="following-sibling::para[(_at_)style='LS1']">
   <xsl:call-template name="list">
     <xsl:with-param name="listitem">
       <xsl:copy-of select="following-sibling::para"/>
     </xsl:with-param>
   </xsl:call-template>
 </xsl:if>
</xsl:template>


But that doesn't change the context to the preceding-sibling, so it loops.

Any suggestions?


XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>