xsl-list
[Top] [All Lists]

Antwort: Re: [xsl] Grouping hierarchy path elements

2004-08-23 07:27:27

Hi Jeni,

wow, this is great! Thank you so much for that. It almost works perfectly.

Transforming the real document - not the example I posted - I get a stack
overflow error.

So far, what I have found about the error is this:
It always occurs at the same spot, ie. it is reproducible. At the spot it
happens, the path name of the following item is equal to the current item's
path, but appended some more characters. From that I conclude that the
error has its cause at some place the starts-with function was used.
I will dig into that now. Again, thanks a lot for your help.

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(_dot_)geske(_at_)iav(_dot_)de>
Internet: http://www.iav.de


                                                                                
                                                                
                      Jeni Tennison                                             
                                                                
                      <jeni(_at_)jenitenniso        An:       "Daniel Geske" 
<Daniel(_dot_)Geske(_at_)iav(_dot_)de>                                          
         
                      n.com>                   Kopie:    
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com                                
                        
                                               Thema:    Re: [xsl] Grouping 
hierarchy path elements                                             
                      2004-08-23 15:04                                          
                                                                
                      Bitte antworten                                           
                                                                
                      an Jeni Tennison                                          
                                                                
                                                                                
                                                                
                                                                                
                                                                




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="{(_at_)id}" />
</xsl:template>

Cheers,

Jeni

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








<Prev in Thread] Current Thread [Next in Thread>
  • Antwort: Re: [xsl] Grouping hierarchy path elements, Daniel Geske <=