Выходная строка VTD-XML и Xpath 2.0

1

Когда я пытаюсь запустить следующее выражение xpath в Java, используя VTD-XML, я получаю непредвиденную ошибку.

Код:

..
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/a//b[text() = 'apple''banana']");

Ошибка:

Syntax error after or around the end of ==> /a//b[text() = 'apple'
Caused by: com.ximpleware.XPathParseException: XPath Syntax error: #29
    at com.ximpleware.xpath.parser.unrecovered_syntax_error(parser.java:492)
    at java_cup.runtime.lr_parser.parse(lr_parser.java:601)
    at com.ximpleware.AutoPilot.selectXPath(AutoPilot.java:809)

Это не ошибка? У меня создалось впечатление, что избежать одиночных кавычек в XPath 2.0 было приемлемым? Когда я пытаюсь запустить xpath-запрос в XML-шпионах с тем же документом, он работает нормально.

  • 0
    Моя обычная рекомендация для введения параметров в выражение XPath заключается в том, чтобы использовать средства, предоставляемые вашей библиотекой XPath, для установки переменных, а затем обращаться к переменным в выражении ( /a//b[. = $targetValue] ). Но VTD-XML позволяет вам задавать переменную только путем оценки другого выражения XPath, в отличие от всех других реализаций XPath, о которых я знаю, которые позволяют вам напрямую вводить строку или число Java в качестве значения переменной.
  • 0
    Я думаю, что обратная косая черта перед двойной кавычкой должна решить проблему.
Теги:
xpath
vtd-xml

3 ответа

0
Лучший ответ

К сожалению, похоже, что экранирование не является вариантом, мне пришлось написать пользовательскую функцию, основанную на следующем:

XQuery ищет текст с "одной" цитатой

Он был написан в javascript, поэтому я преобразовал его в Java:

private static String cleanStringForXPath(String dirtyString)
    {
        Pattern pattern = Pattern.compile("([^'\"]+|['\"])");
        Matcher matcher = pattern.matcher(dirtyString);

        int count = 0;
        StringBuilder sb = new StringBuilder();

        while(matcher.find()) {
            String part = matcher.group(1);
            if(part.equals("'")) {
                sb.append("\"'\"");
            } else if(part.equals("\"")) {
                sb.append("'\"'");
            } else { 
                sb.append("'" + part + "'");
            }
            sb.append(",");
            count++;
        }

    String result = sb.length() > 0 ? sb.substring(0, sb.length() - 1): "";
    return (count > 1) ? "concat(" + result + ")" : result;
}

Я протестировал эту функцию и, похоже, решил проблему.

1

Поскольку XPath также может поддерживать строки ".." которые могут содержать unescaped -s, вы можете просто использовать:

   ap.selectXPath("/a//b[text() = \"apple'banana\"]");
  • 0
    Если вы избегаете двойных кавычек, как это, то они, вероятно, считаются частью строки и ничего не разделяют.
  • 0
    @ MathiasMüller: Ofc они считаются частью строки. В этом все дело, строка становится выражением XPath
Показать ещё 3 комментария
0

Escaping - это вопрос, который полностью оставлен на языке хоста, который использует XPath для запроса данных. Правила экранирования этого языка более высокого уровня обычно также применяются к выражениям XPath, используемым в нем.

Я цитирую из Michael Kay XPath 2.0 Programmer Reference:

Аналогично, когда выражения XPath записываются в символьных строках на языке хоста, таком как Java, вам нужно будет использовать соглашения об экранировании этого языка: например, [...] кавычка как \".

Другими словами, '' исключает одну цитату в XSLT 2.0. В Java одиночная кавычка должна быть экранирована как \' я думаю".

ap.selectXPath("/a//b[text() = 'apple\'banana']");
  • 0
    Спасибо, я попробовал это без удачи. Теперь я получаю acom.ximpleware.XPathParseException: недопустимый символ в исключении XPath Expression.
  • 0
    @BigbyWolf Действительно ли одиночная кавычка действительно имеет отношение к уникальной идентификации элемента? Если вы показываете XML-файл, который запрашиваете, возможно, мы сможем найти другое выражение, которое возвращает тот же узел.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню