From 97b4db8438599500a8a02c8d7b4b05add0471627 Mon Sep 17 00:00:00 2001 From: Sven Rebhan <36194019+srebhan@users.noreply.github.com> Date: Thu, 15 Sep 2022 23:42:18 +0200 Subject: [PATCH] fix(parsers.xpath): Add array index when expanding names. (#11781) --- plugins/parsers/xpath/json_document.go | 21 +++++++- .../testcases/name_expansion/expected.out | 3 ++ .../testcases/name_expansion/telegraf.conf | 10 ++++ .../xpath/testcases/name_expansion/test.json | 48 +++++++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 plugins/parsers/xpath/testcases/name_expansion/expected.out create mode 100644 plugins/parsers/xpath/testcases/name_expansion/telegraf.conf create mode 100644 plugins/parsers/xpath/testcases/name_expansion/test.json diff --git a/plugins/parsers/xpath/json_document.go b/plugins/parsers/xpath/json_document.go index 155ed6335..801f1c35e 100644 --- a/plugins/parsers/xpath/json_document.go +++ b/plugins/parsers/xpath/json_document.go @@ -1,6 +1,8 @@ package xpath import ( + "reflect" + "strconv" "strings" "github.com/antchfx/jsonquery" @@ -42,7 +44,14 @@ func (d *jsonDocument) GetNodePath(node, relativeTo dataNode, sep string) string // Climb up the tree and collect the node names n := nativeNode.Parent for n != nil && n != nativeRelativeTo { - names = append(names, n.Data) + switch reflect.TypeOf(n.Parent.Value()).Kind() { + case reflect.Slice, reflect.Array: + // Determine the index for array elements + names = append(names, d.index(n)) + default: + // Use the name if not an array + names = append(names, n.Data) + } n = n.Parent } @@ -63,3 +72,13 @@ func (d *jsonDocument) OutputXML(node dataNode) string { native := node.(*jsonquery.Node) return native.OutputXML() } + +func (d *jsonDocument) index(node *jsonquery.Node) string { + idx := 0 + + for n := node; n.PrevSibling != nil; n = n.PrevSibling { + idx++ + } + + return strconv.Itoa(idx) +} diff --git a/plugins/parsers/xpath/testcases/name_expansion/expected.out b/plugins/parsers/xpath/testcases/name_expansion/expected.out new file mode 100644 index 000000000..f49896f04 --- /dev/null +++ b/plugins/parsers/xpath/testcases/name_expansion/expected.out @@ -0,0 +1,3 @@ +devices ok=true,phases_0_load=34,phases_0_voltage=231,phases_1_load=35,phases_1_voltage=231,phases_2_load=36,phases_2_voltage=231,rpm=423,type="Motor" 1662730607000000000 +devices flow=3.1414,hours=8762,ok=true,type="Pump" 1662730607000000000 +devices ok=true,phases_0_load=341,phases_0_voltage=231,phases_1_load=352,phases_1_voltage=231,phases_2_load=363,phases_2_voltage=231,throughput=1026,type="Machine" 1662730607000000000 diff --git a/plugins/parsers/xpath/testcases/name_expansion/telegraf.conf b/plugins/parsers/xpath/testcases/name_expansion/telegraf.conf new file mode 100644 index 000000000..060720a34 --- /dev/null +++ b/plugins/parsers/xpath/testcases/name_expansion/telegraf.conf @@ -0,0 +1,10 @@ +[[inputs.file]] + files = ["./testcases/name_expansion/test.json"] + data_format = "xpath_json" + xpath_native_types = true + + [[inputs.file.xpath]] + metric_name = "'devices'" + metric_selection = "/devices/*" + field_selection = "descendant::*" + field_name_expansion = true diff --git a/plugins/parsers/xpath/testcases/name_expansion/test.json b/plugins/parsers/xpath/testcases/name_expansion/test.json new file mode 100644 index 000000000..fd08a47d1 --- /dev/null +++ b/plugins/parsers/xpath/testcases/name_expansion/test.json @@ -0,0 +1,48 @@ +{ + "devices": [ + { + "type": "Motor", + "rpm": 423, + "phases": [ + { + "load": 34, + "voltage": 231 + }, + { + "load": 35, + "voltage": 231 + }, + { + "load": 36, + "voltage": 231 + } + ], + "ok": true + }, + { + "type": "Pump", + "hours": 8762, + "flow": 3.1414, + "ok": true + }, + { + "type": "Machine", + "throughput": 1026, + "phases": [ + { + "load": 341, + "voltage": 231 + }, + { + "load": 352, + "voltage": 231 + }, + { + "load": 363, + "voltage": 231 + } + ], + "ok": true + } + ] +} \ No newline at end of file