xsl-list
[Top] [All Lists]

XSLT 1.0: Grouping Adjacent Elements in Embedded Lists

2004-11-04 13:21:51
Hello,

Essentially I'm trying to create a two-tiered embedded list from a flat list in 
which I need to group by adjacent like items.

<OL_LI> = Ordered List Items
<EM_OL_LI> = Embedded Ordered List Items

Sample Input is:

        <OL_LI>Top: Item 1</OL_LI>
        <EM_OL_LI>Sub A: Item 1</EM_OL_LI>
        <OL_LI>Top: Item 2</OL_LI>
        <EM_OL_LI>Sub B: Item 1</EM_OL_LI>
        <EM_OL_LI>Sub B: Item 2</EM_OL_LI>
        <EM_OL_LI>Sub B: Item 3</EM_OL_LI>
        <OL_LI>Top: Item 3<OL_LI>
        <EM_OL_LI>Sub C: Item 1</EM_OL_LI>
        <EM_OL_LI>Sub C: Item 2<EM_OL_LI>



Desired Output is:

        <p>
           <ol>
              <li>Top: Item 1</li>
              <p>
                 <ol>
                    <li>Sub A: Item 1</li>
                 </ol>
              </p>
              <li>Top: Item 2</li>
              <p>
                 <ol>
                    <li>Sub B: Item 1</li>
                    <li>Sub B: Item 2</li>
                    <li>Sub B: Item 3</li>
                 </ol>
              </p>
              <li>Top: Item 3</li>
              <p>
                 <ol>
                    <li>Sub C: Item 1</li>
                    <li>Sub C: Item 2</li>
                 </ol>
              </p>
           </ol>
        </p>




My Current Transform looks like this:

        <xsl:template match="OL_LI">
           <xsl:if test="not(preceding-sibling::*[1][self::OL_LI])">
              <p>
                 <ol>
                    <xsl:apply-templates select="." mode="li"/>
                 </ol>
              </p>
           </xsl:if>
        </xsl:template>
        
        <xsl:template match="OL_LI" mode="li">
           <li><xsl:apply-templates /></li>
           <xsl:apply-templates 
select="following-sibling::*[1][self::EM_OL_LI]"/>
           <xsl:apply-templates select="following-sibling::*[1][self::OL_LI]" 
mode="li"/>
        </xsl:template>
        
        <xsl:template match="EM_OL_LI">
           <xsl:if test="not(preceding-sibling::*[1][self::EM_OL_LI])">
              <p>
                 <ol>
                    <xsl:apply-templates select="." mode="li"/>
                 </ol>
              </p>
           </xsl:if>
        </xsl:template>
        
        <xsl:template match="EM_OL_LI" mode="li">
           <li><xsl:apply-templates/></li>
           <xsl:apply-templates 
select="following-sibling::*[1][self::EM_OL_LI]" mode="li"/>
        </xsl:template>




However, my current output looks like this:

        <p>
           <ol>
              <li>Top: Item 1</li>
              <p>
                 <ol>
                    <li>Sub A: Item 1</li>
                 </ol>
              </p>
           </ol>
        </p>
        
        <p>
           <ol>
              <li>Top: Item 2</li>
              <p>
                 <ol>
                    <li>Sub B: Item 1</li>
                    <li>Sub B: Item 2</li>
                    <li>Sub B: Item 3</li>
                 </ol>
              </p>
           </ol>
        </p>

        <p>
           <ol>
              <li>Top: Item 3</li>
              <p>
                 <ol>
                    <li>Sub C: Item 1</li>
                    <li>Sub C: Item 2</li>
                 </ol>
              </p>
           </ol>
        </p>

And it is separated into 3 separate lists. The inner list portion is working 
fine. What seems to be tripping me up is that the top level <ol> tag is closing 
before I want it to.
I'm pretty sure I have to edit this part to account for the case when 
preceding-sibling is <EM_OL_LI>

         <xsl:if test="not(preceding-sibling::*[1][self::OL_LI])">
              <p>
                 <ol>
                    <xsl:apply-templates select="." mode="li"/>
                 </ol>
              </p>
           </xsl:if>

But my attempts have been fruitless. This is a condensed version of what I'm 
doing. I also have to account of embedded unordered lists. The current 
transformation works great for non-embedded lists as well, which is something I 
have to handle. Any help would be greatly appreciated.
And if someone could explain to me the difference between [self::OL_LI] and 
[OL_LI] that would be an added educational bonus. Thanks!

-Joe



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