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

Grouping hierarchy path elements, part 2

Subject: Grouping hierarchy path elements, part 2
From: "Daniel Geske" <Daniel.Geske@xxxxxx>
Date: Tue, 24 Aug 2004 10:58:20 +0200
transformdocument
Hi all,

I am a great deal further now, since I can re-create the tree structure
from a path string. Now again, my task has become a bit more complicated.
Instead of extracting the path of an element right from the source document
root, references to elements containing the path information are grouped in
other elements.
Elements containing paths are to be transformed into the destination
document selectively.

To make things clearer, here is an example of the source file:
<?xml version="1.0" encoding="UTF-8"?>
<sourceDocument>
  <items>
     <item id="1">
       <path>root\folderA\folderB\folderC</path>
     </item>
     <item id="2">
       <path>root\folderA\folderB\folderD</path>
     </item>
     <item id="3">
       <path>root\folderA\folderE\folderF</path>
     </item>
     <item id="4">
       <path>root\folderG</path>
     </item>
     <item id="5">
       <path>root\folderA\folderB\folderD</path>
     </item>
  </items>
  <otherItems>
     <otherItem id="A">
       <referenceItemId>2</referenceItemId>
       <referenceItemId>3</referenceItemId>
       <referenceItemId>5</referenceItemId>
     </otherItem>
     <otherItem id="B">
       <referenceItemId>5</referenceItemId>
     </otherItem>
  </otherItems>
</sourceDocument>

This is what the transformed file should look like:
<?xml version="1.0" encoding="UTF-8"?>
<transformedDocument>
  <Chapter id="A">
     <path name="root">
       <path name="folderA">
          <path name="folderB">
            <path name="folderD">
               <item id="2" />
               <item id="5" />
            </path>
          </path>
          <path name="folderE">
            <path name="folderF">
               <item id="3" />
            </path>
          </path>
       </path>
     </path>
  </Chapter>
  <Chapter id="B">
     <path name="root">
       <path name="folderA">
          <path name="folderB">
            <path name="folderD">
               <item id="5" />
            </path>
          </path>
       </path>
     </path>
  </Chapter>
</transformedDocument>

My current XSLT looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
  <!-- Match the source document root -->
  <xsl:template match="/sourceDocument">
     <transformedDocument>
       <xsl:apply-templates select="otherItems"/>
       <!-- Uncomment line below to check wheather template items is
working. -->
       <!--xsl:apply-templates select="items"/-->
     </transformedDocument>
  </xsl:template>
  <xsl:template match="otherItems">
     <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="otherItem">
     <!-- Create a node 'Chapter' for each element 'otherItem'. -->
     <Chapter>
       <xsl:attribute name="id"><xsl:value-of select="attribute::id"/></
xsl:attribute>
       <xsl:variable name="root" select="
substring-before(//items/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[attribute::id=referenceItemId]"/>
          </xsl:call-template>
       </path>
       <xsl:comment>
          <xsl:text>//item[attribute::id]: </xsl:text>
          <xsl:value-of select="//item[attribute::id]"/>
          <xsl:text>
          </xsl:text>
          <xsl:text>referenceItemId: </xsl:text>
          <xsl:value-of select="referenceItemId"/>
       </xsl:comment>
     </Chapter>
  </xsl:template>
  <xsl:template match="items">
     <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>
  </xsl:template>
  <xsl:template name="transformDocument">
     <xsl:param name="path"/>
     <xsl:param name="items" select="$items"/>
     <xsl:comment>
       <xsl:text>transformDocument called with items param='</xsl:text>
       <xsl:value-of select="$items"/>
       <xsl:text>'</xsl:text>
     </xsl:comment>
     <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,
concat($newPath, '\'))]"/>
          </xsl:call-template>
       </path>
       <xsl:call-template name="transformDocument">
          <xsl:with-param name="path" select="$path"/>
          <xsl:with-param name="items" select="$items[path != $newPath and
                                                  not(starts-with(path,
concat($newPath, '\')))]"/>
       </xsl:call-template>
     </xsl:if>
  </xsl:template>
  <xsl:template match="item">
     <xsl:comment>
       <xsl:text>Item path=</xsl:text>
       <xsl:value-of select="path"/>
     </xsl:comment>
     <item id="{@id}"/>
  </xsl:template>
</xsl:stylesheet>

It seems as if there is something wrong with my items parameter for the
transformDocument template called from the template 'otherItem'.
If you run the above, you will notice that <xsl:value-of select="
//item[attribute::id]"/> actually does not return the id-Attribute element
of all items, but instead returns the child elements of the first
referenced item. Finding a solution to this would get me a big step ahead I
think.

Maybe anybody could point me the right direction?
Thanks a lot.

Mit freundlichen Gr|_en / Sincerely

Daniel Geske


Telematik/Infotainment, AE-V32
Telematics/Infotainment, AE-V32

IAV GmbH
Ingenieurgesellschaft Auto und Verkehr
Carnotstra_e 1
10587 Berlin
Germany

Tel.:  +49  (30)  3 99 78 - 90 44
Fax: +49  (30)  3 99 78 - 94 11

E-mail: <mailto:daniel.geske@xxxxxx>
Internet: http://www.iav.de

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.