Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
105 views
in Technique[技术] by (71.8m points)

Generic JSON to XML transformation by templating

I'm trying to devise a service to convert a generic JSON data representation into XML data representation. The first idea that came to my mind (and that I found on the internet) takes advantage of the Go templating utilities.

If I have a JSON data representation like the following:

{
  "user": {
     "name": "Luca",
     "surname": "Rossi"
  }
} 

I could devise a template like the following:

<xml>
  <user name="{{.user.name}}" surname="{{.user.surname}}" />
</xml>

to generate:

<xml>
   <user name="Luca" surname="Rossi" />
</xml>

The problem is: Go requires the definition of a struct which declares how to marshal and unmarshal a JSON data representation; at the same time, however, I'd like to provide the template to generate the XML as a service configuration available at runtime.

The question is: "is it possible"? I know (thanks tothis question) that I can take do something like this:

var anyJson map[string]interface{}
json.Unmarshal(bytes, &anyJson)

The problem comes when I have to access values: I'd be asked to do a type assertion, like

anyJson["id"].(string)

Now, I might be able to know the type of anyJson["id"] by means of JSON schema, for example, but I don't know if I can do a parametric type assertion, something like

anyJson["id"].(typeForIDFromJSONSchema)
question from:https://stackoverflow.com/questions/65890413/generic-json-to-xml-transformation-by-templating

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you unmarshal into map[string]interface{}, every nested JSON object will also be map[string]interface{}. So type assertions of the contained elements to string may typically work, but not to any struct type - the unmarshaller would always be unaware of your structs.

So the two options I suggest are

  • to do it 'the hard way' using type switches and type assertions - this is workable and fast, but not all that nice; or
  • to use a different tool such as jsoniter or gjson - these might be a little slower but they do allow you to traverse arbitrary JSON graphs

I have used both GJson and Jsoniter. GJson works by reading byte by byte through the input, using buffering to keep its speed up, providing an API that allows inspection of the current element and assertions to convert the values.

Jsoniter looks to me like a cleaner implementation along the lines of successful parsers in Java, but I haven't used it for parsing in this manner yet. (It can also be used simply as a fast drop-in replacement for the standard Go encoding/json.) I suggest you focus on using its Iterator and its WhatIsNext method.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...