使用xslt key()函数时出现问题

时间:2011-05-08 13:26:05

标签: xml xslt indexing key

(编辑以包括Martin Honnen的建议)

大家好,

我一直在尝试让关键功能在下面的样式表中正常工作。

<?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"/>
                    </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>

需要一个输入(我无法控制)并产生这个:

* (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

我期待的时候:

* (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

我尝试将此代码段包含在主模板中进行调试,但它没有产生任何输出:

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

我的密钥定义或我尝试使用它的方式有问题吗?

提前全部谢谢。

2 个答案:

答案 0 :(得分:1)

您是否尝试使用这些preferences/pref元素将数据放入样式表中?那些不应该在一个单独的命名空间中?并且每个文档都构建了密钥,并且带有XSLT 1.0的key函数在上下文节点所属的文档中查找节点。如果要在样式表本身中查找节点,则需要首先更改上下文节点,例如<xsl:for-each select="document('')"><xsl:value-of select="key('preferences', $code)"/></xsl:for-each>。然后从/属性值中删除前导match,并确保将元素放在单独的名称空间中的容器元素中。

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

答案 1 :(得分:0)

  

我的钥匙有问题吗?   定义或我正在尝试的方式   使用它?

其中任何一个都没有问题:

我无法重现报告的输出。这意味着如果确实存在任何问题,则代码中没有显示给我们。

提供的转化

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

应用于以下XML文档时(问题中未提供XML文档!):

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

产生完全预期的结果

<?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)              

请注意:

以下所有7个XSLT处理器产生的结果完全相同(上图):MSXML3 / 4,XslCompiledTransform,XslTransform,Saxon 6.5.4,Saxon 9.1.05,AltovaXML(XmlSPY)。