2016-10-08 3 views
1

Ich habe ein Problem, wo eine API zwei verschachtelte XML-Arrays in einer Antwort beide mit dem Namen rowset aber verschiedene Elemente zurückgibt. Der Versuch, in eine Struktur zu entpacken, verursacht den Fehler field "Attackers" with tag "rowset>row" conflicts with field "Items" with tag "rowset>row".Unmarshal geschachtelte Arrays mit identischem Namen, aber separaten Elementen gehen

Beide haben ein Attribut name, die eindeutig sind. Ist es möglich, den Parser mit diesem Attribut zu beeinflussen?

Siehe Beispiel: https://play.golang.org/p/BinDfC3XsW

+0

Haben Sie in Betracht gezogen, eine Struktur zu deklarieren, die der XML-Struktur ähnelt, und diese dann in Ihre KillMailsXML-Struktur konvertieren? Nach dem Lesen der Dokumentation glaube ich nicht, dass Sie ein Element basierend auf seinem Attribut angeben können. Es ist besser, Angreifer und Items im selben Feld zu haben, dann schreibe einen Konverter, der es korrekt übersetzt –

+0

Wahrscheinlich etwas wie [dies] (https://play.golang.org/p/yAkpMaZ2RW), dann wandle das Ergebnis in die Struktur du gewollt? –

Antwort

1

Wenn Sie nicht die Struktur xml Daten ändern können, dann verschieben rowset mit den folgenden Schritten Deserialisieren (Arbeits Beispiel finden Sie unter Go Playground):

  1. Unmarshal Elemente außer rowset, die sich auf victim beziehen. Während dieses Schritts wird die rowset in Roh-XML-Daten unmarshaliert.
  2. Dekodieren Sie XML-Rohdaten separat mit Decoder.DecodeElement.

zuerst die Datenstruktur wie folgt deklarieren (Erklärung Victim, Attacker wird Item weggelassen):

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"` 
} 

nächstes Codezeilen für Deserialisieren der 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) 
} 

und schließlich die Decoderfunktion:

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 
} 
1

Dies funktioniert, versuchen Sie es auf 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>` 
Verwandte Themen