suppress handled error message in processing xpath

when it contains an XML 1.1 escape sequence
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlUtil.java b/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlUtil.java
index e989d5f..2699eeb 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlUtil.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/xstream/XmlUtil.java
@@ -30,12 +30,16 @@
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
+import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
+import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 import com.google.common.annotations.Beta;
+import org.xml.sax.SAXParseException;
 
 public class XmlUtil {
 
@@ -45,12 +49,40 @@
      */
     private static class SharedDocumentBuilder {
         private static ThreadLocal<DocumentBuilder> instance = new ThreadLocal<DocumentBuilder>();
-        
-        public static DocumentBuilder get() throws ParserConfigurationException {
+
+        /** xpath in particular prints to stderr and then throws or swallows; do the same, but without printing to stderr */
+        public static DocumentBuilder getSwallowingOrThrowingErrors(boolean throwIfWarning, boolean throwIfError, boolean throwIfFatal) {
+            ErrorHandler eh = new ErrorHandler() {
+                @Override
+                public void warning(SAXParseException exception) throws SAXException {
+                    if (throwIfWarning) throw exception;
+                }
+                @Override
+                public void error(SAXParseException exception) throws SAXException {
+                    if (throwIfError) throw exception;
+                }
+                @Override
+                public void fatalError(SAXParseException exception) throws SAXException {
+                    if (throwIfFatal) throw exception;
+                }
+            };
+            return get(eh);
+        }
+
+        public static DocumentBuilder get() {
+            return get(null);
+        }
+
+        public static DocumentBuilder get(ErrorHandler errorHandler) {
             DocumentBuilder result = instance.get();
             if (result == null) {
                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                result = factory.newDocumentBuilder();
+                try {
+                    result = factory.newDocumentBuilder();
+                } catch (ParserConfigurationException e) {
+                    throw Exceptions.propagate(e);
+                }
+                if (errorHandler!=null) result.setErrorHandler(errorHandler);
                 instance.set(result);
             } else {
                 result.reset();
@@ -64,16 +96,16 @@
     }
 
     public static Object xpath(String xml, String xpath, QName returnType) {
+        return xpath(SharedDocumentBuilder.get(), xml, xpath, returnType);
+    }
+    public static Object xpath(DocumentBuilder builder, String xml, String xpath, QName returnType) {
         try {
-            DocumentBuilder builder = SharedDocumentBuilder.get();
             Document doc = builder.parse(new InputSource(new StringReader(xml)));
             XPathFactory xPathfactory = XPathFactory.newInstance();
             XPathExpression expr = xPathfactory.newXPath().compile(xpath);
-            
+
             return expr.evaluate(doc, returnType);
             
-        } catch (ParserConfigurationException e) {
-            throw Exceptions.propagate(e);
         } catch (SAXException e) {
             throw Exceptions.propagate(e);
         } catch (IOException e) {
@@ -97,7 +129,8 @@
     @Beta
     public static Object xpathHandlingIllegalChars(String xml, String xpath, QName returnType) {
         try {
-            return xpath(xml, xpath, returnType);
+            return xpath(SharedDocumentBuilder.getSwallowingOrThrowingErrors(false, false, true),
+                    xml, xpath, returnType);
         } catch (Exception e) {
             SAXException saxe = Exceptions.getFirstThrowableOfType(e, SAXException.class);
             if (saxe != null && saxe.toString().contains("&#")) {
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlUtilTest.java b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlUtilTest.java
index 94ff2c8..31acda0 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlUtilTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/xstream/XmlUtilTest.java
@@ -26,6 +26,7 @@
 
 import javax.xml.xpath.XPathConstants;
 
+import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.core.xstream.XmlUtil.Escaper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -100,6 +101,17 @@
     }
 
     @Test
+    public void testWeirdStrings() throws Exception {
+        // should work, and shouldn't print error to stderr anymore
+        Asserts.assertEquals(XmlUtil
+                        .xpathHandlingIllegalChars("<x>" +
+//                          "\u001b" +
+                            "&#x1b;"+
+                            "abc<y>a</y></x>", "/x/y[text()]"),
+                "a");
+    }
+
+    @Test
     public void testXpathWithEscapedCharsAndXmlUnversioned() throws Exception {
         StringBuilder xml = new StringBuilder("<a><b>myb</b><c>");
         for (int i = 0; i < Integer.valueOf("FFFF", 16); i++) {