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

Re: Grouping hierarchy path elements

Subject: Re: Grouping hierarchy path elements
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 23 Aug 2004 14:04:45 +0100
path elements
Hi Daniel,

> I've been working on an XSLT for days now, and cannot find the solution to
> one problem. I have a source XML document containing one level of elements.
> Each element contains a path element that holds information on what path
> the element was extracted from.
>
> Now, through XSL transformation, I would like to recreate the tree
> structure of the items.

Here's a set of templates that works with your example.

The main template is the transformDocument template. This takes a path
(an initial part of a path) and a set of items (whose paths should all
start with the $path). It works out the next step in the path for the
first item and from that creates a new path. Then it sorts the items
into three groups:

  - items whose path *is* the new path, which should just be output
  - items whose path *starts with* the new path, which need to be
    processed again by this template, with the new path
  - items whose path *doesn't* start with the new path, which need to
    be processed again by this template, with the current path

The result of the first two of these groups gets put within a <path>
element, and the result of the third of these groups gets inserted
afterwards.

<xsl:template name="transformDocument">
  <xsl:param name="path"/>
  <xsl:param name="items" select="/.."/>
  <xsl:if test="$items">
    <xsl:variable name="step">
      <xsl:variable name="rest" select="substring-after($items[1]/path, concat($path, '\'))" />
      <xsl:choose>
        <xsl:when test="contains($rest, '\')">
          <xsl:value-of select="substring-before($rest, '\')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$rest" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="newPath" select="concat($path, '\', $step)" />
    <path name="{$step}">
      <xsl:apply-templates select="$items[path = $newPath]"/>
      <xsl:call-template name="transformDocument">
        <xsl:with-param name="path" select="$newPath" />
        <xsl:with-param name="items" select="$items[starts-with(path, $newPath) and
                                                    path != $newPath]"/>
      </xsl:call-template>
    </path>
    <xsl:call-template name="transformDocument">
      <xsl:with-param name="path" select="$path"/>
      <xsl:with-param name="items" select="$items[not(starts-with(path, $newPath))]"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>  

The next template matches the <items> element and starts off the
processing. I've assumed that there's only one root here.

<xsl:template match="items">
  <transformedDocument>
    <xsl:variable name="root" select="substring-before(item[1]/path, '\')" />
    <path name="{$root}">
      <xsl:call-template name="transformDocument">
        <xsl:with-param name="path" select="$root" />
        <xsl:with-param name="items" select="item" />
      </xsl:call-template>
    </path>
  </transformedDocument>
</xsl:template>
  
The final template just outputs whatever you want for each item; here,
a copy of the <item> element without its child <path> element.

<xsl:template match="item">
  <item id="{@id}" />
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

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.