我正在从golang生成SOAP消息(xml)。我有下面的例子:
package main
import (
"encoding/xml"
"fmt"
)
type Envelope struct {
XMLName xml.Name `xml:"Envelope"`
}
func main() {
envelope := Envelope{
XMLName: xml.Name{
Local: "soapenv",
Space: "http://www.w3.org/2003/05/soap-envelope",
},
}
res, _ := xml.Marshal(envelope)
fmt.Print(string(res))
}
程序输出如下
<Envelope></Envelope>
我想得到的输出与命名空间前缀如下,
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"></soapenv:Envelope>
有人能帮我得到我想要的输出吗??
您可以显式地将xmlns
属性添加到您的结构定义中:
type Envelope struct {
XMLName xml.Name `xml:"soapenv:Envelope"`
SoapEnv string `xml:"xmlns:soapenv,attr"`
}
然后实例化:
e := Envelope{
SoapEnv: "http://www.w3.org/2003/05/soap-envelope",
}
https://go.dev/play/p/LrKNg8PTK2A
输出:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"></soapenv:Envelope>
查看XML文档示例获取更多XML自定义。
anseo的答案可以按照您想要的方式生成XML。但是生成的XML看起来像是来自一个有效的模型,但实际上不是。您将无法用相同的结构定义对该XML进行反编组。
我一整天都在摆弄(反)序列化xml,最终得到了它应该如何工作的线索:您需要完全限定xml标记中的每个节点。这就是需要放在标签中定义的名称前面的名称空间(不仅仅是前缀):
type Envelope struct {
XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
}
但是你仍然不会得到你想要的东西。它很可能看起来像这样:
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope"></Envelope>
但至少这是有效的XML,应该适合您的用例(假设您的工具链中的其他工具运行良好)。这样您就可以成功地解组XML了。
问题是,如果您确实有多个名称空间或需要在属性上使用名称空间,会发生什么?同样的道理,在所有标签前加上命名空间url。Marshal()将整理如何处理它,例如动态创建命名空间前缀。
例子:
type XMI struct {
XMLName xml.Name `xml:"http://schema.omg.org/spec/XMI/2.1 XMI"`
Version string `xml:"http://schema.omg.org/spec/XMI/2.1 version,attr"`
Model *Model `xml:"http://www.eclipse.org/uml2/5.0.0/UML Model"`
}
生成如下XML:
<XMI xmlns="http://schema.omg.org/spec/XMI/2.1" xmlns:_="http://schema.omg.org/spec/XMI/2.1" _:version="2.1">
<Model xmlns="http://www.eclipse.org/uml2/5.0.0/UML" _:id="a7e26bff-10a4-44f7-b225-80e079d812c8" name="model">
<packagedElement _:id="7c141da5-fccf-4da8-8fb8-53bf550f2cfc" xmlns:_XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" _XMLSchema-instance:type="uml:PrimitiveType" name="char"></packagedElement>
</Model>
</XMI>
可以看到,Marshal()将在需要时为元素生成默认的名称空间,并为属性生成(计算的)名称空间前缀。有效的XML,但我不得不承认很难阅读。
相比其他人说golang的encoding/xml是坏的,我认为它只是…不方便。