xsl-list
[Top] [All Lists]

Re: [xsl] Nesting XPath predicates

2008-04-23 16:43:32

On Apr 23, 2008, at 4:25 PM, Nathan Potter wrote:



Greetings,

I am having a difficulty creating a XPath element.

Tiny Example XML document:

<?xml version="1.0" encoding="UTF-8"?>
<catalog name="MasterCatalog">

    <service name="WCS"  base="/opendap/wcs_service/"/>

    <dataset name="Foo" urlPath="data/foo" >
        <serviceName>WCS</serviceName>
    </dataset>

</catalog>


This works:

    <xsl:value-of select="//service[(_at_)name='WCS']/@base" /><br />

It returns the value of the attribute "base" for the first "service"
element in the document whose "name" attribute evaluates to "WCS"

However, in my problem when processing a "dataset" element there is a child
element that contains the name of the service:

I need to get the "base" attribute for the "service" that matches the text
value of the "serviceName" element.

I thought that I should be able to do it by calling for the value- of the
serviceName element inside the XPath for the select::


My apologies, there is a typo. This:


    <xsl:template match="dataset">
<xsl:value-of select="(//service/[(_at_)name='{serviceName}']/ @base" />
    </xsl:template-match>


Should be:

    <xsl:template match="dataset">
<xsl:value-of select="//service/[(_at_)name='{serviceName}']/ @base" />
    </xsl:template-match>


Not that either one works...




But that doesn't work.


Question 1): Should that work? Is it just an XPath syntax error on my part, or
must the value of the equality test [(_at_)name='stuff'] be hard wired?

Question 2): Is there another way to get to the same place?


I can kludge it using a named template, but I think it's (a) fragile and (b) ugly.


Thanks in Advance!



Nathan Potter



Complete Example:



Example source XML:

<?xml version="1.0" encoding="UTF-8"?>
<catalog name="MasterCatalog">
    <service name="OPeNDAP-Hyrax"  base="/opendap/"/>
    <service name="WCS"  base="/opendap/wcs_service/"/>
    <dataset name="Surface Air Temperature"
             urlPath="data/TSurfAir" >
        <serviceName>OPeNDAP-Hyrax</serviceName>
   </dataset>
    <dataset name="Foo" urlPath="data/foo" >
        <serviceName>WCS</serviceName>
   </dataset>
    <dataset name="SeaSurfaceTemperature"
             urlPath="data/sst">
        <serviceName>WCS</serviceName>
   </dataset>
</catalog>




Example XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xsl:stylesheet []>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                >
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>


    <xsl:template match="catalog">
        <html>
            <xsl:apply-templates />
        </html>
    </xsl:template>


    <xsl:template match="dataset">
<xsl:if test="not(dataset)"><!-- Otherwise, create the access link. -->

<!-- This Works, but it's hardwired for the same result every time: --> service: <xsl:value-of select="//service[(_at_)name='WCS']/ @base" /><br/>

            <!-- This does not. Is there a way to get there? -->
service: <xsl:value-of select="//service [(_at_)name='{serviceName}']/base" /><br/>

            <!-- And this is a nasty workaround -->
            <xsl:call-template name="accessURL">
<xsl:with-param name="serviceName"><xsl:value-of select="serviceName" /></xsl:with-param> <xsl:with-param name="urlPath"><xsl:value-of select="@urlPath" /></xsl:with-param> <xsl:with-param name="name"><xsl:value-of select="@name" /></xsl:with-param>
                <xsl:with-param name="suffix">html</xsl:with-param>
            </xsl:call-template><br/>

        </xsl:if>

    </xsl:template>


    <xsl:template name="accessURL">
        <xsl:param name="serviceName" />
        <xsl:param name="urlPath" />
        <xsl:param name="name" />
        <xsl:param name="suffix" />
        <xsl:for-each select="//service">
            <xsl:if test="@name = $serviceName">
<a href="{(_at_)base}{$urlPath}(_dot_){$suffix}" > <xsl:value- of select="$name" /></a>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>


    <xsl:template match="serviceName">
        <xsl:param name="indent" />
    </xsl:template>

</xsl:stylesheet>



============================================================
Nathan Potter                 Oregon State University, COAS



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


============================================================
Nathan Potter                 Oregon State University, COAS
ndp at coas.oregonstate.edu   104 Ocean. Admin. Bldg.
541 737 2293 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>