无法从XRTreeFrag转换为XNodeSet

时间:2012-07-18 20:39:52

标签: xslt param node-set

我有以下测试代码...我试图将节点集作为参数传递。几个小时后,我终于能够将它传递给我的模板。

我如何将节点集传递给模板:

<xsl:call-template name="listing">
    <xsl:with-param name="customData">
        <xsl:apply-templates select="exslt:node-set($data)"/>
    </xsl:with-param>
</xsl:call-template>

我的模板如何收到它:

<xsl:template name="listing">
    <xsl:param name="customData" select="/.."/>
    <xsl:variable name="data">
        <xsl:choose>
            <xsl:when test="not($customData)">
                <xsl:value-of select="/data"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$customData"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <textarea><xsl:copy-of select="$data"></xsl:copy-of></textarea>
</xsl:call-template>

如果我用一个衬垫设置参数,那么就不会抱怨......例如:

<xsl:variable name="data" select="$customData"/>

但是一旦我尝试这样设置它就会破坏:

<xsl:variable name="data">
   <xsl:value-of select="$customData"/>
</xsl:variable>

获取此错误消息: org.apache.xpath.objects.XRTreeFrag无法强制转换为org.apache.xpath.objects.XNodeSet

我只能找到另一个可追溯到2000年的线程,谈论这个类似的问题......我需要使用像node-set($ customData)/ *之类的东西重新节点化它,但我试过了,这是不行的。

修改 好的,我可以确认我已成功通过模板中的节点集。但我仍然无法将其复制到我的变量......它一直说它仍然是RTF。

<xsl:template name="listing">
<xsl:param name="customData" as="node-set"/>
<!--<xsl:variable name="data" select="/data"/>-->

<xsl:variable name="data">
    <xsl:choose>
        <xsl:when test="count($customData) != 0">
            <xsl:copy-of select="$customData"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="/data"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

    <textarea><xsl:value-of select="$customData/record[1]"/></textarea>
    <textarea><xsl:value-of select="/data/record[1]"/></textarea>
    <textarea><xsl:value-of select="$data/record[1]"/></textarea>
</xsl:template>

上面的测试表明,我可以毫无问题地访问$ customData和原始/数据,它们都显示记录......但是$ data被搞砸了。这意味着从$ customData到$ data的副本无效...

我尝试了以下方法,但没有一种方法有效:

<xsl:copy-of select="$customData"/>
<xsl:value-of select="$customData"/>
<xsl:apply-templates select="exslt:node-set($customData)"/>
<xsl:apply-templates select="exslt:node-set($customData)/data"/>

任何想法......?

3 个答案:

答案 0 :(得分:4)

此错误消息来自Xalan,它是一个XSLT 1.0处理器。如果您正在使用Xalan,那么您可能正在使用Java,这意味着根本没有理由不以Saxon的形式转移到XSLT 2.0。您会发现XSLT 2.0消除了XSLT 1.0的许多限制,其中这是最令人恼火的。

如果有充分的理由不能继续使用XSLT 2.0(并且很难想到),那么exslt:node-set()函数的形式有一种解决方法,它可以转换结果 - 树片段(即使用子指令定义的变量)到文档节点中。

答案 1 :(得分:2)

让它工作,基本上而不是使用apply-template,我需要将RTF作为参数传递给模板。这是我让它发挥作用的唯一方式。

<xsl:with-param name="data" select="exslt:node-set($customData)"/>

使用此方法,我能够在XSL级别中 MODIFY 数据。这真的很酷,我基本上操纵我想要的数据,然后我重建root /,然后我将我的customData传递给我的模板函数。

因此,我不是从根读取数据,而是读取自己的修改数据(在XSL中构建)。

答案 2 :(得分:1)

使用 exslt:node-set 确实会阻止错误消息 org.apache.xpath.objects.XRTreeFrag无法强制转换为org.apache.xpath.objects.XNodeSet

但是,由于某种原因创建的节点集不能在后续的XPath表达式中使用;至少它似乎不适用于Xalan 2.6.0 / XSLT 1.0,这是许多人因某种原因被迫使用的版本。

有一个简单的解决方案:不是将变量设置为节点集,而是将其设置为XPath表达式。然后你可以使用dyn:evaluate EXSLT函数来计算变量所持有的XPath表达式。

您的代码看起来像这样:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dyn="http://exslt.org/dynamic"
                extension-element-prefixes="dyn"
                exclude-result-prefixes="dyn">

...

    <xsl:variable name="data">
        <xsl:choose>
            <xsl:when test="count(.) != 0">
                <xsl:text>.</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>/data</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <textarea>
         <xsl:value-of select="dyn:evaluate($data)/record[1]"/>
    </textarea>