1

给定一个节点列表和该列表中的当前节点,有没有办法使用 javax.xml.xpath (或 org.apache.xpath 可能)来评估位置相关的 XPath 表达式,例如:

position()=last()-1

javax.xml.xpath 包含:

evaluate(String expression, Object item, QName returnType) 在指定的上下文中计算一个 XPath 表达式,并将结果作为指定的类型返回。

我想我可以创建一个临时节点,将节点列表中的节点添加为子节点,并将与当前节点对应的子节点作为上下文进行评估,但是(假设甚至可以)有更好的方法吗?

或者,在 XSLT 1.0 中,假设我将这三个东西(节点列表、节点和 xpath 表达式(作为字符串))作为变量。是否可以将此表达式应用于节点,使用节点列表作为上下文,并将结果作为变量获取?

4

3 回答 3

3

大多数 XPath API,当然还有 JAXP API,只允许您设置单例焦点,即您可以选择任何项目作为上下文项目的焦点,但上下文位置和大小固定为 1。

于 2012-07-12T16:01:39.723 回答
1

Xalan Java 支持http://www.exslt.org/dyn/functions/evaluate/index.html所以你应该可以使用例如

<xsl:variable name="nodes" select="/root/foo/bar"/>
<xsl:variable name="expression" select="concat('$nodes/', $yourPath)"/>
<xsl:variable name="result" select="dyn:evaluate($expression)"/>

xmlns:dyn="http://exslt.org/dynamic"当然有定义)。

这有帮助吗?我不确定我是否理解拥有节点列表和单个节点并希望将两者用作上下文的部分。

至于 Java 端并在 DOM NodeList 中找到最后一个节点之前的节点,还nodeList.getItem(nodeList.getLength() - 2)不够吗?

于 2012-07-12T14:28:17.727 回答
0

这篇 7 年前的帖子表明,可能有一个特定于 Xalan 的非 XSLT 解决方案可用,但实现独立性和 Michael 的回应将我推向了寻找基于 XSLT1 的有效解决方案的方向。

这里是; 我不确定它是否对其他人有用。我想知道是否有更简单的方法?

只要您正确设置了所有内容,您就可以依赖 XSLT。从规范:

在 XSLT 中,最外层的表达式(即不属于另一个表达式的表达式)按如下方式获取其上下文:

上下文节点来自当前节点

上下文位置来自当前节点在当前节点列表中的位置;第一个位置是 1

从最后开始,我得到将表达式 $expression 应用于变量 $result 的结果:

        <xsl:variable name="result" >
            <xsl:apply-templates select="$vNodeSet" mode="myeval">
                <xsl:with-param name="expression" ><xsl:value-of select="$expression"/></xsl:with-param>
                <xsl:with-param name="pos" ><xsl:value-of select="$pos"/></xsl:with-param>
            </xsl:apply-templates>
        </xsl:variable> 

apply-templates 将合适的“当前节点列表”推送到以下模板:

  <xsl:template match="*" mode="myeval">
    <xsl:param name="expression">1. </xsl:param>
    <xsl:param name="pos">3</xsl:param>

    <xsl:choose>
        <xsl:when test="position()=$pos">
            <xsl:value-of select="dyn:evaluate($expression)" /></xsl:when>
        <xsl:otherwise /> 
    </xsl:choose>

  </xsl:template>

此模板评估我想成为“当前节点”的节点的表达式。注意:

  1. dy:evaluate 的使用(感谢 Martin!)
  2. $pos 标识我想要的当前节点。

我能够使用Dimitre对较早问题的回答来计算 $pos;我还使用了他的变量名 vNodeSet

感谢 Dimitre、Martin 和 Michael!

于 2012-07-13T04:57:04.750 回答