【问题标题】:Dynamic Variables in XSLTXSLT 中的动态变量
【发布时间】:2009-01-15 10:56:05
【问题描述】:

我将一组键值对作为参数传递给 XSL(日期 -> “1 月 20 日”,作者 -> “Dominic Rodger”,...)。

这些在我正在解析的一些 XML 中被引用 - XML 看起来像这样:

<element datasource="date" />

目前,我不知道如何将 1 月 20 日排除在外,除非有一个可怕的 &lt;xsl:choose&gt; 声明:

<xsl:template match="element">
  <xsl:choose>
    <xsl:when test="@datasource = 'author'">
      <xsl:value-of select="$author" />
    </xsl:when>
    <xsl:when test="@datasource = 'date'">
      <xsl:value-of select="$date" />
    </xsl:when> 
    ...
  </xsl:choose>
</xsl:template>

我想使用类似的东西:

<xsl:template match="element">
  <xsl:value-of select="${@datasource}" />
</xsl:template>

但我怀疑这是不可能的。我开始使用外部函数调用,但希望避免在我的 XSL 中枚举所有可能的映射键。有什么想法吗?

谢谢,

Dom

【问题讨论】:

  • 请注意,在提供的三个答案中,有两个是不正确的——XPath 中没有字符串的“+”运算符,而且,不能为“指定 AVT” XSLT 中的“选择”属性。我的解决方案已经过测试并且有效。

标签: xslt libxml2


【解决方案1】:

这是一种可能的解决方案,但是我建议将所有参数分组到一个单独的 XML 文件中,并使用 document() 函数访问它们:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 exclude-result-prefixes="ext"
 >
 <xsl:output method="text"/>

 <xsl:param name="date" select="'01-15-2009'"/>
 <xsl:param name="author" select="'Dominic Rodger'"/>
 <xsl:param name="place" select="'Hawaii'"/>
 <xsl:param name="time" select="'midnight'"/>

 <xsl:variable name="vrtfParams">
   <date><xsl:value-of select="$date"/></date>
   <author><xsl:value-of select="$author"/></author>
   <place><xsl:value-of select="$place"/></place>
   <time><xsl:value-of select="$time"/></time>
 </xsl:variable>

 <xsl:variable name="vParams" select="ext:node-set($vrtfParams)"/>

    <xsl:template match="element">
      <xsl:value-of select=
       "concat('&#xA;', @datasource, ' = ',
               $vParams/*[name() = current()/@datasource]
               )"
       />
    </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时

<data>
  <element datasource="date" />
  <element datasource="place" />
</data>

产生正确的结果

日期 = 01-15-2009

地方 = 夏威夷

请注意使用xxx:node-set() 函数(此处使用the EXSLT one)将RTF (Result Tree Fragment) 转换为常规xml 文档(临时树)。

【讨论】:

    【解决方案2】:

    如果您的@datasource 始终与参数名称匹配,您可以尝试“评估”功能。注意:此代码未经测试。

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:exslt-dynamic="http://exslt.org/dynamic"
    >
    
    <xsl:param name="date"/>
    
    <xsl:template match="element">
      <xsl:value-of select="exslt-dynamic:evaluate('$' + @datasource)"/>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 确实是未经测试的。在 XPath 中,不能对 ('+') 字符串求和——这甚至永远无法编译。
    【解决方案3】:

    怎么样

    <xsl:template match="date-element">
      <xsl:text>${date}</xsl:text>
    </xsl:template>
    

    即而不是使用属性,而是使用不同的元素名称进行匹配。

    如果您无法更改源 XML,请通过一个小型 XSLT 运行它,该 XSLT 将属性转换为正确的元素名称。

    另一种解决方案是将 xsl:param 元素放入不同的 XML 文档中(或尝试让 XSLT 模板再次读取自身)。然后你可以使用 xsl:key 和 key() 来引用它们。

    [编辑] 将 xsl:value-of 替换为 xsl:text。我手边没有 XSLT 实用程序,所以我无法对此进行测试。如果这也不起作用,请发表评论。

    【讨论】:

    • 抱歉,“select”属性是唯一不能指定 AVT(Attribute-value-templates)的属性。
    猜你喜欢
    • 2011-01-16
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 2018-01-07
    • 2011-05-24
    相关资源
    最近更新 更多