If I have the following XML:
<blah>
<a>stuff here</a>
<b>other stuff</b>
<b>more stuff</b>
</blah>
I'd like to be able to unmarshal the innerxml of <blah>
, but only include the <b>
elements and all raw tags, and exclude everything else. In this example, my raw innerxml result needs to be:
<b>other stuff</b>
<b>more stuff</b>
Not sure if this is doable with struct tags or if I have to write a custom unmarshaler function.
Tried the following code:
package main
import (
"encoding/xml"
"fmt"
)
type blah struct {
XMLName xml.Name `xml:"blah"`
RawXML string `xml:",innerxml"`
}
func main() {
blahXML := []byte(`<blah>
<a>stuff here</a>
<b>other stuff</b>
<b>more stuff</b>
</blah>`)
var blah blah
if err := xml.Unmarshal(blahXML, &blah); err != nil {
panic(err)
}
fmt.Printf("%s
", blah.RawXML)
}
Which returns all of the innerxml:
<a>stuff here</a>
<b>other stuff</b>
<b>more stuff</b>
Not sure how to just return the raw <b>
lines.
Thanks!
If you want the inner XML of an element, that will be everything inside that element. You can't choose specific elements and still call it inner XML; that's not how XML parsers work. It seems like what you actually want is the outer XML of all the b
elements in the document. That's relatively easy, once you look at it from the right perspective. I'd suggest just unmarshalling the b
elements, and if you want to reconstruct the XML with only those elements, just marshal it again:
type blah struct {
XMLName xml.Name `xml:"blah"`
Bees []b `xml:"b"`
}
type b struct {
RawXML string `xml:",innerxml"`
}
func main() {
blahXML := []byte(`<blah>
<a>stuff here</a>
<b>other stuff</b>
<b>more stuff</b>
</blah>`)
test := new(blah)
err := xml.Unmarshal(blahXML, test)
if err != nil {
panic(err)
}
output, err := xml.Marshal(&test)
if err != nil {
panic(err)
}
fmt.Println(string(output))
}
Playground example here: https://play.golang.org/p/MAtWk2YMld