Go 解组XML:根据属性值使用不同的目标类型

Go 解组XML:根据属性值使用不同的目标类型,go,Go,我想使用另一种类型根据父节点的name属性来解组子节点的XML内容 在下面的示例中,我有两个子节点,属性为“apple”和“peach”。当属性为“Apple”时,我想使用typeApple;当属性为“Peach”时,我想使用Peach。基本上,Apple和Peach有非常不同的结构,所以这就是场景。我将如何做到这一点,或者建议的方法是什么 下面是解决此问题的基本设置 红色 中等的 var x=`…`//xml 类型元素结构{ 节点[]结构{ 名称字符串`xml:“名称,属性”` }`xml

我想使用另一种类型根据父节点的name属性来解组子节点的XML内容

在下面的示例中,我有两个子节点,属性为“apple”和“peach”。当属性为
“Apple”
时,我想使用type
Apple
;当属性为
“Peach”
时,我想使用
Peach
。基本上,
Apple
Peach
有非常不同的结构,所以这就是场景。我将如何做到这一点,或者建议的方法是什么

下面是解决此问题的基本设置


红色
中等的
var x=`…`//xml
类型元素结构{
节点[]结构{
名称字符串`xml:“名称,属性”`
}`xml:“节点”`
苹果
桃子
}
键入Apple结构{//如果名称为“Apple”,请使用此结构
色串
} 
键入Peach结构{//如果名称为“Peach”,请使用此结构
大小字符串
}
func main(){
e:=元素{}
错误:=xml.Unmarshal([]字节(x),&e)
如果错误!=零{
恐慌(错误)
}   
fmt.Println(如苹果色)
fmt.Println(e.Peach.Size
}

您只需在
元素的节点上迭代
类型,并通过打开
名称
属性,创建
苹果
桃子
结构:

对于u,元素:=范围e.节点{
开关元素。名称{
案例“苹果”:
apples=append(apples,Apple{})
“桃子”案:
peaches=append(peaches,Peach{})
}
}

另一个更复杂的解决方案(但也更优雅和实用)是在
元素
类型上实现您自己的
解组XML
方法,这将直接使用适当的类型填充它:

类型Apple struct{
色串
}
类型结构{
大小字符串
}
类型结构{
苹果
桃子
}
类型元素结构{
XMLName xml.Name`xml:“元素”`
节点[]结构{
名称字符串`xml:“名称,属性”`
苹果结构{
颜色字符串`xml:“颜色”`
}`xml:“苹果”`
桃子结构{
大小字符串`xml:“大小”`
}`xml:“peach”`
}`xml:“节点”`
}
func(f*Fruits)解组xml(d*xml.Decoder,start xml.StartElement)错误{
变量元素
d、 解码元素(&元素,&开始)
对于1,el:=范围元素.Nodes{
开关el.Name{
案例“苹果”:
f、 苹果=附加(f.苹果,苹果{
颜色:el.Apple.Color,
})
“桃子”案:
f、 桃子=附加(f.桃子,桃子{
尺寸:el.Peach.Size,
})
}
}
归零
}
func main(){
f:=水果{}
错误:=xml.Unmarshal([]字节(x),&f)
如果错误!=零{
恐慌(错误)
}
fmt.Println(“苹果:”,f.Apples)
fmt.Println(“桃子”,f.Peaches)
}

结果:


不过,您必须多次解组。为了举例说明,假设
Apple
有“Color”元素,而“Peach”有“Size”元素。现在编辑帖子。检查我建议的替代解决方案。您只需要实现
Fruit
type的unmarshal函数中的逻辑,并对fruits类型调用一次
xml.unmarshal
。我知道您在接口方法中如何处理解析,但这里您只是附加了Apple和Peach的es,你将如何将各自的数据解组到每个苹果和桃子中?完成。如果这回答了你的问题,请告诉我:)是的,我想是的。谢谢:)基本上:你不能这样做。您必须分步解组,或者在解组器上编写命令。@mkopriva感谢您使用
d.Token()
提供的示例@相信没问题,尽管我意识到对于这个例子来说,这有点过分了,因为你所需要的只是得到相同的结果。如果您的go结构看起来更像这样,则更有意义:
Apples: [{red}]
Peaches [{medium}]