In the following example:
package main
import (
"fmt"
"encoding/xml"
)
var data = `
<data>
<text id="0" action="wake"/>
<text id="1" action="eat"/>
<text id="2" action="bathe"/>
<text id="3" action="walk"/>
</data>
`
type Result struct {
XMLName xml.Name `xml:"data"`
Action string //this is the part I want to solve
}
func main() {
res := Result{}
xml.Unmarshal(data, &res)
fmt.Printf("%#v", res)
}
I want to get is the following struct:
{XMLName: xml.Name{Space:"", Local:"data"}, Action:"eat"}
So can I get the value of action
attribute on the fourth text
element only? In other words, I want to get the value of an attribute of any arbitrary elements, but that element is decided by another attribute within that element (id=3
in this case).
One thing to solve the issue is to embed another struct which holds each text
element as slices, and iterate over that slice and if the id
field is 3
, then I get that inner struct's action
field... but it's too daunting and ineffective to process.
Thanks.
Unmarshal unmarshals XML to a struct. It is not called XPath because you cannot do what you want with Unmarshal.
Either unmarshal into a larger struct and iterate until id==3 as you suggested. (Not sure why you say this is inefficient. And I doubt that you measured the cost of doing before claiming inefficiency).
Or: Parse the XML manually with xml.Decoder and processing the Tokens yourself.