wvdz
wvdz

Reputation: 16641

How to query a query result in Saxon xquery

I'm trying to do a basic thing in Saxon HE 9.7 with xquery. I have an xquery that returns a set of elements. Then I want to query each element separately. But I can't seem to figure out how to do a query on just that element. I thought setContextItem() would do the trick, but that doesn't work.

I've created a simple example that illustrates my problem. I am looping over <element> and then I want to retrieve the <name> for each element. But my query returns nothing, because it is actually querying the complete xml, not just the element. If I change the inner query to //name it returns all name tags in the document.

File data/example.xml:

<root>
    <element>
        <name>1</name>
    </element>
    <element>
        <name>2</name>
    </element>
</root>

Java code:

public static void main(String[] args) throws SaxonApiException
{
    Processor proc = new Processor(false);
    XPathCompiler xpath = proc.newXPathCompiler();
    DocumentBuilder builder = proc.newDocumentBuilder();
    XdmNode rootNode = builder.build(new File("data/example.xml"));
    String xquery = "/root/element";
    XPathSelector selector = xpath.compile(xquery).load();
    selector.setContextItem(rootNode);
    for (XdmItem item : selector)
    {
        xquery = "/element/name";
        XPathSelector selector2 = xpath.compile(xquery).load();
        selector2.setContextItem(item);
        System.out.println("item=" + item);
        if (selector2.iterator().hasNext())
            System.out.println("name=" + selector2.iterator().next());
        else
            System.out.println("Not found");
    }
}

My Maven dependency:

<dependency>
    <groupId>net.sf.saxon</groupId>
    <artifactId>Saxon-HE</artifactId>
    <version>9.7.0-4</version>
</dependency>

Result:

item=<element>
        <name>1</name>
    </element>
Not found
item=<element>
        <name>2</name>
    </element>
Not found

Upvotes: 1

Views: 373

Answers (1)

har07
har07

Reputation: 89285

In XPath, / at the beginning always references the document node. If you want your XPath (the one inside the loop) to respect context element, try to make it starts with a full-stop (.) :

xquery = "./name";

Or just remove the / completely * :

xquery = "name";

*) this will work for your case because child:: is the default axis which will be used if none is explicitly mentioned

Upvotes: 3

Related Questions