https://issues.apache.org/jira/browse/JCR-579
So, use org.apache.jackrabbit.util.ISO9075 as shown in:
http://wiki.apache.org/jackrabbit/EncodingAndEscaping
Example xpath servlet (/apps/sandbox/xpath/xpath.jsp):
https://gist.github.com/1478007
<%--
runs xpath
--%><%@page
language="java"
contentType="text/plain; charset=UTF-8"
pageEncoding="UTF-8"
import="javax.jcr.query.*,
java.io.*,
java.util.*,
java.util.regex.*,
org.apache.jackrabbit.util.*"
%><%@include file="/libs/foundation/global.jsp"%><%!
private static Pattern XPATH = Pattern.compile("^/jcr:root(/.+)//(.+)$");
public static String escapeXpath(String xpath) {
final Matcher matcher = XPATH.matcher(xpath);
if (matcher.find()) {
final String path = ISO9075.encodePath(matcher.group(1));
final String props = matcher.group(2);
return String.format("/jcr:root%s//%s", path, props);
}
return xpath;
}
%><%
final String xpathOriginal = slingRequest.getParameter("xpath");
final String xpath = escapeXpath(xpathOriginal);
final boolean isXpathEscaped = !xpath.equals(xpathOriginal);
final String displayParam = slingRequest.getParameter("display");
final boolean display = "false".equals(displayParam) ? false : true;//by default, iterates query result.
final QueryManager queryManager = resourceResolver.adaptTo(Session.class).getWorkspace().getQueryManager();
final Query query = queryManager.createQuery(xpath, Query.XPATH);
final String limitParam = slingRequest.getParameter("limit");
final long limit = (null != limitParam && !"".equals(limitParam)) ? Long.parseLong(limitParam, 10) : 100;
query.setLimit(limit);
final String offsetParam = slingRequest.getParameter("offset");
final long offset = (null != offsetParam && !"".equals(offsetParam)) ? Long.parseLong(offsetParam, 10) : -1;
if (offset > 0) {
query.setOffset(offset);
}
final long t = System.currentTimeMillis();
final QueryResult result = query.execute();
final NodeIterator iter = result.getNodes();
long count = iter.getSize();
out.append("original xpath:\n");
out.append(xpathOriginal + "\n");
out.append("escaped xpath:\n");
out.append(xpath + "\n");
if (isXpathEscaped) {
out.append("(xpath is escaped)\n");
}
out.append("\nresult:\n\n");
if (display) {
count = 0;
while (iter.hasNext()) {
final Node node = iter.nextNode();
out.append(node.getPath() + "\n");
count++;
}
}
final long took = System.currentTimeMillis() - t;
%>
queried <%= count %> nodes (offset: <%= offset %>, limit: <%= limit %>) in <%= (took / 1000.0) %> secs.