php editor Baicao brings you a method to obtain an empty array when parsing XML. When processing XML data, sometimes we encounter a situation where the node is empty. At this time, we need to obtain an empty array to represent the node. In PHP, you can get an empty array by using an xpath expression or by using the children() method of the SimpleXMLElement object. You can use xpath expressions to get an empty array by adding "[]" after the node name, and use the children() method to get an empty array by passing an empty string as a parameter. These methods can help us accurately obtain the value of an empty array when parsing XML.
I have been tasked with writing a go utility that accepts an xml file, parses it, and returns it as json.
The following is an example of xml:
<?xml version="1.0" encoding="utf-8"?> <tracks clid="020"> <track uuid="551" category="s" route="8" vehicle_type="trolleybus" > <point latitude="53.61491" longitude="55.90922" avg_speed="24" direction="270" time="13122022:072116" /> </track> <track uuid="552" category="s" route="6" vehicle_type="trolleybus"> <point latitude="53.68321" longitude="57.90922" avg_speed="42" direction="181" time="13122022:072216" /> </track> </tracks>
I wrote the following code:
package main import ( "encoding/json" "encoding/xml" "fmt" ) type tracks struct { xmlname xml.name `xml:"tracks" json:"-"` clid string `xml:"clid,attr" json:"clid"` tracks []track `xml:"track" json:"track_list"` } type track struct { xmlname xml.name `xml:"tracks"` uuid string `xml:"uuid,attr" json:"uuid"` category string `xml:"category,attr" json:"category"` route string `xml:"route,attr" json:"route"` vehicletype string `xml:"vehicle_type,attr" json:"vehicle_type"` point point `xml:"point" json:"point"` } type point struct { latitude string `xml:"latitude,attr" json:"latitude"` longitude string `xml:"longitude,attr" json:"longitude"` avgspeed string `xml:"avg_speed,attr" json:"avg_speed"` direction string `xml:"direction,attr" json:"direction"` time string `xml:"time,attr" json:"time"` } func main() { rawxmldata := ` <?xml version="1.0" encoding="utf-8"?> <tracks clid="020"> <track uuid="551" category="s" route="8" vehicle_type="trolleybus"> <point latitude="53.61491" longitude="55.90922" avg_speed="24" direction="270" time="13122022:072116"/> </track> <track uuid="552" category="s" route="6" vehicle_type="trolleybus"> <point latitude="53.68321" longitude="57.90922" avg_speed="42" direction="181" time="13122022:072216"/> </track> </tracks> ` var tracks tracks err := xml.unmarshal([]byte(rawxmldata), &tracks) if err != nil { log.fatal(err) } jsondata, err := json.marshal(tracks) if err != nil { log.fatal(err) } fmt.printf(string(jsondata)) }
go.dev
But, unfortunately, it doesn't work. I get the following message in the console:
2009/11/10 23:00:00 expected element type <tracks> but have <track>
What did i do wrong? How can I solve this problem?
I guess I should move the discussion to the answer, since I think you're pretty close. As I mentioned, you need to check the errors returned by xml.unmarshal
. It might look like this:
if err := xml.unmarshal([]byte(rawxmldata), &tracks); err != nil { panic(err) }
Now that you have valid xml data in your code, we can generate meaningful errors; after completing the above error checking, running the code will produce:
panic: expected element type <tracks> but have <track> goroutine 1 [running]: main.main() /home/lars/tmp/go/main.go:48 +0x12f
This happens because there is a small typo in your data structure; in the definition of the track
structure, you have:
type track struct { xmlname xml.name `xml:"tracks"` uuid string `xml:"uuid,attr" json:"uuid"` category string `xml:"category,attr" json:"category"` route string `xml:"route,attr" json:"route"` vehicletype string `xml:"vehicle_type,attr" json:"vehicle_type"` point point `xml:"point" json:"point"` }
You mistagged the xmlname
attribute as tracks
when it should actually be track
:
type track struct { xmlname xml.name `xml:"track"` uuid string `xml:"uuid,attr" json:"uuid"` category string `xml:"category,attr" json:"category"` route string `xml:"route,attr" json:"route"` vehicletype string `xml:"vehicle_type,attr" json:"vehicle_type"` point point `xml:"point" json:"point"` }
Finally - and this is not directly related to the question - you should avoid naming variables error
, as this is the name of an incorrect built-in data type. I would modify your call to json.marshal
to look like this:
jsondata, err := json.marshal(tracks) if err != nil { panic(err) }
panic() on
errors; it's just a convenient way to get rid of your code.
After making these changes, if we compile and run the code, we will get the output (in the format jq
):
{ "clid": "020", "track_list": [ { "xmlname": { "space": "", "local": "track" }, "uuid": "551", "category": "s", "route": "8", "vehicle_type": "trolleybus", "point": { "latitude": "53.61491", "longitude": "55.90922", "avg_speed": "24", "direction": "270", "time": "13122022:072116" } }, { "xmlname": { "space": "", "local": "track" }, "uuid": "552", "category": "s", "route": "6", "vehicle_type": "trolleybus", "point": { "latitude": "53.68321", "longitude": "57.90922", "avg_speed": "42", "direction": "181", "time": "13122022:072216" } } ] }
Note that you don't even need the xmlname
element in your structure; if we remove it entirely, then we have:
type track struct { uuid string `xml:"uuid,attr" json:"uuid"` category string `xml:"category,attr" json:"category"` route string `xml:"route,attr" json:"route"` vehicletype string `xml:"vehicle_type,attr" json:"vehicle_type"` point point `xml:"point" json:"point"` }
Then we get the output (in the format jq
):
{ "clid": "020", "track_list": [ { "uuid": "551", "category": "s", "route": "8", "vehicle_type": "trolleybus", "point": { "latitude": "53.61491", "longitude": "55.90922", "avg_speed": "24", "direction": "270", "time": "13122022:072116" } }, { "uuid": "552", "category": "s", "route": "6", "vehicle_type": "trolleybus", "point": { "latitude": "53.68321", "longitude": "57.90922", "avg_speed": "42", "direction": "181", "time": "13122022:072216" } } ] }
The above is the detailed content of How to get empty array when parsing XML?. For more information, please follow other related articles on the PHP Chinese website!