如何在Golang中解析Soap信封?

9

我是新手,对于Golang和Soap不熟悉,并且在解析soap消息时遇到了麻烦。

1.我有一个Soap消息

<?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>

现在该如何在Golang中对它们进行反序列化,我的结构体声明应该包含标记"SOAP Envelope"?

我有以下一些结构:

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"`
} 

但是我遇到了以下错误:

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"

请问如何声明结构体以便于解析SOAP消息?


1
你确定你要解析的文档是XML格式吗?错误信息表明你正在尝试解析一个PHP脚本中的非XML错误。 - James Henstridge
1
错误的一部分为args=[{name="data",value="\"\\n注意:/ var / www / nusoap / dittotv.php第25行中未定义变量:area \\n... - James Henstridge
@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
3
XML命名空间并不是这样工作的。为了在元素和属性中使用“soap:”前缀,必须有一个“xmlns:soap”的属性将前缀绑定到命名空间URI上。如果要使用例如<SOAP-ENV:Envelope>,则需要使用xmlns:SOAP-ENV属性。也许可以尝试将文档提供给xmllint工具以验证其是否有效。 - James Henstridge
2
你是否尝试过使用xmllint运行该文档,以查看其是否真实有效? - James Henstridge
显示剩余9条评论
1个回答

11
  1. 你的XML格式有误,我猜测这可能是由于复制粘贴不当导致的。我修改了第4行:<activationPack_completeResponse"http://tempuri.org/"> -> <activationPack_completeResponse Id="http://tempuri.org/">

  2. 你的类型定义错误。在MyRespEnvelope中,你调用Body结构时使用了Soap,但没有定义它的xml名称,因此你得不到任何结果。更容易的解决方法是将名称从Soap改为Body

  3. 我不是XML方面的专家,但我认为你在命名空间方面出现了问题。为了简化你的类型定义,下面是一个可以工作的示例: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)
}

注意:在我编写的代码中,我没有使用指向结构体的指针,而是直接使用了结构体本身。您可以根据您的意图和个人偏好选择使用其中之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接