You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2011/11/20 23:11:37 UTC
svn commit: r1204280 - in /jmeter/trunk:
src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java
src/core/org/apache/jmeter/util/XPathUtil.java xdocs/changes.xml
xdocs/usermanual/component_reference.xml
Author: pmouawad
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
Added: jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java?rev=1204280&view=auto
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java (added)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java Sun Nov 20 22:11:36 2011
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.util.JOrphanUtils;
+import org.apache.log.Logger;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.w3c.dom.Node;
+
+/**
+ * {@link PrefixResolver} implementation that loads prefix configuration from jmeter property xpath.namespace.config
+ */
+public class PropertiesBasedPrefixResolver extends PrefixResolverDefault {
+ private static final Logger logger = LoggingManager.getLoggerForClass();
+ private static final String XPATH_NAMESPACE_CONFIG = "xpath.namespace.config";
+ private static final Map<String, String> NAMESPACE_MAP = new HashMap<String, String>();
+ static {
+ String pathToNamespaceConfig = JMeterUtils.getPropDefault(XPATH_NAMESPACE_CONFIG, "");
+ if(!StringUtils.isEmpty(pathToNamespaceConfig)) {
+ Properties properties = new Properties();
+ InputStream inputStream = null;
+ try {
+ File pathToNamespaceConfigFile = JMeterUtils.findFile(pathToNamespaceConfig);
+ if(!pathToNamespaceConfigFile.exists()) {
+ logger.error("Cannot find configured file:'"+
+ pathToNamespaceConfig+"' in property:'"+XPATH_NAMESPACE_CONFIG+"', file does not exist");
+ } else {
+ if(!pathToNamespaceConfigFile.canRead()) {
+ logger.error("Cannot read configured file:'"+
+ pathToNamespaceConfig+"' in property:'"+XPATH_NAMESPACE_CONFIG+"'");
+ } else {
+ inputStream = new BufferedInputStream(new FileInputStream(pathToNamespaceConfigFile));
+ properties.load(inputStream);
+ properties.entrySet();
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ NAMESPACE_MAP.put((String) entry.getKey(), (String) entry.getValue());
+ }
+ logger.info("Read following XPath namespace configuration "+
+ NAMESPACE_MAP);
+ }
+ }
+ } catch(IOException e) {
+ logger.error("Error loading namespaces from file:'"+
+ pathToNamespaceConfig+"', message:"+e.getMessage(),e);
+ } finally {
+ JOrphanUtils.closeQuietly(inputStream);
+ }
+ }
+ }
+ /**
+ * @param xpathExpressionContext Node
+ */
+ public PropertiesBasedPrefixResolver(Node xpathExpressionContext) {
+ super(xpathExpressionContext);
+ }
+
+ /**
+ * Searches prefix in NAMESPACE_MAP, if it fails to find it defaults to parent implementation
+ * @param prefix Prefix
+ * @param namespaceContext Node
+ */
+ @Override
+ public String getNamespaceForPrefix(String prefix, Node namespaceContext) {
+ String namespace = NAMESPACE_MAP.get(prefix);
+ if(namespace==null) {
+ return super.getNamespaceForPrefix(prefix, namespaceContext);
+ } else {
+ return namespace;
+ }
+ }
+}
\ No newline at end of file
Propchange: jmeter/trunk/src/core/org/apache/jmeter/util/PropertiesBasedPrefixResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java?rev=1204280&r1=1204279&r2=1204280&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/XPathUtil.java Sun Nov 20 22:11:36 2011
@@ -39,6 +39,7 @@ import javax.xml.transform.stream.Stream
import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
+import org.apache.xml.utils.PrefixResolver;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Document;
@@ -258,6 +259,23 @@ public class XPathUtil {
}
}
}
+
+ /**
+ * Return value for node
+ * @param node Node
+ * @return String
+ */
+ private static String getValueForNode(Node node) {
+ StringWriter sw = new StringWriter();
+ try {
+ Transformer t = TransformerFactory.newInstance().newTransformer();
+ t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ t.transform(new DOMSource(node), new StreamResult(sw));
+ } catch (TransformerException e) {
+ sw.write(e.getMessageAndLocation());
+ }
+ return sw.toString();
+ }
/**
* Extract NodeList using expression
@@ -267,7 +285,8 @@ public class XPathUtil {
* @throws TransformerException
*/
public static NodeList selectNodeList(Document document, String xPathExpression) throws TransformerException {
- return XPathAPI.selectNodeList(document, xPathExpression);
+ XObject xObject = XPathAPI.eval(document, xPathExpression, getPrefixResolver(document));
+ return xObject.nodelist();
}
/**
@@ -282,7 +301,7 @@ public class XPathUtil {
String xPathQuery,
List<String> matchStrings, boolean fragment) throws TransformerException {
String val = null;
- XObject xObject = XPathAPI.eval(document, xPathQuery);
+ XObject xObject = XPathAPI.eval(document, xPathQuery, getPrefixResolver(document));
final int objectType = xObject.getType();
if (objectType == XObject.CLASS_NODESET) {
NodeList matches = xObject.nodelist();
@@ -315,23 +334,17 @@ public class XPathUtil {
matchStrings.add(val);
}
}
-
+
/**
- * Return value for node
- * @param node Node
- * @return String
+ *
+ * @param document XML Document
+ * @return {@link PrefixResolver}
*/
- private static String getValueForNode(Node node) {
- StringWriter sw = new StringWriter();
- try {
- Transformer t = TransformerFactory.newInstance().newTransformer();
- t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- t.transform(new DOMSource(node), new StreamResult(sw));
- } catch (TransformerException e) {
- sw.write(e.getMessageAndLocation());
- }
- return sw.toString();
- }
+ private static PrefixResolver getPrefixResolver(Document document) {
+ PropertiesBasedPrefixResolver propertiesBasedPrefixResolver =
+ new PropertiesBasedPrefixResolver(document.getDocumentElement());
+ return propertiesBasedPrefixResolver;
+ }
/**
* Validate xpathString is a valid XPath expression
@@ -340,7 +353,7 @@ public class XPathUtil {
* @throws TransformerException if expression fails to evaluate
*/
public static void validateXPath(Document document, String xpathString) throws TransformerException {
- if (XPathAPI.eval(document, xpathString) == null) {
+ if (XPathAPI.eval(document, xpathString, getPrefixResolver(document)) == null) {
// We really should never get here
// because eval will throw an exception
// if xpath is invalid, but whatever, better
@@ -361,7 +374,7 @@ public class XPathUtil {
String xPathExpression,
boolean isNegated) {
try {
- XObject xObject = XPathAPI.eval(doc, xPathExpression);
+ XObject xObject = XPathAPI.eval(doc, xPathExpression, getPrefixResolver(doc));
switch (xObject.getType()) {
case XObject.CLASS_NODESET:
NodeList nodeList = xObject.nodelist();
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1204280&r1=1204279&r2=1204280&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Sun Nov 20 22:11:36 2011
@@ -150,6 +150,7 @@ This behaviour can be changed with prope
<li>Bug 52215 - Confusing synchronization in StatVisualizer, SummaryReport ,Summariser and issue in StatGraphVisualizer</li>
<li>Bug 52216 - TableVisualizer : currentData field is badly synchronized</li>
<li>Bug 52217 - ViewResultsFullVisualizer : Synchronization issues on root and treeModel</li>
+<li>Bug 43294 - XPath Extractor namespace problems</li>
</ul>
<!-- =================== Improvements =================== -->
Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1204280&r1=1204279&r2=1204280&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/component_reference.xml Sun Nov 20 22:11:36 2011
@@ -3856,6 +3856,20 @@ on XPath.
<note>
The non-tolerant parser can be quite slow, as it may need to download the DTD etc.
</note>
+<note>
+To overcome Xalan XPath parser implementation on which JMeter is based, you can help the parsing by
+providing a Properties file which will contain:
+<ul>
+<li>prefix1=Full Namespace 1</li>
+<li>prefix2=Full Namespace 2</li>
+<li>...</li>
+</ul>
+
+You reference this file in jmeter.properties file using the property:
+<ul>
+ <li>xpath.namespace.config</li>
+</ul>
+</note>
</component>
<component name="XML Schema Assertion" index="§-num;.5.9" width="771" height="171" screenshot="assertion/XMLSchemaAssertion.png">
<description><p>The XML Schema Assertion allows the user to validate a response against an XML Schema.</p></description>