【问题标题】:VTD-XML and Xpath 2.0 escaping stringVTD-XML 和 Xpath 2.0 转义字符串
【发布时间】:2014-08-28 23:57:06
【问题描述】:

当我尝试使用 VTD-XML 在 Java 中运行以下 xpath 表达式时,我收到了一个意外错误。

代码:

..
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 中转义单引号是可以接受的?当我尝试在 XML Spy 中使用相同的文档运行 xpath 查询时,它运行良好。

【问题讨论】:

  • 我通常建议将参数注入 XPath 表达式是使用 XPath 库提供的工具来设置变量,然后引用表达式中的变量 (/a//b[. = $targetValue])。但是 VTD-XML 只允许您通过评估另一个 XPath 表达式来设置变量,这与我知道的所有其他 XPath 实现不同,它允许您直接注入 Java 字符串或数字作为变量的值。
  • 我认为双引号前的反斜杠应该可以解决问题。

标签: java xml xpath vtd-xml


【解决方案1】:

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

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

【讨论】:

  • 如果你像这样转义双引号,那么它们很可能被认为是字符串的一部分并且不分隔任何东西。
  • @MathiasMüller:他们被认为是字符串的一部分。这就是重点,字符串变成了 XPath 表达式
  • 但是,这个字符串不再是 delimited,这将导致错误(或者 XPath 将决定它是一个元素名称)。在我看来,至少。如果我遗漏了一些明显的东西,我们深表歉意。
  • XPath 只看到最终的未转义字符串。又名/a//b[text() = "apple'banana"]
【解决方案2】:

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

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

同样,当 XPath 表达式写在字符串中时 在 Java 等宿主语言中,您需要使用转义 该语言的约定:例如,[...] 引号为 \".

换句话说,'' 确实转义了一个单引号 in XSLT 2.0。在 Java 中,单引号必须转义为 \' 我猜。

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

【讨论】:

  • 谢谢,我试过了,但没有成功。我现在得到 acom.ximpleware.XPathParseException: Invalid char in XPath Expression 异常。
  • @BigbyWolf 单引号真的与唯一标识元素相关吗?如果显示正在查询的 XML 文件,也许我们可以找到另一个返回相同节点的表达式。
  • @BigbyWolf 另外,您确定 VTD-XML 使用 XPath 2.0 吗?在 sourceforge 页面here 我发现:“VTD-XML 完全符合 W3C XPath 1.0 建议。”。这是过时的吗?
  • 感谢您的帮助。我相信你是对的,VTD-XML 使用的是 XPath 1.0(我的错误)。基于此,我尝试了“和 &apos 我相信它应该在 XPath 1.0 中工作 - 但没有运气。我最终编写了一个自定义方法,将字符串拆分并使用 Xpath concat 函数。
【解决方案3】:

不幸的是,转义似乎不是一种选择,我不得不根据以下内容编写一个自定义函数:

XQuery looking for text with 'single' quote

它是用 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;
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    相关资源
    最近更新 更多