使用 xml.Name 将 xml 解组为 [] 结构
unmarshal xml to []structs with xml.Name
问题
我需要将 XML
从第 3 方应用程序解组到我的 GO 结构。
我试过的
我创建了结构并且能够从我的代码中生成相同的 XML
。
@see TestMetaData_Marshal
有效的 XML
我简化了这个例子的xml:
<Parent>
<Name>tic.TEST</Name>
<MetaData>
<LawFormID Type="129" DefinedSize="3">DOO</LawFormID>
<FirmUQ Type="129" DefinedSize="15">BARTOG</FirmUQ>
<FirmDescription Type="200" DefinedSize="100">Bartog d.o.o. Trebnje</FirmDescription>
</MetaData>
</Parent>
结构
我对应的结构如下。
注意:我为元数据创建了一个结构,但我宁愿不使用它(由于json,yaml)
type Parent struct {
Name string
MetaData []Node `xml:"MetaData>any"`
}
type Node struct {
XMLName xml.Name // this allows custom node names
Type int `xml:"Type,attr,omitempty"`
DefinedSize int `xml:"DefinedSize,attr,omitempty"`
Text string `xml:",chardata"` // required at some places, cannot omit
}
@TestMetadata_Marshal
func TestMetaData_Marshal(t *testing.T) {
parent := Parent{
Name: "tic.TEST",
MetaData: []Node{
{
XMLName: xml.Name{
Local: "LawFormID",
},
Text: "DOO",
Type: 129,
DefinedSize: 3,
}, {
XMLName: xml.Name{
Local: "FirmUQ",
},
Text: "BARTOG",
Type: 129,
DefinedSize: 15,
}, {
XMLName: xml.Name{
Local: "FirmDescription",
},
Text: "Bartog d.o.o. Trebnje",
Type: 200,
DefinedSize: 100,
},
}, // \MetaData
}
HaveXML := XML(parent)
fmt.Println(HaveXML)
if ValidXML != HaveXML {
t.Error(fmt.Errorf("marshaled XML did not match. Have: %v", HaveXML))
}
}
解组
这就是麻烦的开始;测试 func
很简单;结果是 MetaData
中没有条目可用。
我尝试了很多不同的 tag
s,还尝试创建自己的 MetaData
struct
包含 Items []Node
func TestUnmarshal() {
var parent Parent
err := xml.Unmarshal([]byte(ValidXML), &parent)
if err != nil {
fmt.Println(err)
return
}
HaveXML := XML(parent)
if ValidXML == HaveXML {
fmt.Println("\tmarshaled XML is Valid")
} else {
fmt.Printf("\tmarshaled XML did not match. Have:\n%v\n", HaveXML)
}
}
开始游戏(将测试变成 'normal' 函数
https://goplay.tools/snippet/kWS29HR7O9t
问题
在go&xml中不能这样做吗?
如果有可能,我做错了什么?
问题是 any
不是标签名,它是一个选项。所以使用的时候要在前面加上逗号,e.g. xml:",any"
.
我不认为你可以将它与 >
结合起来,所以创建一个单独的 MetaData
结构:
type Parent struct {
Name string
MetaData MetaData `xml:"MetaData"`
}
type MetaData struct {
Nodes []Node `xml:",any"`
}
通过此重构您的示例工作和输出(在 Go Playground 上尝试):
=== TestMarshal
<Parent>
<Name>tic.TEST</Name>
<MetaData>
<LawFormID Type="129" DefinedSize="3">DOO</LawFormID>
<FirmUQ Type="129" DefinedSize="15">BARTOG</FirmUQ>
<FirmDescription Type="200" DefinedSize="100">Bartog d.o.o. Trebnje</FirmDescription>
</MetaData>
</Parent>
marshaled XML is Valid
=== TestUnmarshal
marshaled XML is Valid
问题
我需要将 XML
从第 3 方应用程序解组到我的 GO 结构。
我试过的
我创建了结构并且能够从我的代码中生成相同的 XML
。
@see TestMetaData_Marshal
有效的 XML
我简化了这个例子的xml:
<Parent>
<Name>tic.TEST</Name>
<MetaData>
<LawFormID Type="129" DefinedSize="3">DOO</LawFormID>
<FirmUQ Type="129" DefinedSize="15">BARTOG</FirmUQ>
<FirmDescription Type="200" DefinedSize="100">Bartog d.o.o. Trebnje</FirmDescription>
</MetaData>
</Parent>
结构
我对应的结构如下。 注意:我为元数据创建了一个结构,但我宁愿不使用它(由于json,yaml)
type Parent struct {
Name string
MetaData []Node `xml:"MetaData>any"`
}
type Node struct {
XMLName xml.Name // this allows custom node names
Type int `xml:"Type,attr,omitempty"`
DefinedSize int `xml:"DefinedSize,attr,omitempty"`
Text string `xml:",chardata"` // required at some places, cannot omit
}
@TestMetadata_Marshal
func TestMetaData_Marshal(t *testing.T) {
parent := Parent{
Name: "tic.TEST",
MetaData: []Node{
{
XMLName: xml.Name{
Local: "LawFormID",
},
Text: "DOO",
Type: 129,
DefinedSize: 3,
}, {
XMLName: xml.Name{
Local: "FirmUQ",
},
Text: "BARTOG",
Type: 129,
DefinedSize: 15,
}, {
XMLName: xml.Name{
Local: "FirmDescription",
},
Text: "Bartog d.o.o. Trebnje",
Type: 200,
DefinedSize: 100,
},
}, // \MetaData
}
HaveXML := XML(parent)
fmt.Println(HaveXML)
if ValidXML != HaveXML {
t.Error(fmt.Errorf("marshaled XML did not match. Have: %v", HaveXML))
}
}
解组
这就是麻烦的开始;测试 func
很简单;结果是 MetaData
中没有条目可用。
我尝试了很多不同的 tag
s,还尝试创建自己的 MetaData
struct
包含 Items []Node
func TestUnmarshal() {
var parent Parent
err := xml.Unmarshal([]byte(ValidXML), &parent)
if err != nil {
fmt.Println(err)
return
}
HaveXML := XML(parent)
if ValidXML == HaveXML {
fmt.Println("\tmarshaled XML is Valid")
} else {
fmt.Printf("\tmarshaled XML did not match. Have:\n%v\n", HaveXML)
}
}
开始游戏(将测试变成 'normal' 函数
https://goplay.tools/snippet/kWS29HR7O9t
问题
在go&xml中不能这样做吗? 如果有可能,我做错了什么?
问题是 any
不是标签名,它是一个选项。所以使用的时候要在前面加上逗号,e.g. xml:",any"
.
我不认为你可以将它与 >
结合起来,所以创建一个单独的 MetaData
结构:
type Parent struct {
Name string
MetaData MetaData `xml:"MetaData"`
}
type MetaData struct {
Nodes []Node `xml:",any"`
}
通过此重构您的示例工作和输出(在 Go Playground 上尝试):
=== TestMarshal
<Parent>
<Name>tic.TEST</Name>
<MetaData>
<LawFormID Type="129" DefinedSize="3">DOO</LawFormID>
<FirmUQ Type="129" DefinedSize="15">BARTOG</FirmUQ>
<FirmDescription Type="200" DefinedSize="100">Bartog d.o.o. Trebnje</FirmDescription>
</MetaData>
</Parent>
marshaled XML is Valid
=== TestUnmarshal
marshaled XML is Valid