Bug 43294 - XPath Extractor namespace problems
XPath Extractor namespace problems
Status: RESOLVED FIXED
Product: JMeter
Classification: Unclassified
Component: Main
2.5.1
All All
: P2 normal with 1 vote (vote)
: ---
Assigned To: JMeter issues mailing list
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2007-09-03 05:36 UTC by Sebb
Modified: 2011-11-20 22:17 UTC (History)
1 user (show)



Attachments
xpathns1.xml - ns defined on 1st use (848 bytes, text/plain)
2007-09-03 05:37 UTC, Sebb
Details
xpathns2.xml - ns defined at top level (848 bytes, text/plain)
2007-09-03 05:37 UTC, Sebb
Details
xpathns.jmx - test plan (12.72 KB, text/plain)
2007-09-03 05:38 UTC, Sebb
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sebb 2007-09-03 05:36:17 UTC
XPath Extractor unconditionally sets namespace=false in the document factory 
call; it should be settable in the GUI.

There is also a problem resolving namespaces defined in child elements - xalan 
appears to only understand XPath namespaces if they are defined at the top-
level.

For example, xpathns1.xml defines the namespace "ns" on the first use of the 
ns namespace - XPath cannot handle //ns:result as the namespace is not defined.

Whereas xpathns2.xml defines the namespace "ns" on the root node, 
and //ns:result works OK - once the document factory namespace is set true.

xpathns.jmx is a test plan showing the problem (requires namespace=true)
Comment 1 Sebb 2007-09-03 05:37:21 UTC
Created attachment 20760 [details]
xpathns1.xml - ns defined on 1st use
Comment 2 Sebb 2007-09-03 05:37:52 UTC
Created attachment 20761 [details]
xpathns2.xml - ns defined at top level
Comment 3 Sebb 2007-09-03 05:38:26 UTC
Created attachment 20762 [details]
xpathns.jmx - test plan
Comment 4 Philippe Mouawad 2011-09-19 21:04:38 UTC
Hello,
It seems first part of this is already implémented, ie checkbox for namespace.
For the other one , it seems we must create a table where user Will map préfix to full namespace
And then use Namespace resolver.
Does this seems ok for you ?

Regards
Philippe Mouawad
Comment 5 Philippe Mouawad 2011-09-20 07:15:00 UTC
Hello,
I tested quickly this approach by replacing current code of
XPathExtractor#getValuesForXPath by this code:
----------------------------------------------------------------------
   private void getValuesForXPath(Document d,String query, List<String>
matchStrings)
        throws TransformerException, XPathExpressionException {
        String val = null;
        final PrefixResolver resolver = new PrefixResolverDefault(d
                .getDocumentElement());
        NamespaceContext ctx = new NamespaceContext() {
            public String getNamespaceURI(String prefix) {
                String uri= null;
// HARD CODED PREFIX THAT WOULD BE REPLACED BY TABLE INPUT OF USER
                if (prefix.equals("ns"))
                    return "http://biz.aol.com/schema/2006-12-18";
                else
                    return resolver.getNamespaceForPrefix(prefix);
            }

            // Dummy implementation - not used!
            public Iterator getPrefixes(String val) {
                return null;
            }

            // Dummy implemenation - not used!
            public String getPrefix(String uri) {
                return null;
            }
        };

        XPathFactory xpathFact = XPathFactory.newInstance();
        XPath xpath = xpathFact.newXPath();
        xpath.setNamespaceContext(ctx);
        XPathExpression expr = xpath.compile(query);
        NodeList nodeList = (NodeList) expr.evaluate(d,
XPathConstants.NODESET);
        int length = nodeList.getLength();
        for (int i = 0 ; i < length; i++) {
            Node match = nodeList.item(i);
            if ( match instanceof Element){
                if (getFragment()){
                    val = getValueForNode(match);
                } else {
                    // elements have empty nodeValue, but we are usually
interested in their content
                    final Node firstChild = match.getFirstChild();
                    if (firstChild != null) {
                        val = firstChild.getNodeValue();
                    } else {
                        val = match.getNodeValue(); // TODO is this correct?
                    }
                }
            } else {
               val = match.getNodeValue();
            }
            matchStrings.add(val);
        }
}

---------------------------------------------------------------------------
And it works.

Do you agree with it ? 
If so what would be the best :
- Adding a table to input prefix=full namespace values to XPath Extractor ?
- Adding a table to input prefix=full namespace values to XPath Extractor
Config element ?

Thank you for your answers.
Regards
Philippe Mouawad
Comment 6 Sebb 2011-11-10 13:37:41 UTC
I suspect it is quite a rare use-case, so I'm inclined to leave the code as it is and just document it.

Seems wrong for JMeter to add a work-round for problems in Xalan which may one day be resolved.

It would probably be more useful to ensure that the XPath elements can use an alternate parser.

If the use-case turns out to be more frequent, and alternate parsers cannot help, then it would probably be worthwhile adding the work-round.
Comment 7 Philippe Mouawad 2011-11-11 13:56:05 UTC
The issue is that if we don't use Xalan, then we don't have the ability to evaluate XPath expression without knowing their return type.
I mean in standard java XPath, evaluate methods expect a second parameter which gives the expected return type otherwise it uses a String return type.
I tried using standard Java XPath and I faced this issue.


Second, examining Xalan , Dom4j and jaxen: 
http://flrt.free.fr/jython/testjava/xpath_ns.html

it seems giving them the prefix mapping is mandatory.


So with first issue we are stuck with Xalan (unless you see a solution).
With second it seems using a configuration element may be the only solution.
Comment 8 Sebb 2011-11-11 16:46:47 UTC
I'd not realised that we used any Xalan-specific classes, but I see now that we use XPathAPI.

We should perhaps work towards removing that dependency ... seems like it is not very efficient anyway.

As a work-round, the simplest would be to allow the user to supply a properties file to provide the additional NS mappings.

If we do go down this route, we should probably provide the additional mappings for use with all other XPath elements, e.g. the XPath function.
Comment 9 Philippe Mouawad 2011-11-20 20:55:47 UTC
Date: Sun Nov 20 20:55:08 2011
New Revision: 1204254

URL: http://svn.apache.org/viewvc?rev=1204254&view=rev
Log:
Bug 43294 - XPath Extractor namespace problems
First part: Put in XPathUtil everything related to XPath computations

Modified:
   jmeter/trunk/src/components/org/apache/jmeter/assertions/XPathAssertion.java
   jmeter/trunk/src/components/org/apache/jmeter/assertions/gui/XPathPanel.java
   jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java
   jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java
   jmeter/trunk/src/functions/org/apache/jmeter/functions/XPathFileContainer.java
Comment 10 Philippe Mouawad 2011-11-20 22:17:27 UTC
Date: Sun Nov 20 22:11:36 2011
New Revision: 1204280

URL: http://svn.apache.org/viewvc?rev=1204280&view=rev
Log:
Bug 43294 - XPath Extractor namespace problems

Added:
   jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java   (with props)
Modified:
   jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java
   jmeter/trunk/xdocs/changes.xml
   jmeter/trunk/xdocs/usermanual/component_reference.xml


Date: Sun Nov 20 22:16:51 2011
New Revision: 1204281

URL: http://svn.apache.org/viewvc?rev=1204281&view=rev
Log:
Bug 43294 - XPath Extractor namespace problems

Modified:
   jmeter/trunk/bin/jmeter.properties