Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jmeter variables in xpath extractor

Tags:

xpath

jmeter

I want to iterate over a set of table rows from a html response (e.g. each row contains data that I want to use in another request). To do this I have set up a variable called COUNTER and I have setup an XPath Extractor with the XPath Query field set to

//table//tr[${COUNTER}]/td[0]

However this fails to obtain a result irrespective of the value of COUNTER. If I replace ${COUNTER} with a numeric value, e.g.

//table//tr[4]/td[0]

it works as expected.

The following bug indicates that this functionality should be in 2.5.1 https://issues.apache.org/bugzilla/show_bug.cgi?id=51885 but it doesn't work for me in 2.5.1 or 2.6

Using variables in XPath expressions must be very useful in jmeter but I can't find any talk of how to do this on the web. I'm open to alternative suggestions but Regular Expressions doesn't immediately appear to be the right solution.

like image 753
Chris Avatar asked Feb 08 '12 11:02

Chris


1 Answers

Try to use Beanshell PostProcessor with beanshell/java code to extract all the values from xml-response using xpath query.

  1. Attach Beanshell PostProcessor as child to the sampler which returns your html response.
  2. Use the following code in PostProcessor (from external file or insert into "Script" field) to extract and save the keys:

    import java.io.*;
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;
    import org.w3c.dom.*;
    import org.xml.sax.SAXException;
    
    import org.apache.jmeter.samplers.SampleResult;
    
    // set here your xpath expression (to extract EVERY key, not any separate one)
    String xpathExpr = "//table//tr/td/text()";
    
    try {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();
    
        // access result of parent sampler via "ctx" BeanShell variable        
        SampleResult result = ctx.getPreviousResult();
        InputSource is = new InputSource(new StringReader(result.getResponseDataAsString()));
        Document doc = builder.parse(is);
    
        XPath xpath = XPathFactory.newInstance().newXPath();
        XPathExpression expr = xpath.compile(xpathExpr);
        NodeList nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
    
        // extract all the keys in loop
        for (int i = 0; i < nodes.getLength(); i++) {
            String key = nodes.item(i).getNodeValue();
            System.out.println(key);
        }
    } catch (Exception ex) {
        IsSuccess = false;
        log.error(ex.getMessage());
        ex.printStackTrace();
    }
    


Using xpathExpr = "//table//tr/td/text()" will give you all the columns in all the rows.
To get more specific selection you can:

  • refine xpath query, e.g.//table//tr/td[1]/text();
  • extract all values and then iterate through list of results to get what you exactly need.

Hope this helps.

like image 153
Aliaksandr Belik Avatar answered Nov 13 '22 20:11

Aliaksandr Belik