开发者

Problem using xslt key() function

(edited to include suggestions from Martin Honnen)

Hello All,

I've been trying to get the key function to work correctly in the stylesheet below.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date"
        xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:m="http://mapping.tables" >


<xsl:key name="preferences" match="preferences/preference" use="@code"/>

<xsl:template match="Reservation/Detail" >
    <xsl:for-each select="Preferences/Preference">
        <xsl:if test ="string-length(./PreferenceCode)>0">

            &#160;&#160;&#160;&#160;* (<xsl:value-of select="./PreferenceCode"/>)

            <xsl:choose>
                <xsl:when test="./PreferenceCode!='PETS'">

                    <xsl:call-template name="prefmap">
                            <xsl:with-param name="code" select="./PreferenceCode"/&g开发者_运维百科t;
                    </xsl:call-template>

                    <br/><br/>
                </xsl:when>
            </xsl:choose>
        </xsl:if>
    </xsl:for-each>
</xsl:template


<xsl:template name="prefmap">
        <xsl:param name="code"/>
        You got here (called template) with code <xsl:value-of select="$code"/>
              <xsl:for-each select="document('')">
        <xsl:value-of select="key('preferences',$code)"/>
    </xsl:for-each>
</xsl:template>

<m:Maps xmlns="">
<preferences>
        <preference code="ANT">
                Hypoallergenic Bedding
        </preference>
        <preference code="NSK">
                Non-smoking Room
        </preference>
        <preference code="SMK">
                Smoking Room
        </preference>
</preferences>
</m:Maps>

</xsl:stylesheet>

It takes a input (that I don't control) and produces this:

* (ANT) You got here (called template) with code ANT


* (EARLY) You got here (called template) with code EARLY


* (NSK) You got here (called template) with code NSK

When I was expecting:

* (ANT) You got here (called template) with code ANT
  Hypoallergenic Bedding

* (EARLY) You got here (called template) with code EARLY

* (NSK) You got here (called template) with code NSK
Non-smoking Room

I tried to include this snippet in the main template to debug, but it produced no output:

            <xsl:for-each select="key('preferences',./PreferenceCode)">
                <p>
                    Code: <xsl:value-of select="@code"/><br />
                    Description: <xsl:value-of select="."/>
                </p>
            </xsl:for-each>

Do I have a problem with my key definition or the way that I am trying to use it?

Thanks all in advance.


Are you trying to put data in your stylesheet with those preferences/pref elements? Shouldn't those be in a separate namespace? And keys are built per each document and the key function with XSLT 1.0 looks up nodes in the document the context node belongs to. If you want to look up nodes in the stylesheet itself then you need to change the context node first with e.g. <xsl:for-each select="document('')"><xsl:value-of select="key('preferences', $code)"/></xsl:for-each>. Then drop the leading / from the match attribute value and make sure you put the elements in a container element in a separate namespace e.g.

<xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date"
        xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:m="http://mapping.tables" 
        xmlns:data="http://example.com/data">


<xsl:key name="preferences" match="preferences/pref" use="@code"/>

<data:data xmlns="">
<preferences>
        <pref code="ANT">
                Hypoallergenic Bedding
        </pref>
        <pref code="NSK">
                Non-smoking Room
        </pref>
        <pref code="SMK">
                Smoking Room
        </pref>
</preferences>
</data:data>


Do I have a problem with my key definition or the way that I am trying to use it?

There is no problem with any of them:

I cannot reproduce the reported output. This means that if there really is any problem, it is in the code not shown to us.

The provided transformation:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:m="http://mapping.tables" >

    <xsl:key name="preferences" match="preferences/preference" use="@code"/>

    <xsl:template match="Reservation/Detail" >
        <xsl:for-each select="Preferences/Preference">
            <xsl:if test ="string-length(./PreferenceCode)>0">              &#160;&#160;&#160;&#160;* (
                <xsl:value-of select="./PreferenceCode"/>)              
                <xsl:choose>
                    <xsl:when test="./PreferenceCode!='PETS'">
                        <xsl:call-template name="prefmap">
                            <xsl:with-param name="code" select="./PreferenceCode"/>
                        </xsl:call-template>
                        <br/>
                        <br/>
                    </xsl:when>
                </xsl:choose>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="prefmap">
        <xsl:param name="code"/>         You got here (called template) with code 
        <xsl:value-of select="$code"/>
        <xsl:for-each select="document('')">
            <xsl:value-of select="key('preferences',$code)"/>
        </xsl:for-each>
    </xsl:template>
    <m:Maps xmlns="">
        <preferences>
            <preference code="ANT">
              Hypoallergenic Bedding
            </preference>
            <preference code="NSK">
             Non-smoking Room
            </preference>
            <preference code="SMK">
             Smoking Room
            </preference>
        </preferences>
    </m:Maps>
</xsl:stylesheet>

when applied on the following XML document (no XML document was provided in the question!):

<Reservation>
    <Detail>
        <Preferences>
            <Preference>
              <PreferenceCode>ANT</PreferenceCode>
            </Preference>
            <Preference>
              <PreferenceCode>NSK</PreferenceCode>
            </Preference>
            <Preference>
              <PreferenceCode>SMK</PreferenceCode>
            </Preference>
            <Preference>
              <PreferenceCode>PETS</PreferenceCode>
            </Preference>
        </Preferences>
    </Detail>
</Reservation>

produces exactly the expected result:

<?xml version="1.0" encoding="utf-8"?>
                      * (
                ANT)              
                         You got here (called template) with code 
        ANT
              Hypoallergenic Bedding
            <br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/><br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/>                  * (
                NSK)              
                         You got here (called template) with code 
        NSK
             Non-smoking Room
            <br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/><br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/>                  * (
                SMK)              
                         You got here (called template) with code 
        SMK
             Smoking Room
            <br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/><br xmlns="http://www.w3.org/1999/xhtml" xmlns:date="http://www.oracle.com/XSL/Transform/java/java.util.Date" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:m="http://mapping.tables"/>                  * (
                PETS)              

Do Note:

All the following 7 XSLT processors produce exactly the same (above) result: MSXML3/4, XslCompiledTransform, XslTransform, Saxon 6.5.4, Saxon 9.1.05, AltovaXML (XmlSPY).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜