Greetings,
I am struggling with the use of an xsl:key in a particular construct.
I can't seem to get the xsl:key to work from within an xsl:for-each
loop. The key is defined outside of any template, and the for-each is
within a template. The key works fine outside of the for-each. Do I
misunderstand something fundamental about the scope of a key?
I please see below for the XSLT, and the input and output files.
I am using Oxygen and Saxon-B 9.1.0.7
Thanks in advance!
Sincerely,
Nathan
######################
XSL Transform:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method='xml' encoding='UTF-8' indent='yes'/>
<xsl:key name="service-by-name" match="//service" use="@name"/>
<xsl:template match="catalog">
<catalog>
<xsl:apply-templates/>
</catalog>
</xsl:template>
<xsl:template match="service" />
<xsl:template match="serviceName" />
<xsl:template match="text()" />
<xsl:template match="dataset">
<!-- Gather the serviceName's -->
<xsl:variable name="serviceNames" >
<xsl:if test="@serviceName">
<xsl:element name="serviceName"><xsl:value-of
select="@serviceName"/></xsl:element>
</xsl:if>
<xsl:copy-of select="serviceName | metadata/serviceName"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="boolean(dataset)">
<xsl:element name="NestedDataset">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="dataset">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:element name="myServiceNames">
<xsl:copy-of select="$serviceNames"/>
</xsl:element>
<TheForEachLoopOutputIsInHere>
<xsl:for-each select="$serviceNames/serviceName" >
<xsl:variable name="sName"><xsl:value-of
select="."/></xsl:variable>
<xsl:comment>
Sanity Check #1: Copy the current node.
</xsl:comment>
<xsl:element name="copy-
of_current_serviceName_element"><xsl:copy-of select="."/></xsl:element>
<xsl:comment>
Sanity Check #2: Enshrine the string value
of the variable sName in a new element.
</xsl:comment>
<xsl:element name="value-
of_sName_variable"><xsl:value-of select="$sName"/></xsl:element>
<xsl:comment>
Sanity Check #3: Use the key "service-by-
name" to retrieve the
service element identified by the sName
variable. This always fails
within the xsl:for-each loop.
</xsl:comment>
<xsl:element name="copy-of_service_element">
<xsl:attribute name="name"><xsl:value-of
select="$sName"/></xsl:attribute>
<xsl:copy-of select="key('service-by-name',
$sName)"/>
</xsl:element>
<!-- <xsl:element name="aservice"><xsl:copy-of
select="."/></xsl:element> -->
</xsl:for-each>
</TheForEachLoopOutputIsInHere>
<xsl:comment>
Sanity Check #4: Outside of the xsl:for-each loop
we can get things from the key "service-by-name".
Here I'll just get a copy of the service called
"wcs".
</xsl:comment>
<xsl:copy-of select="key('service-by-name','wcs')"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
######################
XML Input:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<service name="woo" serviceType="OPENDAP" base="/opendap/hyrax1/" />
<service name="hoo" serviceType="OPENDAP" base="/opendap/hyrax2/" />
<service name="boo" serviceType="OPENDAP" base="/opendap/hyrax3/" />
<service name="all" serviceType="Compound" base="">
<service name="ncdods" serviceType="OPENDAP" base="/thredds/
dodsC/" />
<service name="wcs" serviceType="WCS" base="/thredds/wcs/" />
<service name="wms" serviceType="WMS" base="/thredds/wms/" />
</service>
<dataset name="Dataset 0">
<dataset name="dataset1" serviceName="wcs" urlPath="satellite/
PH/ssta/1day">
<serviceName>all</serviceName>
</dataset>
</dataset>
</catalog>
######################
XML Output:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<NestedDataset name="Dataset 0">
<dataset name="dataset1">
<myServiceNames>
<serviceName>wcs</serviceName>
<serviceName>all</serviceName>
</myServiceNames>
<TheForEachLoopOutputIsInHere><!--
Sanity Check #1: Copy the current node.
--><copy-of_current_serviceName_element>
<serviceName>wcs</serviceName>
</copy-of_current_serviceName_element>
<!--
Sanity Check #2: Enshrine the string value
of the variable sName in a new element.
--><value-of_sName_variable>wcs</value-
of_sName_variable>
<!--
Sanity Check #3: Use the key "service-by-
name" to retrieve the
service element identified by the sName
variable. This always fails
within the xsl:for-each loop.
--><copy-of_service_element name="wcs"/>
<!--
Sanity Check #1: Copy the current node.
--><copy-of_current_serviceName_element>
<serviceName>all</serviceName>
</copy-of_current_serviceName_element>
<!--
Sanity Check #2: Enshrine the string value
of the variable sName in a new element.
--><value-of_sName_variable>all</value-
of_sName_variable>
<!--
Sanity Check #3: Use the key "service-by-
name" to retrieve the
service element identified by the sName
variable. This always fails
within the xsl:for-each loop.
--><copy-of_service_element name="all"/>
</TheForEachLoopOutputIsInHere>
<!--
Sanity Check #4: Outside of the xsl:for-each loop
we can get things from the key "service-by-name".
Here I'll just get a copy of the service called
"wcs".
--><service name="wcs" serviceType="WCS" base="/
thredds/wcs/"/>
</dataset>
</NestedDataset>
</catalog>
============================================================
Nathan Potter Oregon State University, COAS
ndp at coas.oregonstate.edu 104 Ocean. Admin. Bldg.
541 231 3317 voice Corvallis, OR 97331-5503
541 737 2064 fax
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--