在xsl:apply-templates中使用XSL变量作为Xpath值

时间:2017-04-10 20:10:49

标签: xml xslt xpath

我正在尝试将节点的内容用作Xpath引用。不幸的是,到目前为止我还没有找到实现这一目标的方法。

所以这里是我尝试处理的XML类型的一个小例子:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <a>
    <b name="1">
      <e>value1</e>
    </b>
    <b name="2">
      <e>value2</e>
    </b>
  </a>
  <c>
    <d name="3">
      <ref>/root/a/b[@name = "1"]</ref>
    </d>
    <d name="4">
      <ref>/root/a/b[@name = "2"]</ref>
    </d>
  </c>
</root>

在那里,<ref>节点包含一些包含所需值的文件内节点的Xpath。

以下是我试图整理处理此文件的XSL文件的类型:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="root/c/d"/>
  </xsl:template>

  <xsl:template match="d">
    <xsl:variable name="var1" select="ref/text()"/>
    for node <xsl:value-of select="@name"/>
    <xsl:apply-templates select="$var1"/>
  </xsl:template>

  <xsl:template match="b">
   value = <xsl:value-of select="e"/>
  </xsl:template>

</xsl:stylesheet>

但是当我使用提议的XSL处理上述XML文件时,我得到以下结果:

for node 3/root/a/b[@name = "1"]
for node 4/root/a/b[@name = "2"]

显然,$ var1的内容不会被评估为有效的xpath。

注意:如果我用/ root / a / b替换$ var1 [@name =&#34; 1&#34;]我得到了

    for node 3
   value = value1
    for node 4
   value = value1

哪个更接近我想要的,但节点4显然不再指向value2节点了。

我错过了什么?

这可以用XSL吗?

&#34; dyanmic评估&#34;是否存在问题?我应该使用其他方法(如xsl:function或xsl:call-template)?

谢谢你的帮助。

解决方案:

根据&#34; Daniel Haley&#34;使用dyn:evaluate确实可以解决问题。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                            xmlns:dyn="http://exslt.org/dynamic"
                            version="1.0"
                            extension-element-prefixes="dyn">

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="root/c/d"/>
  </xsl:template>

  <xsl:template match="d"><xsl:variable name="var1" select="ref/text()"/>
    for node <xsl:value-of select="@name"/>
    <xsl:apply-templates select="dyn:evaluate($var1)"/>
  </xsl:template>

  <xsl:template match="b">
   value = <xsl:value-of select="e"/>
  </xsl:template>

</xsl:stylesheet>

使用xsltproc和这个XSL样式表确实产生了预期的结果。

$ xsltproc ./file.xsl ./file.xml 

    for node 3
   value = value1
    for node 4
   value = value2
$

我还没有研究过xsl:evaluate方法。

再次感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以在XSLT 3.0中使用xsl:evaluate(前提是您的处理器支持它)。

您还可以使用dyn:evaluate EXSLT扩展功能(再次,只要您的处理器支持它)。