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.
This commit is contained in:
raul 2024-05-15 12:27:24 +02:00
parent 8f9239e392
commit e0a8c745d5
2 changed files with 37 additions and 15 deletions

View File

@ -2,7 +2,7 @@ package cmd
import ( import (
"fmt" "fmt"
xj "github.com/basgys/goxml2json" xj "github.com/riccardomanfrin/goxml2json"
"io" "io"
"net/http" "net/http"
"strings" "strings"
@ -15,28 +15,43 @@ type root struct {
Dia []struct { Dia []struct {
Fecha string `json:"-fecha"` Fecha string `json:"-fecha"`
UV string `json:"uv_max"` UV string `json:"uv_max"`
Temperatura struct { Temperatura struct {
Maxima string `json:"maxima"` Maxima string `json:"maxima"`
Minima string `json:"minima"` Minima string `json:"minima"`
Dato []struct { Dato []struct {
Valor string `json:"#content"` Valor string `json:"#content"`
Hora string `json:"-hora"` Hora string `json:"-hora"`
} } `json:"dato"`
} } `json:"temperatura"`
Sens_Termica struct { Sens_Termica struct {
Maxima string `json:"maxima"` Maxima string `json:"maxima"`
Minima string `json:"minima"` Minima string `json:"minima"`
Dato []struct { Dato []struct {
Valor string `json:"#content"` Valor string `json:"#content"`
Hora string `json:"-hora"` Hora string `json:"-hora"`
} } `json:"dato"`
} } `json:"sens_termica"`
Humedad_Relativa struct { Humedad_Relativa struct {
Maxima string `json:"maxima"` Maxima string `json:"maxima"`
Minima string `json:"minima"` 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"` } `json:"root"`
} }
@ -87,7 +102,12 @@ func getJSON(codPostal string) (s string, err error) {
} }
xml := strings.NewReader(string(data)) 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 { if err != nil {
e := fmt.Errorf("Error occurred converting XML to JSON: %v\n", err) e := fmt.Errorf("Error occurred converting XML to JSON: %v\n", err)
return "", e return "", e

View File

@ -12,18 +12,19 @@ var (
localidades = map[string]string{ localidades = map[string]string{
"valencia": "46250", "valencia": "46250",
"madrid": "28079", "madrid": "28079",
"barcelona": "08019",
} }
) )
func server() { func server() {
router := gin.Default() router := gin.Default()
router.GET("/api/:codigopostal", returnWeather) router.GET("/api/:localidad", returnWeather)
fmt.Printf("Listening on port %v...\n", listenPort) fmt.Printf("Listening on port %v...\n", listenPort)
router.Run(":" + listenPort) router.Run(":" + listenPort)
} }
func returnWeather(c *gin.Context) { func returnWeather(c *gin.Context) {
codPostal := c.Param("codigopostal") codPostal := c.Param("localidad")
isAvailable := false isAvailable := false
for k := range localidades { for k := range localidades {
if codPostal == k { if codPostal == k {
@ -46,6 +47,7 @@ func returnWeather(c *gin.Context) {
if err != nil { if err != nil {
e := fmt.Sprintf("Error occurred unmarshalling data: %v\n", err) e := fmt.Sprintf("Error occurred unmarshalling data: %v\n", err)
c.String(http.StatusInternalServerError, e) c.String(http.StatusInternalServerError, e)
return
} }
c.IndentedJSON(http.StatusOK, aemetRequest) c.IndentedJSON(http.StatusOK, aemetRequest)