github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/funcs/fn_xml.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package funcs
     7  
     8  import (
     9  	"fmt"
    10  	"reflect"
    11  	"strings"
    12  
    13  	"github.com/GuanceCloud/cliutils/pipeline/ptinput"
    14  	"github.com/GuanceCloud/platypus/pkg/ast"
    15  	"github.com/GuanceCloud/platypus/pkg/engine/runtime"
    16  	"github.com/GuanceCloud/platypus/pkg/errchain"
    17  	"github.com/antchfx/xmlquery"
    18  )
    19  
    20  func XMLChecking(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    21  	if len(funcExpr.Param) != 3 {
    22  		return runtime.NewRunError(ctx, fmt.Sprintf(
    23  			"func %s expects 3 args", funcExpr.Name), funcExpr.NamePos)
    24  	}
    25  
    26  	// XML field key.
    27  	if _, err := getKeyName(funcExpr.Param[0]); err != nil {
    28  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    29  	}
    30  
    31  	// XPath expression.
    32  	switch funcExpr.Param[1].NodeType { //nolint:exhaustive
    33  	case ast.TypeStringLiteral:
    34  	default:
    35  		return runtime.NewRunError(ctx, fmt.Sprintf("expect StringLiteral, got %s",
    36  			funcExpr.Param[1].NodeType), funcExpr.Param[1].StartPos())
    37  	}
    38  
    39  	// Field name.
    40  	switch funcExpr.Param[2].NodeType { //nolint:exhaustive
    41  	case ast.TypeAttrExpr, ast.TypeIdentifier, ast.TypeStringLiteral:
    42  	default:
    43  		return runtime.NewRunError(ctx, fmt.Sprintf(
    44  			"expect AttrExpr or Identifier or StringLiteral, got %s",
    45  			funcExpr.Param[2].NodeType), funcExpr.Param[2].StartPos())
    46  	}
    47  
    48  	return nil
    49  }
    50  
    51  func XML(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    52  	var (
    53  		xmlKey, fieldName string
    54  		xpathExpr         string
    55  	)
    56  
    57  	if len(funcExpr.Param) != 3 {
    58  		return runtime.NewRunError(ctx, fmt.Sprintf(
    59  			"func %s expects 3 args", funcExpr.Name), funcExpr.NamePos)
    60  	}
    61  
    62  	// XML field key.
    63  	xmlKey, err := getKeyName(funcExpr.Param[0])
    64  	if err != nil {
    65  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    66  	}
    67  
    68  	// XPath expression
    69  	switch funcExpr.Param[1].NodeType { //nolint:exhaustive
    70  	case ast.TypeStringLiteral:
    71  		xpathExpr = funcExpr.Param[1].StringLiteral().Val
    72  	default:
    73  		return runtime.NewRunError(ctx, fmt.Sprintf("expect StringLiteStringLiteral:ral, got %s",
    74  			reflect.TypeOf(funcExpr.Param[1]).String()), funcExpr.Param[1].StartPos())
    75  	}
    76  
    77  	// Field name.
    78  
    79  	fieldName, err = getKeyName(funcExpr.Param[2])
    80  	if err != nil {
    81  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[2].StartPos())
    82  	}
    83  
    84  	cont, err := ctx.GetKeyConv2Str(xmlKey)
    85  	if err != nil {
    86  		l.Debug(err)
    87  		return nil
    88  	}
    89  
    90  	doc, err := xmlquery.Parse(strings.NewReader(cont))
    91  	if err != nil {
    92  		l.Debug(err)
    93  		return nil
    94  	}
    95  	// xmlquery already caches the compiled expression for us.
    96  	dest, err := xmlquery.Query(doc, xpathExpr)
    97  	if err != nil {
    98  		l.Debug(err)
    99  		return nil
   100  	}
   101  	if dest == nil {
   102  		err = fmt.Errorf("can't find any XML Node that matches the XPath expr: %s", xpathExpr)
   103  		l.Debug(err)
   104  		return nil
   105  	}
   106  
   107  	_ = addKey2PtWithVal(ctx.InData(), fieldName, dest.InnerText(),
   108  		ast.String, ptinput.KindPtDefault)
   109  
   110  	return nil
   111  }