dyn:在<xsl:for-each>中的evaluate()产生奇怪的结果</xsl:for-each>

时间:2014-09-02 11:42:11

标签: xslt xalan

考虑以下XSL转换:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:exsl="http://exslt.org/common"
           xmlns:dyn="http://exslt.org/dynamic"
           extension-element-prefixes="dyn">
    <xsl:variable name="_raw">
        <test>1</test>
        <test>2</test>
    </xsl:variable>
    <xsl:variable name="list" select="exsl:node-set($_raw)"/>

    <xsl:template match="/">
        <result>
            <xsl:for-each select="$list/test">
                <loop>
                    <xsl:value-of select="dyn:evaluate('exsl:node-set($list)/test')"/>
                </loop>
            </xsl:for-each>
        </result>
    </xsl:template>
</xsl:transform>

在任何输入上执行此操作会给出:

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:exsl="http://exslt.org/common">
    <loop>1</loop>
    <loop/>
</result>

我不明白的是:

  • 如果我想在XPath字符串中引用esxl:note-set(),则dyn:evaluate()$list是必需的。否则,第一个<loop>也是空的。为什么? $list已经是一个节点集。
  • 两次执行的代码完全相同。为什么第二次没有结果呢?
  • 如果我不从$list获取值,而是从XML输入中获取值,则此方法有效。差异在哪里?
  • 如果我删除了<xsl:for-each>,则dyn:evaluate()无法使用exsl:node-set()。为什么?在评估的表达式中没有引用上下文,它应该没有区别。

我的XSLT处理器是Xalan 2.7.2。

1 个答案:

答案 0 :(得分:0)

我相信你想要做的是:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:exsl="http://exslt.org/common"
           xmlns:dyn="http://exslt.org/dynamic"
           extension-element-prefixes="exsl dyn">
    <xsl:variable name="_raw">
        <test>1</test>
        <test>2</test>
    </xsl:variable>
    <xsl:variable name="list" select="exsl:node-set($_raw)"/>

    <xsl:template match="/">
        <result>
            <xsl:for-each select="$list/test">
                <loop>
                    <xsl:value-of select="dyn:evaluate(.)"/>
                </loop>
            </xsl:for-each>
        </result>
    </xsl:template>
</xsl:transform>

这将导致:

<?xml version="1.0" encoding="UTF-8"?>
<result><loop>1</loop><loop>2</loop></result>

编辑:

我仍然不确定你在这之后是什么,但让我指出一些细节:

  

两次执行的代码完全相同。为什么没有结果   第二次?

这可能是Xalan中的一个错误。如果使用libxslt运行代码,结果将是:

<?xml version="1.0"?>
<result xmlns:exsl="http://exslt.org/common"><loop>1</loop><loop>1</loop></result>
  

如果我愿意,dyn:evaluate()中的esxl:note-set()是必要的   在XPath字符串中引用$ list。否则,第一个是   也空了。为什么? $ list已经是一个节点集。

我认为没必要。或许我不明白 的必要性。无论如何,改变这个:

<loop>
    <xsl:value-of select="dyn:evaluate('exsl:node-set($list)/test')"/>
</loop>

为:

<loop>
    <xsl:value-of select="dyn:evaluate('$list/test')"/>
</loop>

将导致:

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:exsl="http://exslt.org/common"><loop>1</loop><loop>1</loop></result>

这次Xalan和libxslt的结果相同。