1

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

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

<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 ,它们都显示了记录......但是 $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"/>

任何的想法...?

4

3 回答 3

4

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

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

于 2012-07-18T23:07:49.957 回答
2

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

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

使用这种方法,我能够在 XSL 级别修改数据。这真的很酷,我基本上操作我想要的数据,然后我重建根 /,然后我将我的 customData 传递给我的模板函数。

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

于 2012-08-03T14:22:52.470 回答
1

使用exslt:node-set确实会抑制错误消息org.apache.xpath.objects.XRTreeFrag cannot be cast to 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>
于 2013-10-01T07:25:53.260 回答