xslt 1.0 节点集错误,转换无效

Posted

技术标签:

【中文标题】xslt 1.0 节点集错误,转换无效【英文标题】:xslt 1.0 node-set error with Invalid conversion 【发布时间】:2021-08-08 02:16:23 【问题描述】:

我在 1.0 版本中遇到了 xslt 的问题。 我的节点是这样的

...
<Garage>
    <car>
       <color>red</color>
       <color>yellow</color>
       <wheel>left</wheel>
    <car/>
</Garage>
...

然后我将子节点保存到变量中

<xsl:variable name="entries">
    <xsl:if test="$element/Garage/car">
        <xsl:value-of select="$element/Garage/car"/>
    </xsl:if>
</xsl:variable>

当我在模板中使用这个变量时

    <xsl:template name="entriesToString">
        <xsl:param name="table"/>
        <xsl:for-each select="$table/color">
            <xsl:if test="position() = last()">
                <xsl:value-of select="concat(current(),'/')"/>
            </xsl:if>
            <xsl:value-of select="concat(current(),',')"/>
        </xsl:for-each>
    </xsl:template>

我收到这样的错误

ERROR:  'Invalid conversion from 'com.sun.org.apache.xalan.internal.xsltc.dom.SimpleResultTreeImpl' to 'node-set'.'

xslt中节点迭代有问题吗?

【问题讨论】:

显示一个最小但完整的示例,以便我们理解和重现错误。我担心在一个 sn-p 中使用$element 而不显示它是如何以及在哪里声明的,而第二个带有命名模板的 sn-p 在我们可以看到的代码中没有被调用并没有提供必要的细节。另一方面,XSLT 1 的一个已知限制是,您在 xsl:variable 元素内构造值而不是使用 select 属性的变量是一个结果树片段,您不能在其上使用任何 XPath步骤表达式。 请提供一个可重现的例子。您说您定义了一个名为$entries 的变量,但随后您向我们展示了尝试处理名为$table 的变量的代码。还有为什么xslt-2.0 标记,这与 XSLT 1.0 有关? 此外,xsl:value-of 不会选择子节点,它会创建一个文本节点。完全不清楚您要实现什么,我会首先考虑使用select 表达式从输入文档中选择节点,然后再构造结果树片段。如果您确实需要结果树片段并希望它包含您选择的元素节点(例如car),请使用xsl:copy-of,而不是xsl:value-of。但当然,如果您想使用 XPath 路径表达式,您将需要像 exsl:node-set 这样的扩展函数来将结果树片段转换为节点集。 在 Java 世界中,使用 Saxon 而不是 Xalan 很容易迁移到 XSLT 2 或 3。 【参考方案1】:

在 XSLT 1.0 中,xsl:value-of 指令创建一个文本节点,其值为所选节点集中第一个节点的string-value。 p>

在您的示例中,$entries 变量是一个 result-tree-fragment,其中包含文本 "red yellow left"(带有或不带有一些空白字符)。为了使用xsl:for-each 指令处理result-tree-fragment,您必须首先使用特定于处理器的扩展函数将其转换为节点集。无论如何,在这种情况下它对您没有任何好处,因为 - 如上所述 - 它包含一个 single 文本节点。

【讨论】:

【参考方案2】:

使用&lt;xsl:variable name="entries" select="$element/Garage/car"/&gt; 可能就足够了,这样您就可以在 XPath/XSLT 1 中拥有一个节点集,而无需使用扩展函数。如果路径$element/Garage/car 没有选择任何内容,则节点集为空,它包含来自$elementcar 元素节点(如果它们存在),即路径$element/Garage/car 选择了一些东西。

【讨论】:

以上是关于xslt 1.0 节点集错误,转换无效的主要内容,如果未能解决你的问题,请参考以下文章

XSLT 1.0 - 用 HTML 包装的多个子节点模板

使用 XSLT 过滤不包含节点的 XYZ

使用 XSLT 重命名节点

使用 XSLT 添加强制节点

XSL:在 XSL 1.0 中组合两个节点集

使用 xslt 将 xml 复杂节点元素拆分为多个节点