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 }