svn commit: r889487 - in /jakarta/jmeter/trunk: docs/images/screenshots/ src/components/org/apache/jmeter/extractor/ src/components/org/apache/jmeter/extractor/gui/ src/core/org/apache/jmeter/resources/ test/src/org/apache/jmeter/extractor/ xdocs/ xdoc...

[email protected]
Newsgroups gmane.comp.jakarta.jmeter.devel
Message-ID <[email protected]>
Author: sebb
Date: Fri Dec 11 01:40:43 2009
New Revision: 889487

URL: http://svn.apache.org/viewvc?rev=889487&view=rev
Log:
Bug 48331 - XpathExtractor does not return XML string representations for a Nodeset

Modified:
    jakarta/jmeter/trunk/docs/images/screenshots/xpath_extractor.png
    jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java
    jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jakarta/jmeter/trunk/test/src/org/apache/jmeter/extractor/TestXPathExtractor.java
    jakarta/jmeter/trunk/xdocs/changes.xml
    jakarta/jmeter/trunk/xdocs/images/screenshots/xpath_extractor.png
    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml

Modified: jakarta/jmeter/trunk/docs/images/screenshots/xpath_extractor.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/xpath_extractor.png?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java (original)
+++ jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/XPathExtractor.java Fri Dec 11 01:40:43 2009
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
+import java.io.StringWriter;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerException;
@@ -46,6 +47,12 @@
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
 //@see org.apache.jmeter.extractor.TestXPathExtractor for unit tests
 
 /**
@@ -58,6 +65,10 @@
  *     <dd>extracts value attribute of option element that match text 'Czech Republic'
  *                 inside of select element with name attribute  'country' inside of
  *                 form with name attribute 'countryForm'</dd>
+ * <dt>//head</dt>
+ *     <dd>extracts the XML fragment for head node.</dd>
+ * <dt>//head/text()</dt>
+ *     <dd>extracts the text content for head node.</dd>
  * </dl>
  */
  /* This file is inspired by RegexExtractor.
@@ -83,6 +94,7 @@
     private static final String DOWNLOAD_DTDS   = "XPathExtractor.download_dtds"; // $NON-NLS-1$
     private static final String WHITESPACE      = "XPathExtractor.whitespace"; // $NON-NLS-1$
     private static final String VALIDATE        = "XPathExtractor.validate"; // $NON-NLS-1$
+    private static final String FRAGMENT        = "XPathExtractor.fragment"; // $NON-NLS-1$
     //- JMX file attributes
 
 
@@ -203,6 +215,22 @@
         return getPropertyAsBoolean(QUIET, true);
     }
 
+    /**
+     * Should we return fragment as text, rather than text of fragment?
+     * @return true if we should return fragment rather than text
+     */
+    public boolean getFragment() {
+        return getPropertyAsBoolean(FRAGMENT, false);
+    }
+
+    /**
+     * Should we return fragment as text, rather than text of fragment?
+     * @param selected true to return fragment.
+     */
+    public void setFragment(boolean selected) {
+        setProperty(FRAGMENT, selected, false);
+    }
+
     /*================= internal business =================*/
     /**
      * Converts (X)HTML response to DOM object Tree.
@@ -249,13 +277,17 @@
             for (int i = 0 ; i < length; i++) {
                 Node match = matches.item(i);
                 if ( match instanceof Element){
-                // 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?
-                   }
+                    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();
                 }
@@ -302,5 +334,17 @@
 
     public boolean isDownloadDTDs() {
         return getPropertyAsBoolean(DOWNLOAD_DTDS, false);
+    }     
+    
+    private 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();
     }
 }

Modified: jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java (original)
+++ jakarta/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java Fri Dec 11 01:40:43 2009
@@ -24,6 +24,7 @@
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
+import javax.swing.JCheckBox;
 import javax.swing.JComponent;
 import javax.swing.JPanel;
 
@@ -47,6 +48,8 @@
 
     private JLabeledTextField refNameField;
 
+    private JCheckBox getFragment; // Should we return fragment as text, rather than text of fragment?
+    
     private XMLConfPanel xml;
     
     public String getLabelResource() {
@@ -65,6 +68,7 @@
         xpathQueryField.setText(xpe.getXPathQuery());
         defaultField.setText(xpe.getDefaultValue());
         refNameField.setText(xpe.getRefName());
+        getFragment.setSelected(xpe.getFragment());
         xml.configure(xpe);
     }
 
@@ -82,6 +86,7 @@
             xpath.setDefaultValue(defaultField.getText());
             xpath.setRefName(refNameField.getText());
             xpath.setXPathQuery(xpathQueryField.getText());
+            xpath.setFragment(getFragment.isSelected());
             xml.modifyTestElement(xpath);
         }
     }
@@ -109,8 +114,10 @@
         xml.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), JMeterUtils
                 .getResString("xpath_assertion_option"))); //$NON-NLS-1$
         box.add(xml);
+        getFragment = new JCheckBox(JMeterUtils.getResString("xpath_extractor_fragment"));//$NON-NLS-1$
+        box.add(getFragment);
+        box.add(makeParameterPanel());
         add(box, BorderLayout.NORTH);
-        add(makeParameterPanel(), BorderLayout.CENTER);
     }
 
 

Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Fri Dec 11 01:40:43 2009
@@ -973,6 +973,7 @@
 xpath_assertion_validation=Validate the XML against the DTD
 xpath_assertion_whitespace=Ignore whitespace
 xpath_expression=XPath expression to match against
+xpath_extractor_fragment=Return entire XPath fragment instead of text content?
 xpath_extractor_query=XPath query:
 xpath_extractor_title=XPath Extractor
 xpath_file_file_name=XML file to get values from 

Modified: jakarta/jmeter/trunk/test/src/org/apache/jmeter/extractor/TestXPathExtractor.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/extractor/TestXPathExtractor.java?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/test/src/org/apache/jmeter/extractor/TestXPathExtractor.java (original)
+++ jakarta/jmeter/trunk/test/src/org/apache/jmeter/extractor/TestXPathExtractor.java Fri Dec 11 01:40:43 2009
@@ -128,6 +128,26 @@
             assertEquals("Default", vars.get(VAL_NAME));
             assertEquals("1", vars.get(VAL_NAME_NR));
             assertNull(vars.get(VAL_NAME+"_1"));
+
+            // No text
+            extractor.setXPathQuery("//a");
+            extractor.process();
+            assertEquals("Default", vars.get(VAL_NAME));
+
+            // Test fragment
+            extractor.setXPathQuery("/book/page[2]");
+            extractor.setFragment(true);
+            extractor.process();
+            assertEquals("<page>two</page>", vars.get(VAL_NAME));
+            // Now get its text
+            extractor.setXPathQuery("/book/page[2]/text()");
+            extractor.process();
+            assertEquals("two", vars.get(VAL_NAME));
+
+            // No text, but using fragment mode
+            extractor.setXPathQuery("//a");
+            extractor.process();
+            assertEquals("<a><b/></a>", vars.get(VAL_NAME));
         }
 
         public void testInvalidXpath() throws Exception {

Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Fri Dec 11 01:40:43 2009
@@ -162,6 +162,7 @@
 <li>Bug 47952 - Added JSR223 PreProcessor and PostProcessor</li>
 <li>Added JSR223 Assertion</li>
 <li>Added BSF Timer and JSR223 Timer</li>
+<li>Bug 48331 - XpathExtractor does not return XML string representations for a Nodeset</li>
 </ul>
 
 <h3>Functions</h3>

Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/xpath_extractor.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/xpath_extractor.png?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=889487&r1=889486&r2=889487&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Fri Dec 11 01:40:43 2009
@@ -4075,7 +4075,7 @@
 </p>
 </component>
 
-<component name="XPath Extractor" index="&sect-num;.8.2"  width="541" height="247" screenshot="xpath_extractor.png">
+<component name="XPath Extractor" index="&sect-num;.8.2"  width="613" height="269" screenshot="xpath_extractor.png">
 	<description>This test element allows the user to extract value from 
 		structured response - XML or (X)HTML - using XPath
 		query language.
@@ -4110,9 +4110,15 @@
     <property name="Validate XML"   required="If Tidy is not selected">Check the document against its schema.</property>
     <property name="Ignore Whitespace"  required="If Tidy is not selected">Ignore Element Whitespace.</property>
     <property name="Fetch External DTDs"  required="If Tidy is not selected">If selected, external DTDs are fetched.</property>
+    <property name="Return entire XPath fragment instead of text content?" required="Yes">
+    If selected, the fragment will be returned rather than the text content.<br></br>
+    For example //title would return "&amp;lt;title>Apache JMeter&amp;lt;/title>" rather than "Apache JMeter".<br></br>
+    In this case, //title/text() would return "Apache JMeter".
+    </property>
     <property name="Reference Name" required="Yes">The name of the JMeter variable in which to store the result.</property>
-	<property name="XPath Query" required="Yes">Element query in XPath language. Can return more than one match. </property>
-	<property name="Default Value" required="">Default value returned when no match found</property>
+	<property name="XPath Query" required="Yes">Element query in XPath language. Can return more than one match.</property>
+	<property name="Default Value" required="">Default value returned when no match found. 
+	It is also returned if the node has no value and the fragment option is not selected.</property>
    </properties>
    <p>To allow for use in a ForEach Controller, the following variables are set on return:</p>
    <ul>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.