Re: XSL: Returning a selected node in the context of it's ancestors

Subject: Re: XSL: Returning a selected node in the context of it's ancestors
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 Oct 1999 17:54:04 -0700
At 99/10/19 17:29 -0400, Clark C. Evans wrote:
On Tue, 19 Oct 1999, James Carlyle wrote:
> Has anyone tried to use XSL to return a document fragment that includes the
> necessary parent nodes for a selected node, so that the lineage of the
> selected node is maintained?

<snip/>

> <vendor name="james">
>  <product id="1234">
>   <material>SiO2</material>
>  </product>
>  <product id="5678">
>   <material>CO2</material>
>  </product>
> </vendor>
>
> and a stylesheet fragment
>
> <xsl:for-each select="/vendor/product/material[.='SiO2']">
>
> to return the fragment
>
> <vendor name="james">
>  <product id="1234">
>   <material>SiO2</material>
>  </product>
> </vendor>
>

Brute force solution.... how can this be improved?

The solution below is based on the principle that generate-id() never returns a name that has an embedded space.


I hope this helps, though I think it is as brute force as yours is.

............. Ken

p.s. for your future use, note how I used copy-of to copy the attributes using a succinct syntax

T:\jc>type jc.xml
<?xml version="1.0"?>
<vendor name="james">
 <product id="1234">
  <material>SiO2</material>
 </product>
 <product id="5678">
  <material>CO2</material>
 </product>
</vendor>

T:\jc>type jc.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output method="xml"/>

<xsl:template match="/">
  <xsl:for-each select="/vendor/product/material[.='SiO2']">
    <xsl:call-template name="show-context"/>
  </xsl:for-each>
</xsl:template>

<xsl:template name="show-context" match="*" mode="show-context">
  <xsl:param name="node-ids" select="' '"/>
  <xsl:choose>      <!--walk up tree until at document element-->
    <xsl:when test="ancestor::*">
      <xsl:apply-templates mode="show-context" select="..">
        <xsl:with-param name="node-ids"
              select="concat( $node-ids, generate-id(.), ' ' )"/>
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>            <!--must be at document element-->
      <xsl:apply-templates mode="show-context-members"
                           select=".">     <!--walk down tree -->
        <xsl:with-param name="node-ids"
              select="concat( $node-ids, generate-id(.), ' ' )"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="*" mode="show-context-members">
  <xsl:param name="node-ids"/>   <!--lineage of generate-id(.)-->
  <xsl:choose>            <!--first in list is last in descent-->
    <xsl:when test="starts-with($node-ids,
                            concat( ' ', generate-id(.), ' '))">
      <xsl:copy-of select="."/>
    </xsl:when>
                                  <!--others reflect hierarchy-->
    <xsl:when test="contains($node-ids,
                    concat( ' ', generate-id(.), ' '))">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates mode="show-context-members"
                             select="*">
          <xsl:with-param name="node-ids" select="$node-ids"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:when>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

T:\jc>xt jc.xml jc.xsl jc.out

T:\jc>type jc.out
<vendor name="james"><product id="1234"><material>SiO2</material></product></vendor>
T:\jc>




--
G. Ken Holman                    mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.             http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0   +1(613)489-0999   (Fax:-0995)
Web site: XSL/XML/DSSSL/SGML services, training, libraries, products.
Practical Transformation Using XSLT and XPath      ISBN 1-894049-02-0
Next instructor-led training:  1999-11-08, 1999-11-09, 1999-12-05/06,
-                1999-12-07, 2000-02-27/28, 2000-05-11/12, 2000-05-15


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread