9

I am new to golang and Soap and having trouble in parsing soap msg.

1.I have an Soap message

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<activationPack_completeResponse"http://tempuri.org/">
<activationPack_completeResult xsi:type="xsd:string">Active</activationPack_completeResult>
</activationPack_completeResponse>
</soap:Body>
</soap:Envelope>

Now how should i Unmarshal them in golang what should be my struct declaration for tag Soap Envelope.

I have some structure as below:

type MyRespEnvelope struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
    Soap    *Body
}
type Body struct {
    XMLName     xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
    GetResponse *ActivationPack_CompleteResponse
}
type ActivationPack_CompleteResponse struct {
    XMLName xml.Name `xml:"activationPack_completeResponse"`
    Id      string   `xml:"xmlns,attr"`
    MyVar   string   `xml:"activationPack_completeResult"`
} 

But I am getting error as below:

error: expected element <Envelope> in name space http://schemas.xmlsoap.org/soap/envelope/ but have soap*stopped,reason="end-stepping-range",frame={addr="0x0000000000401211",func="main.UnmarshalFirstDitto",args=[{name="data",value="\"\\nNotice: Undefined variable: area in /var/www/nusoap/dittotv.php on line 25\\n\\nNotice: Undefined variable: area in /var/www/nusoap/dittotv.php on line 27\\n\\nNotice: Undefined variable: area in /var/www/nu\"..."}],file="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",fullname="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",line="60"},thread-id="1",stopped-threads="all",core="0"

So someone please tell me how should i declare my structure so that i am able to parse the soap message.

user
  • 2,298
  • 6
  • 19
  • 24
  • 1
    Are you sure the document you're trying to parse is actually XML? The error message makes it sound like you are trying to parse a (non-XML) error from a PHP script – James Henstridge May 13 '14 at 06:09
  • @JamesHenstridge Yes i am. But for my knowledge what field make you feel that php is returning error – user May 13 '14 at 06:12
  • 1
    Part of the error reads `args=[{name="data",value="\"\\nNotice: Undefined variable: area in /var/www/nusoap/dittotv.php on line 25\\n...` – James Henstridge May 13 '14 at 06:14
  • @JamesHenstridge Ok let me check it once – user May 13 '14 at 06:16
  • @JamesHenstridge You were right i have fixed the same in my php script but even now i am getting approximate same error – user May 13 '14 at 06:24
  • My resp Xml Mobile Number is string type 9650104435 – user May 13 '14 at 06:25
  • Error Received: error: expected element in name space http://schemas.xmlsoap.org/soap/envelope/ but have soap*stopped,reason="end-stepping-range",frame={addr="0x0000000000401211",func="main.UnmarshalFirstDitto",args=[{name="data",value="\" – user May 13 '14 at 06:26
  • @JamesHenstridge ,file="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",fullname="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",line="60"},thread-id="1",stopped-threads="all",core="0" – user May 13 '14 at 06:29
  • Is there an `xmlns:soap` attribute on the top level `` element? I don't see it on the sample message in the question, and it is required for the document to parse correctly. – James Henstridge May 13 '14 at 07:07
  • @JamesHenstridge No but there is xmlns:SOAP-ENV field which is generated by nusoap in PHP – user May 13 '14 at 07:13
  • 3
    That's not how XML namespaces work. In order to use the `soap:` prefix on elements and attributes, there must be an `xmlns:soap` attribute binding the prefix to a namespace URI. The `xmlns:SOAP-ENV` attribute would let you use e.g. ``. Perhaps try feeding the document to the `xmllint` tool to verify that it is valid. – James Henstridge May 13 '14 at 07:23
  • @JamesHenstridge I have modified nusoap.php And my xml response is 9650104435 – user May 13 '14 at 07:55
  • @JamesHenstridge But now i am getting following error error: XML syntax error on line 1: expected attribute name in element*stopped,reason="end-stepping-range",frame={addr="0x0000000000401026",func="main.FirstDitto",args=[],file="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",fullname="/media/winshare/Golang/WorkSpace/src/DittoTv/ditto.go",line="52"},thread-id="1",stopped-threads="all",core="0" I am new to php soap and golang please help – user May 13 '14 at 07:56
  • 2
    Have you tried running the document through `xmllint` to see if it is actually valid? – James Henstridge May 13 '14 at 08:29

1 Answers1

11
  1. Your XML was malformed, I assume it's a bad copy-paste. I corrected it, line 4: <activationPack_completeResponse"http://tempuri.org/"> -> <activationPack_completeResponse Id="http://tempuri.org/">

  2. Your types were wrong. in MyRespEnvelopeyou call the Body struct Soap. Without defining its xml name you're not going to get anything. An easier fix is to change the name from Soap to Body.

  3. I'm not an expert in XML, but I think you were doing something wrong with namespaces. simplifying your types a little, here is a working example: http://play.golang.org/p/957GWzfdvN

    package main
    
    import "fmt"
    import "encoding/xml"
    
    type MyRespEnvelope struct {
        XMLName xml.Name
        Body    Body
    }
    
    type Body struct {
        XMLName     xml.Name
        GetResponse completeResponse `xml:"activationPack_completeResponse"`
    }
    
    type completeResponse struct {
        XMLName xml.Name `xml:"activationPack_completeResponse"`
        Id      string   `xml:"Id,attr"`
        MyVar   string   `xml:"activationPack_completeResult"`
    }
    
    func main() {
    
        Soap := []byte(`<?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
    <soap:Body>
    <activationPack_completeResponse Id="http://tempuri.org/">
    <activationPack_completeResult xsi:type="xsd:string">Active</activationPack_completeResult>
    </activationPack_completeResponse>
    </soap:Body>
    </soap:Envelope>`)
    
        res := &MyRespEnvelope{}
        err := xml.Unmarshal(Soap, res)
    
        fmt.Println(res.Body, err)
    }
    

    Note: In the code I put together, I don't use pointer to structs but the structs themselves. You can use either depending on how you're intending to use it, and your preferences I guess.

Martin Tournoij
  • 23,567
  • 24
  • 90
  • 127
Dean Elbaz
  • 1,880
  • 14
  • 17