From ae9a67d6e5ffdf1990b08915cb0e810abfc24f3c Mon Sep 17 00:00:00 2001 From: Rohit Jangid Date: Tue, 27 Jun 2023 13:35:59 +0530 Subject: [PATCH] Add argument in parseXmlJsonml function --- builtins.go | 26 ++++++++++++++----- jsonml.go | 22 +++++++++------- linter/internal/types/stdlib.go | 2 +- testdata/builtinParseXmlJsonml2.golden | 7 +++++ testdata/builtinParseXmlJsonml2.jsonnet | 1 + testdata/builtinParseXmlJsonml2.linter.golden | 0 6 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 testdata/builtinParseXmlJsonml2.golden create mode 100644 testdata/builtinParseXmlJsonml2.jsonnet create mode 100644 testdata/builtinParseXmlJsonml2.linter.golden diff --git a/builtins.go b/builtins.go index bcae1c6..bce6a17 100644 --- a/builtins.go +++ b/builtins.go @@ -1512,14 +1512,26 @@ func builtinParseYAML(i *interpreter, str value) (value, error) { return jsonToValue(i, elems[0]) } -func builtinParseXmlJsonml(i *interpreter, str value) (value, error) { - sval, err := i.getString(str) +func builtinParseXmlJsonml(i *interpreter, arguments []value) (value, error) { + strv := arguments[0] + pwsv := arguments[1] + + sval, err := i.getString(strv) if err != nil { return nil, err } s := sval.getGoString() - json, err := BuildJsonmlFromString(s) + pws := false + if pwsv.getType() != nullType { + pwsval, err := i.getBoolean(pwsv) + if err != nil { + return nil, err + } + pws = pwsval.value + } + + json, err := BuildJsonmlFromString(s, pws) if err != nil { return nil, i.Error(fmt.Sprintf("failed to parse XML: %v", err.Error())) } @@ -2143,12 +2155,12 @@ func builtinAvg(i *interpreter, arrv value) (value, error) { if err != nil { return nil, err } - + len := float64(arr.length()) if len == 0 { return nil, i.Error("Cannot calculate average of an empty array.") } - + sumValue, err := builtinSum(i, arrv) if err != nil { return nil, err @@ -2158,7 +2170,7 @@ func builtinAvg(i *interpreter, arrv value) (value, error) { return nil, err } - avg := sum.value/len + avg := sum.value / len return makeValueNumber(avg), nil } @@ -2566,7 +2578,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{ &unaryBuiltin{name: "parseInt", function: builtinParseInt, params: ast.Identifiers{"str"}}, &unaryBuiltin{name: "parseJson", function: builtinParseJSON, params: ast.Identifiers{"str"}}, &unaryBuiltin{name: "parseYaml", function: builtinParseYAML, params: ast.Identifiers{"str"}}, - &unaryBuiltin{name: "parseXmlJsonml", function: builtinParseXmlJsonml, params: ast.Identifiers{"str"}}, + &generalBuiltin{name: "parseXmlJsonml", function: builtinParseXmlJsonml, params: []generalBuiltinParameter{{name: "str"}, {name: "preserveWhitespace", defaultValue: &nullValue}}}, &generalBuiltin{name: "manifestJsonEx", function: builtinManifestJSONEx, params: []generalBuiltinParameter{{name: "value"}, {name: "indent"}, {name: "newline", defaultValue: &valueFlatString{value: []rune("\n")}}, {name: "key_val_sep", defaultValue: &valueFlatString{value: []rune(": ")}}}}, diff --git a/jsonml.go b/jsonml.go index 57ff64b..0ae8a2c 100644 --- a/jsonml.go +++ b/jsonml.go @@ -47,13 +47,14 @@ func (s *stack) Size() int { } type jsonMLBuilder struct { - stack *stack - currDepth int + stack *stack + preserveWhitespace bool + currDepth int } // BuildJsonmlFromString returns a jsomML form of given xml string. -func BuildJsonmlFromString(s string) ([]interface{}, error) { - b := newBuilder() +func BuildJsonmlFromString(s string, preserveWhitespace bool) ([]interface{}, error) { + b := newBuilder(preserveWhitespace) d := xml.NewDecoder(strings.NewReader(s)) for { @@ -79,9 +80,10 @@ func BuildJsonmlFromString(s string) ([]interface{}, error) { return b.build(), nil } -func newBuilder() *jsonMLBuilder { +func newBuilder(preserveWhitespace bool) *jsonMLBuilder { return &jsonMLBuilder{ - stack: &stack{}, + stack: &stack{}, + preserveWhitespace: preserveWhitespace, } } @@ -108,9 +110,11 @@ func (b *jsonMLBuilder) addToken(token xml.Token) error { b.currDepth++ case xml.CharData: t := token.(xml.CharData) - s := strings.TrimSpace(string(t)) - if len(s) > 0 { - // Skip whitespace only string + s := string(t) + if !b.preserveWhitespace { + s = strings.TrimSpace(s) + } + if len(s) > 0 { // Skip empty strings b.appendToLastNode(string(t)) } case xml.EndElement: diff --git a/linter/internal/types/stdlib.go b/linter/internal/types/stdlib.go index a82fb0f..2646c64 100644 --- a/linter/internal/types/stdlib.go +++ b/linter/internal/types/stdlib.go @@ -111,7 +111,7 @@ func prepareStdlib(g *typeGraph) { "parseHex": g.newSimpleFuncType(numberType, "str"), "parseJson": g.newSimpleFuncType(jsonType, "str"), "parseYaml": g.newSimpleFuncType(jsonType, "str"), - "parseXmlJsonml": g.newSimpleFuncType(jsonType, "str"), + "parseXmlJsonml": g.newFuncType(jsonType, []ast.Parameter{required("str"), optional("preserveWhitespace")}), "encodeUTF8": g.newSimpleFuncType(numberArrayType, "str"), "decodeUTF8": g.newSimpleFuncType(stringType, "arr"), diff --git a/testdata/builtinParseXmlJsonml2.golden b/testdata/builtinParseXmlJsonml2.golden new file mode 100644 index 0000000..84826ae --- /dev/null +++ b/testdata/builtinParseXmlJsonml2.golden @@ -0,0 +1,7 @@ +[ + "svg", + [ + "circle", + " Foobar" + ] +] diff --git a/testdata/builtinParseXmlJsonml2.jsonnet b/testdata/builtinParseXmlJsonml2.jsonnet new file mode 100644 index 0000000..99d80a2 --- /dev/null +++ b/testdata/builtinParseXmlJsonml2.jsonnet @@ -0,0 +1 @@ +std.parseXmlJsonml(' Foobar', preserveWhitespace=true) \ No newline at end of file diff --git a/testdata/builtinParseXmlJsonml2.linter.golden b/testdata/builtinParseXmlJsonml2.linter.golden new file mode 100644 index 0000000..e69de29