如何在XPath查询中使用Java String变量

Jav*_*its 3 java xml xpath

我有books.xml包含作者姓名和书名的文件.我使用以下代码片段进行查询books.xml.

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr 
    = xpath.compile("//book[author= 'Larry Niven']/title/text()");
Run Code Online (Sandbox Code Playgroud)

现在,如果我想在程序作为String变量运行时传递它而不是直接将名称放在查询中,该怎么做.只是把字符串变量名称不起作用!

McD*_*ell 6

这里的问题是当你有一个臭名昭着的拉里"Basher"O'Niven这样的作家.

在这种情况下,您需要转义变量,就像在这个天真的实现中一样:

  public static String escape(String s) {
    Matcher matcher = Pattern.compile("['\"]")
        .matcher(s);
    StringBuilder buffer = new StringBuilder("concat(");
    int start = 0;
    while (matcher.find()) {
      buffer.append("'")
          .append(s.substring(start, matcher.start()))
          .append("',");
      buffer.append("'".equals(matcher.group()) ? "\"'\"," : "'\"',");
      start = matcher.end();
    }
    if (start == 0) {
      return "'" + s + "'";
    }
    return buffer.append("'")
        .append(s.substring(start))
        .append("'")
        .append(")")
        .toString();
  }
Run Code Online (Sandbox Code Playgroud)

这可以通过以下代码演示:

String xml =
    "<xml><foo bar=\"Larry &quot;Basher&quot; O'Niven\">Ringworm</foo></xml>";
String query =
    String.format("//foo[@bar=%s]", escape("Larry \"Basher\" O'Niven"));
System.out.println(query);
String book = XPathFactory.newInstance()
    .newXPath()
    .evaluate(query, new InputSource(new StringReader(xml)));
System.out.println(query + " > " + book);
Run Code Online (Sandbox Code Playgroud)