Unexpected string representation for node of complex type
srebhan opened this issue · comments
For nodes containing complex types such as a map
or slice
its string representation (via Value()
) is unexpected. The
results are not matching the actual raw content of that node in the JSON input. This is even more severe when using InnerText()
.
Here an example to reproduce the issue and to show the expectations:
Code
package main
import (
"fmt"
"os"
"github.com/antchfx/jsonquery"
"github.com/antchfx/xpath"
)
func main() {
filename := "test.json"
queries := []string{"//a", "//b", "//c", "//d", "//e"}
f, err := os.Open(filename)
if err != nil {
panic(fmt.Errorf("failed to read file %q: %w", filename, err))
}
defer f.Close()
doc, err := jsonquery.Parse(f)
if err != nil {
panic(fmt.Errorf("failed to parse document: %w", err))
}
// Queries
for _, query := range queries {
// Compile the query expression
expr, err := xpath.Compile(query)
if err != nil {
panic(fmt.Errorf("failed to compile query '%s': %v", query, err))
}
// Evaluate the compiled expression
var r interface{}
node := expr.Evaluate(jsonquery.CreateXPathNavigator(doc))
if iter, ok := node.(*xpath.NodeIterator); ok {
if iter.MoveNext() {
current := iter.Current()
r = current.Value()
}
}
fmt.Printf("query %q: %-40q (%T)\n", query, r, r)
}
}
Input data
{
"a": "a string",
"b": 3.1415,
"c": true,
"d": {
"d1": 1,
"d2": "foo",
"d3": true,
"d4": null
},
"e": ["master", 42, true],
"f": 1690193829
}
Actual result
query "//a": "a string" (string)
query "//b": "3.1415" (string)
query "//c": "true" (string)
query "//d": "map[d1:1 d2:foo d3:true d4:<nil>]" (string)
query "//e": "[master 42 true]" (string)
query "//f": "1.690193829e+09" (string)
Expected result
query "//a": "a string" (string)
query "//b": "3.1415" (string)
query "//c": "true" (string)
query "//d": "{"d1":1, "d2":"foo", "d3":true, "d4:" null}" (string)
query "//e": "["master", 42, true]" (string)
query "//f": "1690193829" (string)
My guess is that we either store the raw string of the input or we json.Marshal
the complex types when getting the string. The latter method requires less changes, however it does not guarantee to return the exact same value as found in the input (e.g. due to stripped/added whitespaces)...
Merged, thanks.
I guess we can via Node.InnerText()
method provides the raw value, that can simplify the code for Xath.NodeIterator.MoveNext()
operation.
I'm currently not using InnerText()
, just noticed it looks strange. So, honestly speaking, I can neither agree nor decline your idea. :-)