使用 xslt 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">
    * (<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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否尝试使用这些
preferences/pref
元素将数据放入样式表中?这些不应该位于单独的名称空间中吗?键是针对每个文档构建的,并且 XSLT 1.0 的key
函数会在上下文节点所属的文档中查找节点。如果您想查找样式表本身中的节点,那么您需要首先使用
。然后从match
属性值中删除前导/
并确保将元素放入单独命名空间中的容器元素中,例如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 thekey
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 thematch
attribute value and make sure you put the elements in a container element in a separate namespace e.g.其中任何一个都没有问题:
我无法重现报告的输出。这意味着,如果确实存在任何问题,问题也出在未向我们展示的代码中。
提供的转换:
应用于以下 XML 文档时(问题中未提供 XML 文档!):
产生完全预期的结果:
请注意:
以下所有 7 个 XSLT 处理器都会产生完全相同的(上述)结果:MSXML3/4、XslCompiledTransform、XslTransform、Saxon 6.5.4、Saxon 9.1.05,AltovaXML (XmlSPY)。
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:
when applied on the following XML document (no XML document was provided in the question!):
produces exactly the expected result:
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).