如果Http响应代码为200,如何让XPathExtractor提取xml元素?

时间:2016-07-18 21:08:40

标签: jmeter beanshell

在我的JMeter测试计划中,我有一个HttpRequest,我想仅在响应代码为200时从其响应中提取链接。 我可以在HttpRequest下添加一个XPathExtractor后处理器,它可以工作。

但我希望首先使用IfCondition,以便提取器不会尝试处理无效内容。但是IfController不能作为后处理器添加。

也许我可以有BeanShell sampler来做,但我不知道如何在BeanShell中使用XPathExtractor。

1 个答案:

答案 0 :(得分:2)

  1. "简短易行"方式 - 使用额外的采样器

    • 在HTTP请求
    • 之后添加If Controller
    • 使用SampleResult.setResponseData(ctx.getPreviousResult().getResponseData()); 作为"条件"
    • Beanshell Sampler放在If Controller
    • 在Beanshell Sampler" Script"中使用以下代码面积:

      import org.apache.jmeter.util.PropertiesBasedPrefixResolver;
      import org.apache.jmeter.util.XPathUtil;
      import org.apache.xpath.XPathAPI;
      import org.apache.xpath.objects.XObject;
      import org.w3c.dom.Document;
      import org.w3c.dom.Element;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      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;
      
      
      InputStream in = new ByteArrayInputStream(prev.getResponseData());
      boolean useNameSpace = false;
      boolean isTolerant = true;
      boolean isQuiet = true;
      boolean showWarnings = true;
      boolean reportErrors = true;
      boolean isXML = false;
      boolean isDownloadDTDs = false;
      
      
      if (prev.isResponseCodeOK()) {
      
          InputStream in = new ByteArrayInputStream(prev.getResponseData());
          boolean useNameSpace = false;
          boolean isTolerant = true;
          boolean isQuiet = true;
          boolean showWarnings = true;
          boolean reportErrors = true;
          boolean isXML = false;
          boolean isDownloadDTDs = false;
      
      
          String query = "//a[text()='JMeter FAQ (Wiki)']";
          List matchStrings = new ArrayList();
          //matchStrings.add("-1");
          boolean returnFragment = false;
      
      
          Document doc = XPathUtil.makeDocument(in, false, false, useNameSpace, isTolerant, isQuiet, showWarnings, reportErrors
                      , isXML, isDownloadDTDs);
          String val = null;
          XObject xObject = XPathAPI.eval(doc, query, new PropertiesBasedPrefixResolver(doc.getDocumentElement());
          int objectType = xObject.getType();
          if (objectType == xObject.CLASS_NODESET) {
              NodeList matches = xObject.nodelist();
              int length = matches.getLength();
      
              for (int i = 0; i < length; ++i) {
                  Node match = matches.item(i);
                  if (match instanceof Element) {
                      if (returnFragment) {
                          StringWriter sw = new StringWriter();
      
                          Transformer t = TransformerFactory.newInstance().newTransformer();
                              t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                          t.transform(new DOMSource(match), new StreamResult(sw));
      
                          val = sw.toString();
                      } else {
                          Node firstChild = match.getFirstChild();
                          if (firstChild != null) {
                              val = firstChild.getNodeValue();
                          } else {
                              val = match.getNodeValue();
                          }
                      }
                  } else {
                      val = match.getNodeValue();
                  }
      
                  matchStrings.add(val);
              }
          } else if (objectType != xObject.CLASS_NULL && objectType != xObject.CLASS_UNKNOWN && objectType != xObject.CLASS_UNRESOLVEDVARIABLE) {
              val = xObject.toString();
              matchStrings.add(val);
          } else {
              log.warn("Unexpected object type: " + xObject.getTypeString() + " returned for: " + query);
          }
      
      
          for (String match : matchStrings) {
              log.info("Match -----> " + match);
          }
      }
      
    • 将XPath Extractor作为Beanshell Sampler的子项

    上面的Beanshell脚本将返回与前面的HTTP Request sampler相同的响应

    1. &#34;漫长而艰难&#34;方式 - 直接在Beanshell中提取XPath。

      • 放置Beanshell PostProcessor而不是XPath Extractor
      • 使用以下脚本作为参考:

          $("#"+row_id).text("Deactivate");
        
  2. 有关在JMeter脚本中使用Beanshell的更多信息,请参阅How to Use BeanShell: JMeter's Favorite Built-in Component指南