xsl-list
[Top] [All Lists]

Re: XSLT 1.0: Grouping Adjacent Elements in Embedded Lists

2004-11-04 16:30:26
Joe,

I haven't tested this, but I think you're almost there.

At 03:21 PM 11/4/2004, you wrote:
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.

I think you're correct, though. Or to refine slightly: it's not the special case of an OL_LI that has a preceding EM_OL_LI, but rather that the *first* OL_LI in the group is the special case.

That is, you want this kick-off (the creation of the p and ol wrappers and the initiation of the "walk" you perform to occur for the first OL_LI, but no others.

This would be a simple matter of changing your test to:

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

which is to say "if there's no OL_LI before this one, start my list" instead of "if the immediately preceding sibling is not an OL_LI, start my list".

Now, if your lists aren't wrapped at all, but are completely flat and appear mixed in with other elements (such as paragraphs or whatever) you might need a test that says "if the immediately preceding sibling is not an OL_LI or an EM_OL_LI, start my list". That would be

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

And if someone could explain to me the difference between [self::OL_LI] and [OL_LI] that would be an added educational bonus. Thanks!

"OL_LI" in XPath is short for "child::OL_LI", so the difference here is the same as the difference between [self::OL_LI] (the predicate tests true for context nodes that are OL_LI elements) and [child::OL_LI] (the predicate tests true for context nodes that have OL_LI children).

The expression "*[self::X|self::Y]" returns a child element ("*" being short for "child::*") that is either an X or a Y (the predicate returns a union of the set of X elements that are the context node and the set of Y elements that are the context node -- i.e. the context node if it's an X or a Y, nothing if it's something else).

I hope this helps,
Wendell


======================================================================
Wendell Piez                            
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================



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