From e0a8c745d5bd406b2817053263d9921f48e98353 Mon Sep 17 00:00:00 2001 From: raul Date: Wed, 15 May 2024 12:27:24 +0200 Subject: [PATCH] Fix JSON unmarshalling breaking on XML arrays being rendered as objects Due to a problem in the upstream goxml2json repo, I had to switch to a fork that allowed me to specify which children should be forcefully rendered as arrays, as some in some instances the AEMET's XML would contain completely individual values that are usually arrays, resulting in the JSON translator interpreting them as objects instead of arrays. The amount of effort I had to put into fixing this problem was mind-boggling. --- cmd/clientFunc.go | 42 +++++++++++++++++++++++++++++++----------- cmd/serverFunc.go | 10 ++++++---- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/cmd/clientFunc.go b/cmd/clientFunc.go index 24f231a..3639c36 100644 --- a/cmd/clientFunc.go +++ b/cmd/clientFunc.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - xj "github.com/basgys/goxml2json" + xj "github.com/riccardomanfrin/goxml2json" "io" "net/http" "strings" @@ -13,30 +13,45 @@ type root struct { Nombre string `json:"nombre"` Prediccion struct { Dia []struct { - Fecha string `json:"-fecha"` - UV string `json:"uv_max"` + Fecha string `json:"-fecha"` + UV string `json:"uv_max"` + Temperatura struct { Maxima string `json:"maxima"` Minima string `json:"minima"` Dato []struct { Valor string `json:"#content"` Hora string `json:"-hora"` - } - } + } `json:"dato"` + } `json:"temperatura"` + Sens_Termica struct { Maxima string `json:"maxima"` Minima string `json:"minima"` Dato []struct { Valor string `json:"#content"` Hora string `json:"-hora"` - } - } + } `json:"dato"` + } `json:"sens_termica"` + Humedad_Relativa struct { Maxima string `json:"maxima"` Minima string `json:"minima"` - } - } - } + } `json:"humedad_relativa"` + + Estado_Cielo []struct { + Test string `json:"#content"` + Periodo string `json:"-periodo"` + Descripcion string `json:"-descripcion"` + } `json:"estado_cielo"` + + // Prob_Precipitacion []struct { + // Probabilidad string `json:"#content"` + // Periodo string `json:"-periodo"` + // } `json:"prob_precipitacion"` + + } `json:"dia"` + } `json:"prediccion"` } `json:"root"` } @@ -87,7 +102,12 @@ func getJSON(codPostal string) (s string, err error) { } xml := strings.NewReader(string(data)) - json, err := xj.Convert(xml) + + // I am in tremendous pain after what I had to go through to get this damn thing working, + json, err := xj.Convert(xml, xj.WithNodes( + xj.NodePlugin("root.prediccion.dia.estado_cielo", xj.ToArray()), + )) + if err != nil { e := fmt.Errorf("Error occurred converting XML to JSON: %v\n", err) return "", e diff --git a/cmd/serverFunc.go b/cmd/serverFunc.go index 27d96dc..fc1158e 100644 --- a/cmd/serverFunc.go +++ b/cmd/serverFunc.go @@ -10,20 +10,21 @@ import ( var ( listenPort string = "1302" localidades = map[string]string{ - "valencia": "46250", - "madrid": "28079", + "valencia": "46250", + "madrid": "28079", + "barcelona": "08019", } ) func server() { router := gin.Default() - router.GET("/api/:codigopostal", returnWeather) + router.GET("/api/:localidad", returnWeather) fmt.Printf("Listening on port %v...\n", listenPort) router.Run(":" + listenPort) } func returnWeather(c *gin.Context) { - codPostal := c.Param("codigopostal") + codPostal := c.Param("localidad") isAvailable := false for k := range localidades { if codPostal == k { @@ -46,6 +47,7 @@ func returnWeather(c *gin.Context) { if err != nil { e := fmt.Sprintf("Error occurred unmarshalling data: %v\n", err) c.String(http.StatusInternalServerError, e) + return } c.IndentedJSON(http.StatusOK, aemetRequest)