[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Changing a Tree Walking, forward walk example

Subject: Re: Changing a Tree Walking, forward walk example
From: "Graeme Kidd" <coolkidd3@xxxxxxxxxxx>
Date: Tue, 27 Jan 2009 00:37:22 -0000
Re:  Changing a Tree Walking
Thanks for your detailed explanation, it helped a lot with my understanding.

Can you by any chance suggest any good books? Since I would like to get to know more about XSLT 2.0

Graeme
--------------------------------------------------
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Sent: Saturday, January 24, 2009 2:39 AM
To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re:  Changing a Tree Walking, forward walk  example

At 2009-01-24 01:04 +0000, Graeme Kidd wrote:
The problem is that my list does not have an end list node if a new list starts immediately after an existing list. So for example this:
...
Needs to be changed to this:
...
I am finding it hard because I need to match a list node that does not contain "End List" to start a list as well as end it. So far I have not been able to detect if I am still in a list before a new list starts, in which case I need to close it and start a new one.

That is a typical imperative programming approach that does not work well with XML content. You are thinking about tags instead of thinking about elements. In XSLT one cannot "close one off and start a new one", because that implies one is able to "throw in an end tag and then a start tag". When dealing with markup, this isn't an issue, but XSLT doesn't deal with markup, it deals with nodes. I see this a lot in very poorly written XSLT where novice users try to "end off a table row and start another" by inappropriately using disable-output-escaping. That's fine in programming where I'm serializing markup, but in XSLT one is constructing result trees, not serializing markup (that's the responsibility of the XSLT processor, not the stylesheet).


The approach you need must be more declarative. "How do I detect everything that belongs in a list so that I can properly construct the result tree list nodes?" Nothing there about tags, only about structures.

So, you need to look at your content and determine how to declaratively express the presence of the lists. This is done for your example with <xsl:for-each-group>, which I tell my students is better understood when one reads the element name as if it were "for the first member of each group".

Now, based on the nature of your data, your lists start with "<list>...</list>" and they optionally end with "<list>End List</list>". Another way to say that is a list starts with "<list>....</list>" and non-lists start with "<list>End List</list>".

So this is how I approached it in the solution below ... I hope this helps.

. . . . . . . . . . . ken

t:\ftemp>type kidd.xml
<document>
   <p>Non List text</p>
   <list>List Heading Type 1</list>
   <p>First item</p>
   <p>Second item</p>
   <list>List Heading Type 2</list>
   <p>First item</p>
   <p>Second item</p>
   <p>Third item</p>
   <list>End List</list>
   <p>Unrelated Text</p>
   <p>Not in a list</p>
   <list>List Heading Type 1</list>
   <p>First item</p>
   <list>End List</list>
   <p>More Unrelated Text</p>
   <p>Not in a list</p>
</document>

t:\ftemp>call xslt2 kidd.xml kidd.xsl
<?xml version="1.0" encoding="UTF-8"?>
<document>
   <p>Non List text</p>
   <list>
      <li>First item</li>
      <li>Second item</li>
   </list>
   <list>
      <li>First item</li>
      <li>Second item</li>
      <li>Third item</li>
   </list>
   <p>Unrelated Text</p>
   <p>Not in a list</p>
   <list>
      <li>First item</li>
   </list>
   <p>More Unrelated Text</p>
   <p>Not in a list</p>
</document>
t:\ftemp>type kidd.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="document">
  <document>
    <xsl:for-each-group select="*" group-starting-with="list">
      <xsl:choose>
        <xsl:when test="not(self::list)">
          <!--there must be a group before the first list-->
          <xsl:apply-templates select="current-group()"/>
        </xsl:when>
        <xsl:when test=".='End List'">
          <!--this indicates that what follows isn't in a list-->
          <xsl:apply-templates select="current-group()[position()>1]"/>
        </xsl:when>
        <xsl:otherwise>
          <!--we are starting a list-->
          <list>
            <xsl:for-each select="current-group()[position()>1]">
              <li><xsl:apply-templates/></li>
            </xsl:for-each>
          </list>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </document>
</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!



--
Upcoming XSLT/XSL-FO, UBL and code list hands-on training classes:
:  Sydney, AU 2009-01/02; Brussels, BE 2009-03; Prague, CZ 2009-03
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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.