XPath 2.0 中的 Reverse() 函数:如何使用它来评估表达式?

3

请对我温柔一点,这是我第一次使用 XPath 2.0 :)

给定以下代码:

import net.sf.saxon.expr.Expression;
import net.sf.saxon.expr.StaticContext;
import net.sf.saxon.functions.CompileTimeFunction;
import net.sf.saxon.sort.Reverser;
import net.sf.saxon.trans.XPathException;

public class MyReverse extends CompileTimeFunction {

    public Expression simplify(StaticContext env) throws XPathException {
        Reverser a = new Reverser(argument[0]);
        return a.simplify(env);
    }

}

我想反转查询:

String query = "inventory/book/chapter[3]/preceding-sibling::chapter//title";
Object myQuery= xpath.evaluate(query,doc,XPathConstants.NODESET);

针对我的XML文件(如果需要,我可以附上XML文件,请告知是否需要!

据我理解,如果我这样做:

MyReverse rev = new MyReverse();

如果我想要使用方法evaluateAsString,像这样:rev.evaluateAsString(arg0),那么arg0应该是一个XPathContext对象。

我该如何使用上述方法来查询?

谢谢。

编辑1:

在尊敬的@Dimitre Novatchev先生编写的示例中,需要的是从节点X到文档的上方的所有节点。

然而,如果X的其中一个兄弟有子元素,则我需要呈现兄弟节点,然后才是他(兄弟节点)的子元素(然后继续移动到下一个兄弟,以此类推),而不是兄弟节点的子元素,仅然后是兄弟节点。

非常抱歉之前没有提及和解释这一点。

再次感谢 :)


1
XPath 2.0有一个reverse函数,所以你可以使用XPath表达式级别来解决这个问题,例如reverse(inventory/book/chapter[3]/preceding-sibling::chapter//title) - undefined
@MartinHonnen: 我知道,但我想在函数的层面上做到这一点,这可能吗? - undefined
2
@ron:抱歉,我不理解你在编辑中说的内容。逆序 的意思是:根据定义 reverse(n1,n2n, nM) = (nM, n(M-1), ...n2, n1)。你想要按照文档的相反顺序选择节点 - 当在选定的节点集上应用 reverse() 函数时,这就是结果。如果你现在想要其他的,请提一个新问题。 - undefined
2
@ron:我希望你在你的新问题中解释一下。而且,请不要使用“反转”这个词,因为它的意思与你想要的不同。晚安。 - undefined
2
好的,我想你想要的是:reverse(/inventory/book/chapter[3]/preceding-sibling::chapter)//title - undefined
显示剩余2条评论
2个回答

3

请评估此XPath 2.0表达式:

reverse(/inventory/book/chapter[3]/preceding-sibling::chapter//title)

这里是基于 XSLT 的验证:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:sequence select=
     "reverse(/inventory/book/chapter[3]/preceding-sibling::chapter//title)
     "/>
 </xsl:template>
</xsl:stylesheet>

当应用此转换时,以下XML文档(取自您之前的问题)将被转换:
<inventory>
    <book num="myBook1">
        <title>Lindsy Boxer</title>
        <author>James Patterson</author>
        <publisher>LittleBig</publisher>
        <price>18.21</price>
        <chapter>
            <title>Alex Cross Is Back - Chapter A</title>
            <paragraph>
                    This is the 
                <emph>first</emph> paragraph.
                <image file="alexCrossImage.gif"/>
                    afetr image...
            </paragraph>
            <paragraph>
                    This is the 
                <emph>second</emph> paragraph.
                <image file="alexCrossImageAnother.gif"/>
                    afetr image...
            </paragraph>
        </chapter>
        <chapter>
            <title>Along Came A Spider - Chapter B</title>
            <section>
                <title>Along Came A Spider - Chapter B - section 1</title>
                <paragraph>
                        This is the 
                    <emph>first</emph>paragraph for chapter TWO section ONE.
                    <image file="Chapter_B_firstParagraphImage.gif"/>
                        afetr image...
                </paragraph>
                <paragraph>
                        This is the 
                    <emph>second</emph> paragraph for chapter TWO section ONE.
                    <image file="Chapter_B_secondParagraphImage.gif"/>
                        afetr image...
                </paragraph>
            </section>
        </chapter>
        <chapter>
            <title>Chapter C</title>
            <paragraph>
                    This chapter has no images and only one paragraph
            </paragraph>
        </chapter>
    </book>
    <book num="myBook2">
        <title>Jack Reacher Series</title>
        <author>Lee Child</author>
        <author>Jonny White</author>
        <publisher>Pocket</publisher>
        <price>5.99</price>
        <chapter>
            <title>Jack Reacher - Chapter ONE</title>
        </chapter>
        <chapter>
            <title>Jack Reacher - Chapter TWO</title>
            <paragraph>
                    This is the 
                <emph>second</emph> paragraph of SECOND book chapter TWO.
                <image file="Jack_Reacher_Picture_Top_Sniper_US_Army.gif"/>
                    afetr image...
            </paragraph>
        </chapter>
    </book>
    <book num="myBook3">
        <title>Alex Cross - Double Cross</title>
        <author>James Patterson</author>
        <publisher>Spectra</publisher>
        <price>17.30</price>
        <chapter>
            <title>Alex Cross - Double Cross - Chapter A</title>
        </chapter>
    </book>
</inventory>

上述XPath表达式被评估,结果节点序列被复制到输出中。
<title>Along Came A Spider - Chapter B - section 1</title>
<title>Along Came A Spider - Chapter B</title>
<title>Alex Cross Is Back - Chapter A</title>

我们可以看到,该序列包含所需的元素,并按照相反的文档顺序排列 - 正如所请求的那样。
至于如何使用Saxon 9.x评估XPath表达式,请阅读相应的文档:http://www.saxonica.com/documentation/xpath-api/s9api-xpath.xml,其中有一个指向完全工作示例的指针。
更新:
在评论中,OP表示他需要逆文档顺序的元素,但是它们的标题元素按文档顺序排列。
要实现这一点,请使用:
reverse(/inventory/book/chapter[3]/preceding-sibling::chapter)//title

链接已损坏,你可能有其他的替代方案吗?谢谢! - undefined
@ron:我可以正常访问链接。显然,你的网络连接有问题。 - undefined
我一开始没有注意到,但是"reverse"函数并不能做到所需的功能。请查看您的输出,并将其与所请求的输出进行比较(这是请求的输出):" * <title>Along Came A Spider - Chapter B</title> * <title>Along Came A Spider - Chapter B - section 1</title> * <title>Alex Cross Is Back - Chapter A</title>"... 正如您所见,对于前两个条目,第一行应该是第二行(第二行应该是第一行).... - undefined
@ron:在你的问题中,你没有明确说明什么是“requested”(被请求的)。你只是说:“我想反转查询”。现在,对我来说,这意味着你想以相反的顺序获取所选元素的序列。而reverse()函数恰好可以实现这一点。如果你需要其他顺序,那么你必须编辑问题,删除“reverse”这个词,并准确说明新的顺序是什么。或者更好的是,重新提一个问题,并且这次更加关注你所说的内容。 - undefined
@ron:我根据你的新要求更新了这个答案,并添加了一个XPath表达式来选择元素。 - undefined

1

你正在摆弄内部Saxon实现类,这些类你不需要使用,而且显然你也不理解。你应该在XPath表达式中完成你想要的工作(反转一组节点的顺序),而不是在调用Java代码中完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接