github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/postprocessor/var_xpath.go (about)

     1  package postprocessor
     2  
     3  import (
     4  	"io"
     5  	"net/http"
     6  
     7  	"github.com/antchfx/htmlquery"
     8  	"github.com/antchfx/xpath"
     9  	"golang.org/x/net/html"
    10  )
    11  
    12  type VarXpathPostprocessor struct {
    13  	Mapping map[string]string
    14  }
    15  
    16  func (p *VarXpathPostprocessor) ReturnedParams() []string {
    17  	result := make([]string, len(p.Mapping))
    18  	for k := range p.Mapping {
    19  		result = append(result, k)
    20  	}
    21  	return result
    22  }
    23  
    24  func (p *VarXpathPostprocessor) Process(_ *http.Response, body io.Reader) (map[string]any, error) {
    25  	if len(p.Mapping) == 0 {
    26  		return nil, nil
    27  	}
    28  	doc, err := html.Parse(body)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	result := make(map[string]any, len(p.Mapping))
    33  	for k, path := range p.Mapping {
    34  		values, err := p.getValuesFromDOM(doc, path)
    35  		if err != nil {
    36  			return nil, err
    37  		}
    38  		if len(values) == 1 {
    39  			result[k] = values[0]
    40  		} else {
    41  			result[k] = values
    42  		}
    43  	}
    44  	return result, nil
    45  }
    46  
    47  func (p *VarXpathPostprocessor) getValuesFromDOM(doc *html.Node, xpathQuery string) ([]string, error) {
    48  	expr, err := xpath.Compile(xpathQuery)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	iter := expr.Evaluate(htmlquery.CreateXPathNavigator(doc)).(*xpath.NodeIterator)
    54  
    55  	var values []string
    56  	for iter.MoveNext() {
    57  		node := iter.Current()
    58  		values = append(values, node.Value())
    59  	}
    60  
    61  	return values, nil
    62  }