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 }