xml - 如何编组和解组具有不规则属性的 XML
问题描述
我有一个 XML,其中不同的实体用相同的标签表示但具有不同的属性。像这样的东西:
<xml>
<body>
<Packet type="clients">
<Row id="123" name="bill"/>
<Row id="456" name="sasha"/>
</Packet>
<Packet type="orders">
<Row sum="90" status="DONE" />
<Row sum="190" status="DONE" />
</Packet>
</body>
</xml>
保证每种类型只有一个数据包。
不幸的是,改变 XML 的结构不是我的责任,我必须照原样处理它。在 Go 中处理这种结构的最佳方法是什么?我是否应该拥有一个具有所有可能属性的结构,并为每个“数据包”填充正确的结构?
type XML struct {
XMLName xml.Name `xml:"xml"`
Body struct {
Packet []struct {
Type string `xml:"type,attr"`
Row []struct {
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
Sum string `xml:"sum,attr"`
Status string `xml:"status,attr"`
} `xml:"Row"`
} `xml:"Packet"`
} `xml:"body"`
}
这似乎可行,但很不方便,因为实际上我有许多不同类型的数据包,它们具有不同的属性。
或者也许有办法将数据包映射到不同的 Go 结构?像这样的东西:
type XML struct {
XMLName xml.Name `xml:"xml"`
Body struct {
ClientPacket struct {
Type string `xml:"type,attr"`
Row []struct {
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
} `xml:"Row"`
} `xml:"Packet"` // ???
OrderPacket struct {
Type string `xml:"type,attr"`
Row []struct {
Sum string `xml:"sum,attr"`
Status string `xml:"status,attr"`
} `xml:"Row"`
} `xml:"Packet"` // ???
} `xml:"body"`
}
后者似乎更聪明,更易读的例子,但我不明白如何用它来编组和解组 xml。
解决方案
我可以想到几种方法可以实现这一点:您可以尝试已经描述的方法,使用包含所有可能属性的结构。这会很乏味但很容易。您还可以尝试为以下内容编写自定义解组器Packet
:
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
实例的哪些元素是非空的,并使用它。
推荐阅读
- java - 在 getter 和 setter 方法中将 LocalDate 解析为 String
- python - Python中的多线程:迭代器中对象的并行比较
- python - 如何将鼠标点击信号连接到 pyqtgraph 绘图小部件
- python-3.x - 仅执行第一个命令并重定向到控制台窗口
- python - 如何创建具有特定范围内的值的numpy数组?
- php - 手动创建一个空的 PDO 记录集
- javascript - 单击图像后如何导航到另一个页面
- python - 如何将负 datetime.timedelta 转换为正 datetime.timedelta 值
- angularjs - Angular Calendar 获取当前周、前几周和下周
- asp.net-core - .net Core 选择下拉菜单很慢