我遇到一个问题,即API在响应中返回两个嵌套的XML数组,名称为rowset
,但元素不同。尝试解组成结构会导致错误field "Attackers" with tag "rowset>row" conflicts with field "Items" with tag "rowset>row"
。
它们都具有唯一的属性name
。是否可以使用此属性影响解析器?
答案 0 :(得分:1)
这很好用,请在The Go Playground上尝试:
package main
import (
"encoding/xml"
"fmt"
)
func main() {
var v *KillMailsXML
if err := xml.Unmarshal([]byte(str), &v); err != nil {
panic(err)
}
for _, ks := range v.Kills {
for _, rs := range ks.Rowsets {
fmt.Println(rs.Who, rs.Rows)
}
}
}
type KillMailsXML struct {
Kills []struct {
// Generic kill information
KillID int64 `xml:"killID,attr"`
Hash string
SolarSystemID int64 `xml:"solarSystemID,attr"`
MoonID int64 `xml:"moonID,attr"`
// Victim Information
Victim struct {
AllianceID int64 `xml:"allianceID,attr"`
AllianceName string `xml:"allianceName,attr"`
CharacterID int64 `xml:"characterID,attr"`
CharacterName string `xml:"characterName,attr"`
CorporationID int64 `xml:"corporationID,attr"`
CorporationName string `xml:"corporationName,attr"`
DamageTaken int64 `xml:"damageTaken,attr"`
FactionID int64 `xml:"factionID,attr"`
FactionName string `xml:"factionName,attr"`
ShipTypeID int64 `xml:"shipTypeID,attr"`
X float64 `xml:"x,attr"`
Y float64 `xml:"y,attr"`
Z float64 `xml:"z,attr"`
} `xml:"victim"`
Rowsets []struct {
Who string `xml:"name,attr"` // Attackers or Items
Rows []struct {
// Attackers struct {
AllianceID int64 `xml:"allianceID,attr"`
AllianceName string `xml:"allianceName,attr"`
CharacterID int64 `xml:"characterID,attr"`
CharacterName string `xml:"characterName,attr"`
CorporationID int64 `xml:"corporationID,attr"`
CorporationName string `xml:"corporationName,attr"`
DamageDone int64 `xml:"damageDone,attr"`
FactionID int64 `xml:"factionID,attr"`
FactionName string `xml:"factionName,attr"`
FinalBlow bool `xml:"finalBlow,attr"`
SecurityStatus float64 `xml:"securityStatus,attr"`
ShipTypeID int64 `xml:"shipTypeID,attr"`
WeaponTypeID int64 `xml:"weaponTypeID,attr"`
// }
// Items struct {
QtyDestroyed int64 `xml:"qtyDestroyed,attr"`
QtyDropped int64 `xml:"qtyDropped,attr"`
TypeID int64 `xml:"typeID,attr"`
Flag int64 `xml:"flag,attr"`
Singleton int64 `xml:"singleton,attr"`
// }
} `xml:"row"`
} `xml:"rowset"`
} `xml:"result>rowset>row"`
}
var str = `<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="2">
<currentTime>2016-07-06 05:49:28</currentTime>
<result>
<rowset name="kills" key="killID" columns="killID,solarSystemID,killTime,moonID">
<row killID="54933226" solarSystemID="31001222" killTime="2016-07-03 22:29:19" moonID="0">
<victim characterID="93811169" characterName="Madcat326" corporationID="98008818" corporationName="Haight Industries LLC" allianceID="0" allianceName="" factionID="0" factionName="" damageTaken="63039" shipTypeID="17918" x="59788513854.179" y="-13687850177.3741" z="157817245029.115" />
<rowset name="attackers" columns="characterID,characterName,corporationID,corporationName,allianceID,allianceName,factionID,factionName,securityStatus,damageDone,finalBlow,weaponTypeID,shipTypeID">
<row characterID="91316135" characterName="Celeo Servasse" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="-1.0646369409683" damageDone="7825" finalBlow="1" weaponTypeID="3520" shipTypeID="12003" />
<row characterID="95273329" characterName="Mupoc Kashuken" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="-0.2" damageDone="16656" finalBlow="0" weaponTypeID="31882" shipTypeID="12023" />
<row characterID="94389072" characterName="Johanis Cal-dahari" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="2" damageDone="11999" finalBlow="0" weaponTypeID="24486" shipTypeID="29986" />
<row characterID="92090484" characterName="Foxstar Damaskeenus" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="-0.4" damageDone="10383" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="95708401" characterName="Bibet Shakure" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="-1.3" damageDone="6928" finalBlow="0" weaponTypeID="24490" shipTypeID="29986" />
<row characterID="0" characterName="" corporationID="500020" corporationName="Serpentis" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="0" damageDone="3903" finalBlow="0" weaponTypeID="0" shipTypeID="38659" />
<row characterID="96420826" characterName="D Joker" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="0" damageDone="2858" finalBlow="0" weaponTypeID="2488" shipTypeID="33470" />
<row characterID="0" characterName="" corporationID="500011" corporationName="Angel Cartel" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="0" damageDone="2487" finalBlow="0" weaponTypeID="0" shipTypeID="42127" />
<row characterID="94791823" characterName="chaosInjection" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="-1" damageDone="0" finalBlow="0" weaponTypeID="12267" shipTypeID="29986" />
<row characterID="90957994" characterName="Conner Asanari" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" securityStatus="0.5" damageDone="0" finalBlow="0" weaponTypeID="16521" shipTypeID="22452" />
</rowset>
<rowset name="items" columns="typeID,flag,qtyDropped,qtyDestroyed,singleton">
<row typeID="394" flag="20" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="24427" flag="32" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="2446" flag="87" qtyDropped="1" qtyDestroyed="1" singleton="0" />
<row typeID="28209" flag="87" qtyDropped="2" qtyDestroyed="0" singleton="0" />
<row typeID="4405" flag="15" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="33450" flag="27" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="19215" flag="23" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="2456" flag="87" qtyDropped="5" qtyDestroyed="0" singleton="0" />
<row typeID="26448" flag="93" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="33450" flag="28" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="394" flag="24" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="394" flag="21" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="19215" flag="19" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="4405" flag="14" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="1422" flag="12" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="2048" flag="16" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="26448" flag="94" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="33450" flag="29" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="33450" flag="30" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="2629" flag="5" qtyDropped="1750" qtyDestroyed="0" singleton="0" />
<row typeID="33450" flag="31" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="2281" flag="22" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="19241" flag="25" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="1422" flag="13" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="26448" flag="92" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="1422" flag="11" qtyDropped="0" qtyDestroyed="1" singleton="0" />
</rowset>
</row>
<row killID="54868503" solarSystemID="31000868" killTime="2016-06-30 03:39:22" moonID="0">
<victim characterID="91316135" characterName="Celeo Servasse" corporationID="98134538" corporationName="Wormbro" allianceID="0" allianceName="" factionID="0" factionName="" damageTaken="18472" shipTypeID="11987" x="685670430496.578" y="-376814977944.382" z="-365907110851.975" />
<rowset name="attackers" columns="characterID,characterName,corporationID,corporationName,allianceID,allianceName,factionID,factionName,securityStatus,damageDone,finalBlow,weaponTypeID,shipTypeID">
<row characterID="641035756" characterName="Lenex Raay" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="5.00297218487895" damageDone="1169" finalBlow="1" weaponTypeID="2969" shipTypeID="22444" />
<row characterID="1817541889" characterName="gr33nCO" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-0.1" damageDone="2163" finalBlow="0" weaponTypeID="2456" shipTypeID="22444" />
<row characterID="92060039" characterName="Braxus Deninard" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-0.7" damageDone="1770" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="1734877398" characterName="Pantuf" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="4.9" damageDone="1681" finalBlow="0" weaponTypeID="2456" shipTypeID="22444" />
<row characterID="92941592" characterName="Foedus Latro" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-1.2" damageDone="1663" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="782985098" characterName="AwingendeR" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="1.9" damageDone="1501" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="93802816" characterName="Tycho Loor" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-1.9" damageDone="1405" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="91004291" characterName="Broxis Khoros" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-1.8" damageDone="1228" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="92007576" characterName="Dean Mintar" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="3.1" damageDone="1057" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="91702100" characterName="EMU EVIL" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-1.4" damageDone="792" finalBlow="0" weaponTypeID="2488" shipTypeID="11978" />
<row characterID="95430803" characterName="Violet Dawn" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="1" damageDone="789" finalBlow="0" weaponTypeID="2488" shipTypeID="33157" />
<row characterID="647412341" characterName="Lysus" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-2" damageDone="761" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="91986431" characterName="sHanQ Myteia" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-1" damageDone="497" finalBlow="0" weaponTypeID="2456" shipTypeID="11963" />
<row characterID="90571681" characterName="Pyrric Skloric" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="0.1" damageDone="356" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="964223112" characterName="Tisisan" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="0.9" damageDone="313" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="1039287135" characterName="J3rz11" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="0.4" damageDone="265" finalBlow="0" weaponTypeID="2488" shipTypeID="22444" />
<row characterID="91343130" characterName="Sophia Utama" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="0.6" damageDone="237" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="94149890" characterName="Minnie Sodom" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="2.6" damageDone="225" finalBlow="0" weaponTypeID="2488" shipTypeID="11978" />
<row characterID="91875279" characterName="Derek Itinen" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="0.8" damageDone="210" finalBlow="0" weaponTypeID="2488" shipTypeID="11978" />
<row characterID="1556079273" characterName="Alita Hayes" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-0.1" damageDone="186" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="2086742079" characterName="Turd Destroyer" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="3.3" damageDone="115" finalBlow="0" weaponTypeID="22444" shipTypeID="22444" />
<row characterID="91044028" characterName="Viktoria Bernhardt" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="2.8" damageDone="89" finalBlow="0" weaponTypeID="28215" shipTypeID="11978" />
<row characterID="941167595" characterName="Justin Cody" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="1.6" damageDone="0" finalBlow="0" weaponTypeID="15891" shipTypeID="11969" />
<row characterID="686125406" characterName="NoobMan" corporationID="98040755" corporationName="Hard Knocks Inc." allianceID="99005065" allianceName="Hard Knocks Citizens" factionID="0" factionName="" securityStatus="-0.1" damageDone="0" finalBlow="0" weaponTypeID="2873" shipTypeID="11186" />
</rowset>
<rowset name="items" columns="typeID,flag,qtyDropped,qtyDestroyed,singleton">
<row typeID="16455" flag="30" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="16455" flag="28" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="31366" flag="92" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="16487" flag="32" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="6005" flag="19" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="16487" flag="31" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="29011" flag="5" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="31366" flag="93" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="29009" flag="5" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="13970" flag="11" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="13982" flag="12" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="2048" flag="14" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="18712" flag="13" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="20353" flag="15" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="16455" flag="27" qtyDropped="1" qtyDestroyed="0" singleton="0" />
<row typeID="16455" flag="29" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="2488" flag="87" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="41155" flag="20" qtyDropped="0" qtyDestroyed="1" singleton="0" />
<row typeID="1952" flag="20" qtyDropped="1" qtyDestroyed="0" singleton="0" />
</rowset>
</row>
</rowset>
</result>
<cachedUntil>2016-07-06 06:16:28</cachedUntil>
</eveapi>`
答案 1 :(得分:1)
如果您无法更改xml
数据的结构,请按照以下步骤推迟解组rowset
(可在Go Playground找到工作示例):
rowset
以外与victim
相关的元素。在此步骤中,rowset
将被解组为原始XML数据。Decoder.DecodeElement
单独解码原始XML。 首先声明数据结构如下(省略Victim
,Attacker
,Item
的声明:
type Kill struct{
// Generic kill information
KillID int64 `xml:"killID,attr"`
Hash string
SolarSystemID int64 `xml:"solarSystemID,attr"`
MoonID int64 `xml:"moonID,attr"`
// Victim Information
Victim Victim `xml:"victim"`
RawAttackersItems []byte `xml:",innerxml" json:"-"`
Attackers []Attacker `xml:"-"`
Items []Item `xml:"-"`
}
type Kills struct {
Kills []Kill `xml:"result>rowset>row"`
}
接下来,用于解组xml的代码行:
//Step (1). Unmarshal to Kills
v := &Kills{}
if err := xml.Unmarshal([]byte(xmlText()), v); err != nil {
fmt.Printf("Error unmarshaling: %v\n", err)
return
}
//Step (2). Decode attackers and items related to victim
for i, k := range v.Kills {
v.Kills[i].Attackers, v.Kills[i].Items = decodeAttackerAndItems(k.RawAttackersItems)
}
最后是解码器功能:
func decodeAttackerAndItems(data []byte) ([]Attacker, []Item) {
xmlReader := bytes.NewReader(data)
decoder := xml.NewDecoder(xmlReader)
const (
unknown int = iota
attackers
items
)
rowset := unknown
attackerList := []Attacker{}
itemList := []Item{}
for {
t, _ := decoder.Token()
if t == nil {
break
}
switch se := t.(type) {
case xml.StartElement:
if se.Name.Local == "rowset" {
rowset = unknown
for _, attr := range se.Attr {
if attr.Name.Local == "name" {
if attr.Value == "attackers" {
rowset = attackers
break
} else if attr.Value == "items" {
rowset = items
break
}
}
}
} else if se.Name.Local == "row" {
switch rowset {
case attackers:
a := Attacker{}
if err := decoder.DecodeElement(&a, &se); err == nil {
attackerList = append(attackerList, a)
}
case items:
it := Item{}
if err := decoder.DecodeElement(&it, &se); err == nil {
itemList = append(itemList, it)
}
}
}
}
}
return attackerList, itemList
}