Please see this playground: https://play.golang.org/p/FOMWqhjdneg
As you can see I have a XML response which I want to unmarshal into a Product struct. The XML has an "assetBlock" which contains nested nodes and extract data to Product struct. Any help would be appreciated
You need to make a struct for AssetBlock and all of the types below it, I've done it up to group to show you what I mean:
https://play.golang.org/p/vj_CkneHuLd
type Product struct {
GlobalID string `xml:"globalId"`
Title string `xml:"title"`
ChunkID int `xml:"gpcChunkId"`
AssetBlock assetBlock `xml:"assetBlock"`
}
type assetBlock struct {
Images images `xml:"images"`
}
type images struct {
GroupList groupList `xml:"groupList"`
}
type groupList struct {
Groups []group `xml:"group"`
}
type group struct {
Usage string `xml:"usage"`
Size string `xml:"size"`
}
Related
Let's say I have two different structs:
type One struct {
Id string
// Other fields
}
type Two struct {
Id string
// Other fields
}
Is it possible to define a function that accepts both One and Two without explicitly listing them as options?
E.g. I am looking for something like this:
type ModelWithId struct {
Id string
}
func Test[M ModelWithId](m M) {
fmt.PrintLn(m.Id)
}
one := One { Id: "1" }
Test(one) // Prints 1
I don't want to use funcTest[M One | Two](m M), because I'll likely have 10+ structs and I don't want to come back to the function every time I add a new struct to the codebase.
Generics constraints the type parameter behaviours using methods, so you need to rewrite your code as:
type One struct {
id string
}
func (o *One) Id() string {
return o.id
}
then your use site would become:
type ModelWithId interface {
Id() string
}
func Test[M ModelWithId](m M) {
fmt.Println(m.Id())
}
type Old struct {
UserID int `json:"user_ID"`
Data struct {
Address string `json:"address"`
} `json:"old_data"`
}
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: { // from here it says missing expression
Address: old.Data.Address,
},
}
}
What is "missing expression" error when using structs?
I am transforming old object to a new one. I minified them just to get straight to the point but the transformation is much more complex. The UserID field for example works great. But when I use struct (which intended to be a JSON object in the end) the Goland IDE screams "missing expression" and the compiler says "missing type in composite literal" on this line. What I am doing wrong? Maybe should I use something else instead of struct? Please help.
Data is an anonymous struct, so you need to write it like this:
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
(playground link)
I think it'd be cleanest to create a named Address struct.
You're defining Data as an inline struct. When assigning values to it, you must first put the inline declaration:
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
Hence it is generally better to define a separate type for Data, just like User.
I created a struct in a file called availability.go
package restconsume
import (
)
// Availabilityrequest for sabre
type Availabilityrequest struct {
OTAAirLowFareSearchRQ struct {
OriginDestinationInformation []struct {
DepartureDateTime string `json:"DepartureDateTime"`
DestinationLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"DestinationLocation"`
OriginLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"OriginLocation"`
RPH string `json:"RPH"`
} `json:"OriginDestinationInformation"`
POS struct {
Source []struct {
PseudoCityCode string `json:"PseudoCityCode" default:"F9CE"`
RequestorID struct {
CompanyName struct {
Code string `json:"Code" default:"TN"`
} `json:"CompanyName"`
ID string `json:"ID" default:"1"`
Type string `json:"Type" default:"1"`
} `json:"RequestorID"`
} `json:"Source"`
} `json:"POS"`
TPAExtensions struct {
IntelliSellTransaction struct {
RequestType struct {
Name string `json:"Name" default:"200ITINS"`
} `json:"RequestType"`
} `json:"IntelliSellTransaction"`
} `json:"TPA_Extensions"`
TravelPreferences struct {
TPAExtensions struct {
DataSources struct {
ATPCO string `json:"ATPCO" default:"Enable"`
LCC string `json:"LCC" default:"Disable"`
NDC string `json:"NDC" default:"Disable"`
} `json:"DataSources"`
NumTrips struct {
} `json:"NumTrips"`
} `json:"TPA_Extensions"`
} `json:"TravelPreferences"`
TravelerInfoSummary struct {
AirTravelerAvail []struct {
PassengerTypeQuantity []struct {
Code string `json:"Code"`
Quantity int `json:"Quantity"`
} `json:"PassengerTypeQuantity"`
} `json:"AirTravelerAvail"`
SeatsRequested []int `json:"SeatsRequested" default:"1"`
} `json:"TravelerInfoSummary"`
Version string `json:"Version" default:"1"`
} `json:"OTA_AirLowFareSearchRQ"`
}
// AddADepartureDate to set the date you leave
func (a *Availabilityrequest) AddADepartureDate() Availabilityrequest {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DepartureDateTime = "2020-03-21"
return *a
}
//AddOriginDestination to set the ori and dest
func (a *Availabilityrequest) AddOriginDestination(Origin ,Destination string) {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DestinationLocation.LocationCode = Destination
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].OriginLocation.LocationCode = Origin
}
Now I've imported this package into my main one and having issue instatntiating with only one substruct(TPAExtensions)
main.go
package main
import (
"restconsume"
"fmt"
)
func main() {
var a= new(restconsume.Availabilityrequest)
a = Availabilityrequest{
"OTA_AirLowFareSearchRQ":OTAAirLowFareSearchRQ{
"IntelliSellTransaction": IntelliSellTransaction{
"RequestType": RequestType{
"Name": "200ITINS"},
},
},
}
}
error message
undefined: Availabilityrequest
My question is how could I instantiate this kind of complex struct?
The simplest answer is to not try to use struct literal but rather have a variable of the top-level type to be initialized to an appropriate zero value for its type and then explicitly set only those fields which are needed, like this:
var a Availabilityrequest
a.OTAAirLowFareSearchRQ.TPAExtensions.IntelliSellTransaction.RequestType.Name = "200ITINS"
But honestly, judging from your question, it looks like you're JavaScript programmer trying to attack Go without much prior knowledge about that language. This is a path to suffering.
Please be advised to at least start with the Tour of Go and then read any introductory-level book on Go (I would recommend this one).
"Effective Go" is also a must.
I am having a json as
{
"fields": ["time","id","status","customerId","additionalDetail"],
"pageInfo": {"start": 0, "rows": 1000}
}
I wanted to Marshal my structure to above json and create the structure as below -
type RBody struct {
Fields []string `json:"fields"`
PageInfo struct {
Start int `json:"start"`
Rows int `json:"start"`
} `json:"pageInfo"`
}
I am having trouble in initializing the above structure. I am not sure how to initialize the anonymous struct in below fashion :
bd := RBody {
Fields : []string{"time","id","status","customerId","additionalDetail"},
PageInfo : ???
}
I worked around this by creating a separate structure for page info and attaching that with parent struct. However there's got to be some way to perform the initialisation of the anonymous nested struct, in the same way I did with Fields (string slice) above. Can anyone redirect me to some guide to do that ?
This works, but it is ugly:
bd := RBody { Fields : []string{"time","id","status","customerId","additionalDetail"},
PageInfo : struct {Start int `json:"start"`
Rows int `json:"rows"`} {Start:1,Rows:2}}
I suggest you either name the anonymous struct, or initialize Fields in the declaration, and PageInfo using assignments later.
I have a meal struct that "appends" another struct, except I want to add another struct "mealComponents".
type mealMain struct {
*model.Meal
Components []mealComponent `json:"components"`
}
type mealComponent struct {
*model.MealComponent
}
Where *model.Meal is as follows
type Meal struct {
ID int64 `json:"id"`
}
What I want is basically for "mealMain" struct to act like "Meal" struct, so that I can assign values and somehow append mealComponent as child (or maybe this is not a good idea? I'm open to suggestions)
However when I do something like this
var meal mealMain
meal.ID = 1
It throws runtime error: invalid memory address or nil pointer dereference at meal.ID assignment.
But if I do it like this:
type mealMain struct {
MealMain *model.Meal `json:"meal_main"`
Components []mealComponent `json:"components"`
}
Then assign it this way:
var meal mealMain
meal.mealMain.ID = 1
It works properly, but I have the return json even deeper like this:
{
"MealModel": {
"id": 1
}
}
What I want is this:
{
"id": 1
}
Note: I want to avoid changing the model.
If you don't want to change the model:
var meal = mealMain{
Meal: &Meal{},
}
meal.ID = 1
The point is that in the following struct *Meal is set to nil if you don't initialize it.
type mealMain struct {
*Meal
Components []mealComponent `json:"components"`
}
I'd probably create a function to never have to worry about the correct initialization ever again:
func newMealMain() mealMain {
return mealMain{
Meal: &Meal{},
}
}
Then your code would be:
var meal = newMealMain()
meal.ID = 1