1

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.

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. But there is an another problem. If the response data is a wrong validation message, the xml structure will be different. I think it's better to check the response data with UnmarshalXML first, then choose use which struct to catch the data. How to loop all the xml element names by go?
You should probably open another question asking how to unmarshal XML that doesn't always have the same structure. Show what you've tried and show the types into which you want to unmarshal them. How does the "wrong validation message" xml look? What is it's structure? Where is it coming from? Is it an HTTP response? If so, can you check the HTTP response's status first and then pass in the correct struct to xml.Unmarshal? Anyway, more info is necessary, trying to fit it into comments is not recommended. Please create a new question.
I created a new question here: stackoverflow.com/questions/66795170/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.