如何封送和取消封送具有不规则属性的XML
我有一个XML,其中不同的实体用相同的标记表示,但属性不同。大概是这样的:如何封送和取消封送具有不规则属性的XML,xml,go,attributes,marshalling,unmarshalling,Xml,Go,Attributes,Marshalling,Unmarshalling,我有一个XML,其中不同的实体用相同的标记表示,但属性不同。大概是这样的: 保证每种类型只有一个数据包 不幸的是,改变XML的结构不是我的责任,我必须按原样处理它。在Go中处理此类结构的最佳方法是什么?我是否应该拥有一个包含所有可能属性的结构,并为每个“数据包”填充正确的属性 类型XML结构{ XMLName xml.Name`xml:“xml”` 身体结构{ 数据包[]结构{ 类型字符串`xml:“类型,属性”` 行[]结构{ ID字符串`xml:“ID,attr”` 名称字符串`xml:
保证每种类型只有一个数据包
不幸的是,改变XML的结构不是我的责任,我必须按原样处理它。在Go中处理此类结构的最佳方法是什么?我是否应该拥有一个包含所有可能属性的结构,并为每个“数据包”填充正确的属性
类型XML结构{
XMLName xml.Name`xml:“xml”`
身体结构{
数据包[]结构{
类型字符串`xml:“类型,属性”`
行[]结构{
ID字符串`xml:“ID,attr”`
名称字符串`xml:“名称,属性”`
Sum字符串`xml:“Sum,attr”`
状态字符串`xml:“状态,属性”`
}`xml:“行”`
}`xml:“数据包”`
}`xml:“正文”`
}
这似乎是可行的,但相当不方便,因为在现实中,我有很多不同类型的数据包,具有不同属性的负载
或者有办法将数据包映射到不同的Go结构?大概是这样的:
类型XML结构{
XMLName xml.Name`xml:“xml”`
身体结构{
ClientPacket结构{
类型字符串`xml:“类型,属性”`
行[]结构{
ID字符串`xml:“ID,attr”`
名称字符串`xml:“名称,属性”`
}`xml:“行”`
}`xml:'Packet`/???
OrderPacket结构{
类型字符串`xml:“类型,属性”`
行[]结构{
Sum字符串`xml:“Sum,attr”`
状态字符串`xml:“状态,属性”`
}`xml:“行”`
}`xml:'Packet`/???
}`xml:“正文”`
}
后者看起来更聪明、可读性更强,但我不知道如何使用它封送和解封xml 我可以想出几种方法来实现这一点:您可以尝试前面描述的方法,使用包含所有可能属性的结构。这将是乏味但容易的。您还可以尝试为
数据包编写自定义解组器:
type PacketXML struct {
A *PacketTypeA
B *PacketTypeB
...
}
func (x *PacketXML) UnmarshalXML(d *Decoder, start StartElement) error {
// Look at start attributes, find out what type of packet it has
packetType:=findAttr(start,"type")
switch packetType {
case "typeA":
x.A=&PacketTypeA{}
return d.Decode(x.A)
case "typeB":
x.B=&PacketTypeB{}
return d.Decode(x.B)
...
}
return nil
}
完成所有操作后,您可以检查PacketXML
实例的哪个元素是非nill,并使用它。在编组之前首先转换文件(例如使用XSLT)。您可以尝试“检测”您拥有的数据类型和Marshmall以不同的方式进行封送,我最终使用了这个库,它提供了对结果XML的所有控制:以及每个“数据包”的单独结构(但使用相同的接口包装)。从结构到xmlwriter类型的转换可以通过反射完成,也可以不通过反射完成(对于每个结构)。