xsl-list
[Top] [All Lists]

[xsl] A problem using the xsl:key facility

2010-07-20 15:17:55







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>
--~--

<Prev in Thread] Current Thread [Next in Thread>