From: <rb...@us...> - 2013-07-25 18:36:31
|
Revision: 8422 http://sourceforge.net/p/htmlunit/code/8422 Author: rbri Date: 2013-07-25 18:36:28 +0000 (Thu, 25 Jul 2013) Log Message: ----------- XPathEvaluator.evaluate() ignores namespace resolver (patch by Chuck Dumont) Issue 1528 Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluator.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluatorTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2013-07-25 17:30:45 UTC (rev 8421) +++ trunk/htmlunit/src/changes/changes.xml 2013-07-25 18:36:28 UTC (rev 8422) @@ -8,6 +8,9 @@ <body> <release version="2.13" date="???" description="Bugfixes"> + <action type="fix" dev="rbri" issue="1528" due-to="Chuck Dumont"> + XPathEvaluator.evaluate() ignores namespace resolver. + </action> <action type="fix" dev="rbri" issue="1527" due-to="Chuck Dumont"> XPathResult types STRING_TYPE, NUMBER_TYPE and BOOLEAN_TYPE don't work. </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluator.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluator.java 2013-07-25 17:30:45 UTC (rev 8421) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluator.java 2013-07-25 18:36:28 UTC (rev 8422) @@ -15,7 +15,11 @@ package com.gargoylesoftware.htmlunit.javascript.host; import static com.gargoylesoftware.htmlunit.javascript.configuration.BrowserName.FF; +import net.sourceforge.htmlunit.corejs.javascript.NativeArray; +import net.sourceforge.htmlunit.corejs.javascript.NativeFunction; +import org.apache.xml.utils.PrefixResolver; + import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor; @@ -27,6 +31,8 @@ * * @version $Revision$ * @author Marc Guillemot + * @author Chuck Dumont + * @author Ronald Brill */ @JsxClass(browsers = @WebBrowser(value = FF, minVersion = 17)) public class XPathEvaluator extends SimpleScriptable { @@ -58,7 +64,7 @@ /** * Evaluates an XPath expression string and returns a result of the specified type if possible. * @param expression the XPath expression string to be parsed and evaluated - * @param contextNode the context node for the evaluation of this XPath expression + * @param contextNodeObj the context node for the evaluation of this XPath expression * @param resolver the resolver permits translation of all prefixes, including the XML namespace prefix, * within the XPath expression into appropriate namespace URIs. * @param type If a specific type is specified, then the result will be returned as the corresponding type @@ -66,7 +72,7 @@ * @return the result of the evaluation of the XPath expression */ @JsxFunction(@WebBrowser(FF)) - public XPathResult evaluate(final String expression, final Node contextNode, + public XPathResult evaluate(final String expression, final Object contextNodeObj, final Object resolver, final int type, final Object result) { XPathResult xPathResult = (XPathResult) result; if (xPathResult == null) { @@ -74,7 +80,23 @@ xPathResult.setParentScope(getParentScope()); xPathResult.setPrototype(getPrototype(xPathResult.getClass())); } - xPathResult.init(contextNode.getDomNodeOrDie().getByXPath(expression), type); + // contextNodeObj can be either a node or an array with the node as the first element. + Node contextNode = null; + if (contextNodeObj instanceof NativeArray) { + contextNode = (Node) ((NativeArray) contextNodeObj).get(0); + } + else { + contextNode = (Node) contextNodeObj; + } + PrefixResolver prefixResolver = null; + if (resolver instanceof PrefixResolver) { + prefixResolver = (PrefixResolver) resolver; + } + else if (resolver instanceof NativeFunction) { + prefixResolver = new NativeFunctionPrefixResolver((NativeFunction) resolver, contextNode.getParentScope()); + } + xPathResult.init(contextNode.getDomNodeOrDie().getByXPath(expression, prefixResolver), type); return xPathResult; } + } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluatorTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluatorTest.java 2013-07-25 17:30:45 UTC (rev 8421) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/XPathEvaluatorTest.java 2013-07-25 18:36:28 UTC (rev 8422) @@ -26,6 +26,8 @@ * * @version $Revision$ * @author Marc Guillemot + * @author Chuck Dumont + * @author Ronald Brill */ @RunWith(BrowserRunner.class) public class XPathEvaluatorTest extends WebDriverTestCase { @@ -58,4 +60,68 @@ loadPageWithAlerts2(html); } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = { "Immortality" }, IE = { }, FF3_6 = { }) + public void namespacesWithNodeInArray() throws Exception { + final String html = "<html><head><title>foo</title><script>\n" + + " var xml = " + + " '<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" + + " <soap:books>" + + " <soap:book>" + + " <title>Immortality</title>" + + " <author>John Smith</author>" + + " </soap:book>" + + " </soap:books>" + + " </soap:Envelope>';\n" + + " function test() {\n" + + " if (window.XPathEvaluator) {" + + " var doc = (new DOMParser).parseFromString(xml);" + + " var xpe = new XPathEvaluator();\n" + + " var nsResolver = xpe.createNSResolver(doc.documentElement);\n" + + " var result = xpe.evaluate('/soap:Envelope/soap:books/soap:book/title/text()', " + + "[doc.documentElement], nsResolver, XPathResult.STRING_TYPE, null);\n" + + " alert(result.stringValue);\n" + + " }}\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts(DEFAULT = { "Immortality" }, IE = { }, FF3_6 = { }) + public void namespacesWithCustomNSResolver() throws Exception { + final String html = "<html><head><title>foo</title><script>\n" + + " function nsResolver(prefix) {" + + " return {s : 'http://schemas.xmlsoap.org/soap/envelope/'}[prefix] || null;" + + " }" + + " var xml = " + + " '<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" + + " <soap:books>" + + " <soap:book>" + + " <title>Immortality</title>" + + " <author>John Smith</author>" + + " </soap:book>" + + " </soap:books>" + + " </soap:Envelope>';\n" + + " function test() {\n" + + " if (window.XPathEvaluator) {" + + " var doc = (new DOMParser).parseFromString(xml);" + + " var xpe = new XPathEvaluator();\n" + + " var result = xpe.evaluate('/s:Envelope/s:books/s:book/title/text()', " + + "doc.documentElement, nsResolver, XPathResult.STRING_TYPE, null);\n" + + " alert(result.stringValue);\n" + + " }}\n" + + "</script></head><body onload='test()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } } |