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="§-num;.8.2" width="541" height="247" screenshot="xpath_extractor.png"> +<component name="XPath Extractor" index="§-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 "&lt;title>Apache JMeter&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> --------------------------------------------------------------------- To unsubscribe, e-mail: jmeter-dev-unsubscr...@jakarta.apache.org For additional commands, e-mail: jmeter-dev-h...@jakarta.apache.org