Следующий xpath находит узел, пока он не должен. Это происходит с VTD-xml java 2.12 и 2.13, а v2.11 работает нормально.VTD 2.13 обнаруживает неправильный узел, оценивающий xpath с условием на значение узла
XML: <CONTACT><ID>10</ID></CONTACT>
Xpath: //CONTACT[ID='1']/ID
Результат: 10
модульного тестирования Java:
@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);
}
}
При выполнении теста на блок выше, мы получаем:
java.lang.AssertionError: evalXpath should have returned -1, but returned 2.
Кто-нибудь знает, почему Бывает? Это известная ошибка?
Я задал вопрос на форуме VTD-xml, однако позже заметил сообщение о том, что вопросы можно задать на StackOverflow, поэтому сообщение здесь.
Редактировать 14-11-2016
В ответ на комментарий ниже, смотрите следующий тест, который не с 2.11 (в то время как она работает с 2.9, 2.12 и 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);
}
}
Итак, я пытаюсь найти КОНТАКТ с ID 10 и заменить его новым контактным узлом с ID 11. Однако вызов xm.output
приводит к IndexOutOfBoundsException
.
Обратите внимание, что при изменении XML-кода выше в UTF-8 код работает нормально.
Кроме того, в то время как код выше фактически заменяет корневой узел (поскольку CONTACT является корневым узлом), эта проблема также существует при замене только идентификатора субнода. Так работает тест следующим текстом expression
и replace value
, дает точную и ту же ошибку:
String expression = "//ID[text()='10']";
String replace = "<ID>11</ID>";
Это известная ошибка, которая относится к UTF-16 вставки, мода и обновления. http://vtd-xml.cvs.sourceforge.net/viewvc/vtd-xml/ximple-dev/com/ximpleware/XMLModifier.java?view=log –
ОК, новая версия завершена, а URL-адрес последней банке размещен ниже –