1

When I try to running the following xpath expression in Java using VTD-XML I get an unexpected error.

Code:

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

Error:

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)

Is this not a bug? I was under the impression that escaping single quotes in XPath 2.0 was acceptable? When I try running the xpath query in XML Spy with the same document it runs fine.

4

3 回答 3

1

由于 XPath 还可以支持".."可以包含未转义 '-s 的字符串,因此您可以使用:

   ap.selectXPath("/a//b[text() = \"apple'banana\"]");
于 2014-08-28T15:57:06.080 回答
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;
}

我测试了这个功能,它似乎解决了我的问题。

于 2014-08-28T15:33:01.780 回答
0

转义是完全留给使用 XPath 查询数据的宿主语言的事情。该高级语言的转义规则通常也适用于其中使用的 XPath 表达式。

我引用 Michael Kay 的 XPath 2.0 Programmer's Reference:

类似地,当 XPath 表达式用宿主语言(如 Java)编写在字符串中时,您将需要使用该语言的转义约定:例如,[...] 引号 as \".

换句话说,'' 确实在 XSLT 2.0中转义了单引号。\'在 Java 中,我猜必须对单引号进行转义。

ap.selectXPath("/a//b[text() = 'apple\'banana']");
于 2014-08-27T20:15:09.753 回答