1

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 クエリを実行しようとすると、正常に実行されます。

4

3 に答える 3

1

XPath はエスケープされていない「-s」を含む文字列もサポートできるため".."、次のように使用できます。

   ap.selectXPath("/a//b[text() = \"apple'banana\"]");
于 2014-08-28T15:57:06.080 に答える
0

エスケープは、XPath を使用してデータをクエリするホスト言語に完全に任せられる問題です。通常、その高水準言語のエスケープ規則は、そこで使用される XPath 式にも適用されます。

Michael Kay の XPath 2.0 Programmer's Reference から引用します。

同様に、XPath 式が Java などのホスト言語の文字列内に記述されている場合、その言語のエスケープ規則を使用する必要があります。たとえば、 [...] a quote mark as \".

つまり、XSLT 2.0 では単一引用符をエスケープし'' ます。Java では、私が推測するように、一重引用符をエスケープする必要があります。\'

ap.selectXPath("/a//b[text() = 'apple\'banana']");
于 2014-08-27T20:15:09.753 に答える
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 に答える