我们可以在 xslt 的 select 语句中使用动态变量名吗?

Posted

技术标签:

【中文标题】我们可以在 xslt 的 select 语句中使用动态变量名吗?【英文标题】:can we use dynamic variable name in the select statement in xslt? 【发布时间】:2011-05-24 03:39:16 【问题描述】:

我想在 xslt 的 select 语句中使用动态变量名。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
    <xsl:variable name="input" select="input/message" />
    <xsl:variable name="Name" select="'MyName'" />
    <xsl:variable name="Address" select="MyAddress" />
    <xsl:variable name="output" select="concat('$','$input')" />  <!-- This is not working -->
     <output>
       <xsl:value-of select="$output" />
     </output>
</xsl:template>

变量“输入”的可能值是“名称”或“地址”。 输出变量的 select 语句应该有一个基于输入变量值的动态变量名。我不想使用 xsl:choose。我想动态选择值。 请给我一个解决方案。

谢谢, 迪努

【问题讨论】:

好问题,+1。请参阅我的答案以获得完整而简短的解决方案。 :) 【参考方案1】:

XSLT 1.0 和 XSLT 2.0 没有动态评估。

您的问题的解决方案

这种转变

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output method="text"/>

 <my:values>
  <name>MyName</name>
  <address>MyAdress</address>
 </my:values>

 <xsl:template match="/">
  <xsl:variable name="vSelector"
   select="input/message"/>
  <xsl:value-of select=
   "document('')/*/my:values/*[name()=$vSelector]"/>
 </xsl:template>
</xsl:stylesheet>

应用于以下 XML 文档时

<input>
  <message>address</message>
</input>

产生想要的正确结果

MyAdress

当对这个 XML 文档应用相同的转换时

<input>
  <message>name</message>
</input>

再次产生所需的正确结果

MyName

最后:如果您不想使用document() 功能,但会使用xxx:node-set() 扩展功能,那么这个解决方案(看起来非常相似)就是您想要的,您可以在其中查阅 XSLTprocessor 文档以了解扩展的确切命名空间:

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

 <xsl:variable name="vValues">
  <name>MyName</name>
  <address>MyAdress</address>
 </xsl:variable>

 <xsl:template match="/">
  <xsl:variable name="vSelector"
   select="input/message"/>
  <xsl:value-of select=
   "ext:node-set($vValues)/*[name()=$vSelector]"/>
 </xsl:template>
</xsl:stylesheet>

【讨论】:

谢谢!它对我有用.. 只是想知道是否有任何替代方法而不使用额外的命名空间 xmlns:my="my:my" ? @dhinu:很高兴我的回答很有用。在 SO 通过接受答案表示感谢(通过单击答案旁边的复选标记):)。您可以将&lt;my:values&gt; 放在另一个文件中,然后使用document() 函数再次访问它。在 XSLT 1.0 中,您通常必须使用这种技术。如果元素在&lt;xsl:variable&gt;&lt;xsl:param&gt; 的主体中,则不能直接使用XPath 访问它们,需要先应用扩展函数(xxx:node-set())。在 XSLT 2.0 中,&lt;xsl:variable&gt;&lt;xsl:param&gt; 中的元素可以直接访问。 您能否提供一个使用扩展函数 (xxx:node-set()) 访问 xsl:variable 主体中元素的示例? (我使用 XSLT 1.0)【参考方案2】:

除了@Dimitre 的好答案,对于这种特殊情况(输出字符串值),您还可以使用:

<xsl:variable name="output" 
              select="concat(substring($Name, 1 div ($input = 'Name')),
                             substring($Address, 1 div ($input = 'Address')))"/>

【讨论】:

以上是关于我们可以在 xslt 的 select 语句中使用动态变量名吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 xslt 获取与复杂条件匹配的所有 xml 项的计数并在终止语句中使用它?

我们可以在不使用 select 语句的情况下选择表数据吗[关闭]

XSL 风格:在 XSLT 中使用 <xsl:for-each select> 或 <xsl:template match> 或其他解决方案?

在 XSLT 中,如何使用存在多个相同节点的 ID 从节点中选择一个值?

如何在 XSLT 1.0 中获取具有唯一数字的数字?

XSLT:将样式表包含在主样式表中