Waruzjan
Waruzjan

Reputation: 79

VTD 2.13 finds the wrong node evaluating xpath with condition on node value

The following xpath finds a node while it shouldn't. This happens with VTD-xml java 2.12 and 2.13, while v2.11 works fine.

XML: <CONTACT><ID>10</ID></CONTACT> Xpath: //CONTACT[ID='1']/ID Result:10

Java unit test:

@Test
public void testXpath() throws Exception {
    String xml = "<CONTACT><ID>10</ID></CONTACT>";
    String expression = "//CONTACT[ID='1']/ID";

    VTDGen p = new VTDGen();
    p.setDoc(xml.getBytes("UTF-8"));
    p.parse(false);
    VTDNav nav = p.getNav();
    AutoPilot pilot = new AutoPilot(nav);
    pilot.selectXPath(expression);
    int evalXPath = pilot.evalXPath();

    if (evalXPath != -1) {
        String readValue = nav.toNormalizedString(nav.getText());
        Assert.assertEquals("10", readValue);
        Assert.fail("evalXpath should have returned -1, but returned " + evalXPath);
    }
}

When running the unit test above we get:

java.lang.AssertionError: evalXpath should have returned -1, but returned 2.

Does anyone know why this happens? Is this a known bug?

I have asked the question on the forum of VTD-xml, however noticed later a post that the questions can better be asked on StackOverflow, therefore the post here.


Edit 14-11-2016

In response to the comment below, please see the following test that fails with 2.11 (while it works with 2.9, 2.12 and 2.13)

@Test
public void testXmlModifier() throws Exception {
    String xml = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><CONTACT><ID>10</ID></CONTACT>";
    String expression = "//CONTACT[ID='10']";
    String replace = "<CONTACT><ID>11</ID></CONTACT>";

    VTDGen p = new VTDGen();
    p.setDoc(xml.getBytes("UTF-16"));
    p.parse(false);
    VTDNav nav = p.getNav();

    AutoPilot pilot = new AutoPilot(nav);
    pilot.selectXPath(expression);

    if (pilot.evalXPath() != -1) {
        XMLModifier xm = new XMLModifier(nav);
        xm.remove();
        xm.insertAfterElement(replace);

        /*
         * Following call results in IndexOutOfBoundsException
         *  at java.io.FileOutputStream.writeBytes(Native Method)
         *  at java.io.FileOutputStream.write(FileOutputStream.java:326)
         *  at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)
         *  at java.io.PrintStream.write(PrintStream.java:480)
         *  at com.ximpleware.XMLModifier.output(XMLModifier.java:2068)
         */
        xm.output(System.out);
    } else {
        Assert.fail("Should have found a node by " + expression);
    }
}

So I try to find the CONTACT with ID 10 and replace it with a new CONTACT node with ID 11. However, the call to xm.output results in IndexOutOfBoundsException.

Please do note that when changing the XML above to UTF-8, the code runs fine.

Also, while the code above actually replaces the root node (since CONTACT is the root node), this issue also exists when replacing just the subnode ID. So running the test with the following expression and replace value, gives exact the same error:

String expression = "//ID[text()='10']";
String replace = "<ID>11</ID>";

Upvotes: 2

Views: 393

Answers (1)

vtd-xml-author
vtd-xml-author

Reputation: 3377

If you have been using 2.13 version of vtd-xml.. there is a new version (2.13_1) available that solves a few reported bugs...

https://sourceforge.net/projects/vtd-xml/files/vtd-xml/ximpleware_2.13_1/ximpleware-2.13.1-java.zip/download

This is a bug that has been reported and fixed... Can you check out VTDNav.java from CVS repository and do a re-build?

Here is the link to it..

http://vtd-xml.cvs.sourceforge.net/viewvc/vtd-xml/ximple-dev/com/ximpleware/VTDNav.java?revision=1.146

Upvotes: 1

Related Questions