xml.unmarshal не пересекает дерево XML - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь упаковать XML в набор пользовательских структур, и он не работает, как я ожидал.Я ожидаю, что xml.StartElement для каждой из моих функций «UnmarshalXML» будет меняться для каждого объекта, который он обрабатывает (например, TrainingCenterDatabase vs Activities).Кажется, этого не происходит.Мой xml.StartElement всегда является корневым элементом всего XML-файла.

Кроме того, мой окончательно декодированный Struct пуст после завершения Unmarshaling.Я предполагаю, что поскольку передается неправильный «startElement», он не находит никаких значений для анализа.

Что я делаю не так?

Структуры и функции:

func (v *TrainingCenterDatabase) UnmarshalXML(d *xml.Decoder, startElement xml.StartElement) error {
    decodeError := d.DecodeElement(&v.Activities, &startElement)
    fmt.Println("TrainingCenterDatabase StartELement Name: " + startElement.Name.Local)
    if decodeError != nil {
        logging.LogError("tcxhelper - XMLTpxFile.UnmarshalXML Error - "+decodeError.Error(), "")
        return decodeError
    }
    return nil
}

func (v *Activities) UnmarshalXML(d *xml.Decoder, startElement xml.StartElement) error {
    decodeError := d.DecodeElement(&v.Activity, &startElement)
    fmt.Println("Activities StartELement Name: " + startElement.Name.Local)
    if decodeError != nil {
        logging.LogError("tcxhelper - XMLTpxFile.UnmarshalXML Error - "+decodeError.Error(), "")
        return decodeError
    }
    return nil
}

func (v *Activity) UnmarshalXML(d *xml.Decoder, startElement xml.StartElement) error {
    for _, attr := range startElement.Attr {
        fmt.Println("Attr Name: " + attr.Name.Local)
        fmt.Println("Attr Value: " + attr.Value)
    }
    fmt.Println("Activity StartELement Name: " + startElement.Name.Local)

    decodeError := d.DecodeElement(&v.Lap, &startElement)
    if decodeError != nil {
        logging.LogError("tcxhelper - XMLTpxFile.UnmarshalXML Error - "+decodeError.Error(), "")
        return decodeError
    }
    return nil
}

type TpxFile struct {
    TpxFile TrainingCenterDatabase `xml:"TrainingCenterDatabase"`
}

type TrainingCenterDatabase struct {
    Activities Activities `xml:"Activities"`
}

type Activities struct {
    Activity Activity `xml:"Activity"`
}

type Activity struct {
    Sport string    `xml:"Sport"`
    ID    time.Time `xml:"Id"`
    Lap   Lap       `xml:"Lap"`
}

type Lap struct {
    Cadence       string `xml:"Cadence"`
    TriggerMethod string `xml:"TriggerMethod"`
    Track         Track  `xml:"Track"`
}

type Track struct {
    Trackpoint          Trackpoint          `xml:"Trackpoint"`
    MaximumSpeed        string              `xml:"MaximumSpeed"`
    MaximumHeartRateBpm MaximumHeartRateBpm `xml:"MaximumHeartRateBpm"`
    Intensity           string              `xml:"Intensity"`
    Calories            string              `xml:"Calories"`
    AverageHeartRateBpm AverageHeartRateBpm `xml:"AverageHeartRateBpm"`
    StartTime           time.Time           `xml:"StartTime"`
    TotalTimeSeconds    string              `xml:"TotalTimeSeconds"`
    DistanceMeters      string              `xml:"DistanceMeters"`
}

type MaximumHeartRateBpm struct {
    Value string `xml:"Value"`
}

type AverageHeartRateBpm struct {
    Value string `xml:"Value"`
}

type Trackpoint []struct {
    Position       Position     `xml:"Position"`
    AltitudeMeters string       `xml:"AltitudeMeters"`
    DistanceMeters string       `xml:"DistanceMeters"`
    HeartRateBpm   HeartRateBpm `xml:"HeartRateBpm"`
    Cadence        string       `xml:"Cadence"`
    Extensions     Extensions   `xml:"Extensions"`
    Time           time.Time    `xml:"Time"`
}

type Extensions struct {
    TPX TPX `xml:"TPX"`
}

type TPX struct {
    Xmlns string `xml:"xmlns"`
    Speed string `xml:"Speed"`
    Watts string `xml:"Watts"`
}
type HeartRateBpm struct {
    Value string `xml:"Value"`
}

type Position struct {
    LatitudeDegrees  string `xml:"LatitudeDegrees"`
    LongitudeDegrees string `xml:"LongitudeDegrees"`
} 

Код маршалу

func TestMarshalTPX(t *testing.T) {

    fileByteArray, myErr := ioutil.ReadFile("/my/local/directory/Lunch_Ride.tcx")
    if myErr != nil {
        t.Error("Error Reading File: " + myErr.Error())
    }
    tpxFile := TrainingCenterDatabase{}

    marshalError := xml.Unmarshal(fileByteArray, &tpxFile)
    if marshalError != nil {
        t.Error("Marshal Error: " + marshalError.Error())
    }
}

Образец XML:

<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase
  xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"
  xmlns:ns5="http://www.garmin.com/xmlschemas/ActivityGoals/v1"
  xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2"
  xmlns:ns2="http://www.garmin.com/xmlschemas/UserProfile/v2"
  xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <Activities>
  <Activity Sport="Biking">
   <Id>2018-10-16T18:41:12Z</Id>
   <Lap StartTime="2018-10-16T18:41:12Z">
    <TotalTimeSeconds>3732</TotalTimeSeconds>
    <DistanceMeters>26451.5</DistanceMeters>
    <MaximumSpeed>52560.0</MaximumSpeed>
    <Calories>0</Calories>
    <AverageHeartRateBpm>
     <Value>148</Value>
    </AverageHeartRateBpm>
    <MaximumHeartRateBpm>
     <Value>188</Value>
    </MaximumHeartRateBpm>
    <Intensity>Active</Intensity>
    <Cadence>79</Cadence>
    <TriggerMethod>Manual</TriggerMethod>
    <Track>
     <Trackpoint>
      <Time>2018-10-16T18:41:12Z</Time>
      <Position>
       <LatitudeDegrees>39.7711140</LatitudeDegrees>
       <LongitudeDegrees>-105.0392580</LongitudeDegrees>
      </Position>
      <AltitudeMeters>1646.2</AltitudeMeters>
      <DistanceMeters>0.0</DistanceMeters>
      <HeartRateBpm>
       <Value>97</Value>
      </HeartRateBpm>
      <Cadence>69</Cadence>
      <Extensions>
       <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
        <Speed>0.0</Speed>
        <Watts>320</Watts>
       </TPX>
      </Extensions>
     </Trackpoint>
     <Trackpoint>
      <Time>2018-10-16T18:41:13Z</Time>
      <Position>
       <LatitudeDegrees>39.7711120</LatitudeDegrees>
       <LongitudeDegrees>-105.0392590</LongitudeDegrees>
      </Position>
      <AltitudeMeters>1646.2</AltitudeMeters>
      <DistanceMeters>0.2</DistanceMeters>
      <HeartRateBpm>
       <Value>97</Value>
      </HeartRateBpm>
      <Cadence>73</Cadence>
      <Extensions>
       <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
        <Speed>0.2</Speed>
        <Watts>195</Watts>
       </TPX>
      </Extensions>
     </Trackpoint>
    </Track>
   </Lap>
  </Activity>
 </Activities>
</TrainingCenterDatabase>
...