Search code examples
xmlgostructxml-parsingresponse

How to parse XML data to get some target elements with go?


For this xml response data

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <ns1:postResponse xmlns:ns1="http://example.com/">
         <return>
            <postDetails>
                <title>P</title>
                <body>A</body>
            </postDetails>
            <postResult>
               <postId>1234</postId>
            </postResult>
            <postNumber>1000000</postNumber>
         </return>
      </ns1:postResponse>
   </env:Body>
</env:Envelope>

Only want to get its postId and postNumber. So created a struct as

type PostResponse struct {
    PostID string `xml:"postId"`
    PostNumber string `xml:"postNumber"`
}

A xmlunmarshal method as

func (r *PostResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    v := struct {
        XMLName        xml.Name
        PostID string `xml:"postId"`
        PostNumber string `xml:"postNumber"`
    }{}

    d.DecodeElement(&v, &start)
    r.PostID = v.PostID
    r.PostNumber = v.PostNumber

    return nil
}

When call it from main function

var postResponse = &PostResponse{}
xml.Unmarshal([]byte(payload), &postResponse)
fmt.Println(postResponse)

It can't set value to the PostResponse object currectly.

The full program on go playground.


Solution

  • https://golang.org/pkg/encoding/xml/#Unmarshal

    If the XML element contains a sub-element whose name matches the prefix of a tag formatted as "a" or "a>b>c", unmarshal will descend into the XML structure looking for elements with the given names, and will map the innermost elements to that struct field. A tag starting with ">" is equivalent to one starting with the field name followed by ">".

    type PostResponse struct {
        PostID     string `xml:"Body>postResponse>return>postResult>postId"`
        PostNumber string `xml:"Body>postResponse>return>postNumber"`
    }
    

    https://play.golang.org/p/EpGP_PmjclX