2
<xsl:variable name="map">
   <map>
        <item key="Name" value="John"/>
        <item key="Address" value="Un_Known"/>
        <item key="Phone" value="(878)876678"/>
        <item key="Last Name" value="Verner"/>
    </map>
</xsl:variable>

<xsl:for-each select "$map/map/item">
   <xsl:if test="./@key = $input">
      <!-- cool user is asking for something know .. do something fancy -->
   </xsl:if>
<xsl:for-each>

我想在我的 XSLT 中声明一个类似映射的结构,然后想要访问它。显然,我不想使用额外的名称空间,所以使用 exsl:node-set 不是我现在正在寻找的解决方案。

我正在使用 XSLT 1.0 Saxon。

有没有更好的方法来做我想做的事情?

谢谢卡勒菲尔


下面提到的所有答案都是正确和有效的。我们最终决定使用“exsl:node-set”

谢谢你的建议..

4

4 回答 4

2

If you are using Saxon, then it is very hard to see why you are still using XSLT 1.0. This kind of thing (and many other things) are much easier in XSLT 2.0 - it's time you moved forward.

于 2012-08-28T08:25:13.883 回答
1

你得到了三个非常好的答案。

这是另一个,它演示了如何使用键来访问查找表(在实际情况下,它会驻留在单独的 XML 文档中):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pInput" select="'Phone'"/>
   <my:map>
        <item key="Name" value="John"/>
        <item key="Address" value="Un_Known"/>
        <item key="Phone" value="(878)876678"/>
        <item key="Last Name" value="Verner"/>
    </my:map>

 <xsl:key name="kLookup" match="item/@value" use="../@key"/>

 <xsl:template match="/">
     <xsl:for-each select="document('')">
       <xsl:value-of select="key('kLookup', $pInput)"/>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当将此转换应用于任何 XML 文档(未使用)时,将产生所需的正确结果

(878)876678

在 XSLT 2.0 中xsl:for-each不需要,因为该key()函数接受指定要索引的文档的第三个参数:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pInput" select="'Phone'"/>
   <my:map>
        <item key="Name" value="John"/>
        <item key="Address" value="Un_Known"/>
        <item key="Phone" value="(878)876678"/>
        <item key="Last Name" value="Verner"/>
    </my:map>

 <xsl:key name="kLookup" match="item/@value" use="../@key"/>

 <xsl:template match="/">
       <xsl:value-of select="key('kLookup', $pInput, document(''))"/>
 </xsl:template>
</xsl:stylesheet>
于 2012-08-28T12:13:07.683 回答
1

如果您不想使用node-set()扩展功能,可以将<map>数据放在单独的 XML 文件中,例如map.xml. 然后使用document('map.xml'). 然后,您可以使用 XPath 表达式访问映射的内容,如上所示。

于 2012-08-27T19:28:24.653 回答
1

您可以包含额外的 XML 信息,例如<map>直接在 XSLT 中。该 XML 数据需要绑定到名称空间(XSLT 名称空间除外),但它可以是任何名称空间。

您可以通过使用document()带有空字符串的函数来访问 XSLT 中的数据,这将加载 XSLT 文档。

顺便说一句,您可以通过在您选择<xsl:if>的 XPath 上使用谓词过滤器来消除对 的需要。xsl:for-each

例如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"
    xmlns:my="http://stackoverflow.com/questions/12146687/creating-a-map-in-xlst">

    <xsl:param name="input" />

    <my:map >
        <item key="Name" value="John"/>
        <item key="Address" value="Un_Known"/>
        <item key="Phone" value="(878)876678"/>
        <item key="Last Name" value="Verner"/>
    </my:map>

    <xsl:template match="/">
        <xsl:for-each select="document('')/*/my:map/item[@key=$input]">
                <!-- cool user is asking for something know .. do something fancy -->
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
于 2012-08-28T01:50:43.783 回答