How to pass data structure as parameter in golang

XML for Json

package main import ( "encoding/json" "encoding/xml" "fmt" ) type Persons struct { Person []struct { Name string Age int } } type Places struct { Place []struct { Name string Country string } } type Parks struct { Park struct { Name []string Capacity []int } } const personXml = ` <Persons> <Person><Name>Koti</Name><Age>30</Age></Person> <Person><Name>Kanna</Name><Age>29</Age></Person> </Persons> ` const placeXml = ` <Places> <Place><Name>Chennai</Name><Country>India</Country></Place> <Place><Name>London</Name><Country>UK</Country></Place> </Places> ` const parkXml = ` <Parks> <Park><Name>National Park</Name><Capacity>10000</Capacity></Park> <Park>Asian Park</Name><Capacity>20000</Capacity></Park> </Parks> ` func WhatIamUsing() { var persons Persons xml.Unmarshal([]byte(personXml), &persons) per, _ := json.Marshal(persons) fmt.Printf("%s\n", per) var places Places xml.Unmarshal([]byte(placeXml), &places) pla, _ := json.Marshal(places) fmt.Printf("%s\n", pla) var parks Parks xml.Unmarshal([]byte(parkXml), &parks) par, _ := json.Marshal(parks) fmt.Printf("%s\n", par) } 

What I want is a generic function that takes an xml and dataStruct string and returns Json output. But below the function throws an error. How to influence this?

 func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) { var dataStruct DataStruct xml.Unmarshal([]byte(personXml), &dataStruct) js, _ := json.Marshal(dataStruct) return fmt.Sprintf("%s\n", js), nil } func main() { jsonstring, _ := Xml2Json(personXml, Persons) } 

Error message:

prog.go: 73: DataStruct is not a type

prog.go: 80: type Person is not an expression

goplay link: http://play.golang.org/p/vayb0bawKx

+7
go
source share
2 answers

You cannot save a type (e.g. Persons ) in an interface. You can pass reflect.Type to your function. Then your call will look like Xml2Json(personXml, reflect.TypeOf(Persons)) , which, in my opinion, is pretty ugly.

Perhaps a better approach:

 func Xml2Json(xmlString string, value interface{}) (string, error) { if err := xml.Unmarshal([]byte(xmlString), value); err != nil { return "", err } js, err := json.Marshal(value) if err != nil { return "", err } return string(js), nil } 

You can use this function with Xml2Json(personXml, new(Persons)) if you are not interested in the value itself, and

 var persons Persons Xml2Json(personXML, &persons) 

when you also want to get a struct value for later processing.

+12
source share

The Xml2Json function declares a parameter named DataStruct . In the same scope, a DataStruct identifier cannot indicate a type name. If you want to use a name of type DataStruct within the same scope, you must specify your parameter in different ways.

The problem with the main function is that the function call syntax expects a list of expressions in parentheses. There you pass a type name, which obviously cannot be an expression.

So, to answer your question: No, you cannot pass a type as an argument to a function. But you can pass an instance of a type (in this case, a pointer to such an instance) to get the effect you are talking about:

 package main import ( "encoding/json" "encoding/xml" "fmt" "log" ) type Persons struct { Person []struct { Name string Age int } } type Places struct { Place []struct { Name string Country string } } type Parks struct { Park struct { Name []string Capacity []int } } const ( personXml = ` <Persons> <Person><Name>Koti</Name><Age>30</Age></Person> <Person><Name>Kanna</Name><Age>29</Age></Person> </Persons> ` placeXml = ` <Places> <Place><Name>Chennai</Name><Country>India</Country></Place> <Place><Name>London</Name><Country>UK</Country></Place> </Places> ` parkXml = ` <Parks> <Park><Name>National Park</Name><Capacity>10000</Capacity></Park> <Park><Name>Asian Park</Name><Capacity>20000</Capacity></Park> </Parks> ` ) func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) { if err = xml.Unmarshal([]byte(xmlString), DataStruct); err != nil { return } js, err := json.Marshal(DataStruct) if err != nil { return } return fmt.Sprintf("%s", js), nil } func main() { var p Persons jsonstring, err := Xml2Json(personXml, &p) if err != nil { log.Fatal(err) } fmt.Println(jsonstring) var q Places jsonstring, err = Xml2Json(placeXml, &q) if err != nil { log.Fatal(err) } fmt.Println(jsonstring) var r Parks jsonstring, err = Xml2Json(parkXml, &r) if err != nil { log.Fatal(err) } fmt.Println(jsonstring) } 

Playground


Output:

 {"Person":[{"Name":"Koti","Age":30},{"Name":"Kanna","Age":29}]} {"Place":[{"Name":"Chennai","Country":"India"},{"Name":"London","Country":"UK"}]} {"Park":{"Name":["National Park","Asian Park"],"Capacity":[10000,20000]}} 
+1
source share

All Articles