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

发布于 2024-11-05 22:24:10 字数 2922 浏览 1 评论 0原文

(经过编辑以包括 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>

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

预先感谢大家。

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温馨耳语 2024-11-12 22:24:10

您是否尝试使用这些 preferences/pref 元素将数据放入样式表中?这些不应该位于单独的名称空间中吗?键是针对每个文档构建的,并且 XSLT 1.0 的 key 函数会在上下文节点所属的文档中查找节点。如果您想查找样式表本身中的节点,那么您需要首先使用 。然后从 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>

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>
人间不值得 2024-11-12 22:24:10

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

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

我无法重现报告的输出。这意味着,如果确实存在任何问题,问题也出在未向我们展示的代码中。

提供的转换

<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">                  * (
                <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)。

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">                  * (
                <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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文