XSLT 1.0值查找地图

时间:2015-09-07 13:08:18

标签: xml xslt xslt-1.0 xslt-2.0

我是XSLT的新手,花了相当多的时间来创建一个内联查找地图,用XSLT 2.0中的映射列表的另一个值替换特定值,但却发现我只能使用1.0。 : - (

我的问题是如何在1.0中复制以下工作的XSLT 2.0代码。我尝试过一些东西,但似乎无法让它发挥作用。

请注意,如果没有地图,则该元素应为空。

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>


<xsl:variable name="mapxml" >
<map>
<Country>
    <input value="GB">RZ</input>
    <input value="FR">TH</input>
   </Country>
</map>
 </xsl:variable>


  <xsl:variable name="vMap" 
       select="$mapxml" />


 <xsl:key name="kInputByVal" match="input" 
   use="@value" />


    <xsl:template match="Country/text()">
        <xsl:sequence select= 
         "(key('kInputByVal', ., $vMap/*/Country)[1]/text()
           )[1]
         "/>

 </xsl:template>
</xsl:stylesheet>

输入XML:

 <user>
        <Country>GB</Country>
        <Name>FOO</Name>
        <Address>BAR</Address>
<user>

2 个答案:

答案 0 :(得分:3)

这是等效的XSLT 1.0程序:

<ul>

注意:

  • 您可以在XSLT中设置额外的节点,因为XSLT本身就是XML。例如,配置数据,如此处。您只需要确保为它们使用不同的命名空间。
  • 命名空间URI必须是唯一的,它们不需要指向现有文档。像<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://tempuri.org/dummy" exclude-result-prefixes="my" > <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*" /> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <my:config> <map> <Country> <input value="GB">RZ</input> <input value="FR">TH</input> </Country> </map> </my:config> <xsl:variable name="vCountryMap" select="document('')/*/my:config/map/Country/input" /> <xsl:template match="Country/text()"> <xsl:value-of select="$vCountryMap[@value = current()]" /> </xsl:template> </xsl:stylesheet> 这样的临时URI非常完美。
  • http://tempuri.org/dummy指示XSLT处理器忽略输入中无关紧要的空格。这有助于创建整齐的缩进输出。
  • <xsl:strip-space elements="*" />指的是XSLT样式表本身。如果您愿意,也可以将配置保存在额外的XML文件中。
  • document('')可以防止我们的临时命名空间泄漏到输出。
  • exclude-result-prefixes指的是XSLT处理器当前正在处理的节点。 (current()不起作用,因为$vCountryMap[@value = .]指的是XPath上下文,即.个节点。)

答案 1 :(得分:2)

XSLT 1.0中的密钥仅适用于当前文档。要使用键从样式表本身进行查找,必须在使用键之前将上下文切换到样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="input-by-value" match="input" use="@value" />

<my:map>
    <input value="GB">RZ</input>
    <input value="FR">TH</input>
</my:map>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Country/text()">
    <xsl:variable name="value" select="." />
    <!-- switch context to stylesheet in order to use key -->
    <xsl:for-each select="document('')">
        <xsl:value-of select="key('input-by-value', $value)"/>
    </xsl:for-each>
 </xsl:template>

</xsl:stylesheet>