解析XML命名空间节点

huangapple go评论77阅读模式
英文:

Parsing XML namespaced nodes

问题

我对Go相对较新,但在一个基本任务上遇到了困难。我正在使用"encoding/xml"包解析一个GPX文件,并有以下示例xml数据;

<gpx creator="StravaGPX" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
 <metadata>
  <time>2013-02-16T10:11:25Z</time>
 </metadata>
 <trk>
  <name>Demo Data</name>
  <trkseg>
   <trkpt lat="51.6395658" lon="-3.3623858">
    <ele>111.6</ele>
    <time>2013-02-16T10:11:25Z</time>
    <extensions>
     <gpxtpx:TrackPointExtension>
      <gpxtpx:atemp>8</gpxtpx:atemp>
      <gpxtpx:hr>136</gpxtpx:hr>
      <gpxtpx:cad>0</gpxtpx:cad>
     </gpxtpx:TrackPointExtension>
    </extensions>
   </trkpt>

到目前为止,我能够使用以下类型获取最基本的信息;

type Gpx struct {
	Creator string `xml:"creator,attr"`
	Time string `xml:"metadata>time"`
	Title string `xml:"trk>name"`
	TrackPoints []TrackPoint `xml:"trk>trkseg>trkpt"`
}

type TrackPoint struct {
	Lat float64 `xml:"lat,attr"`
	Lon float64 `xml:"lon,attr"`
	Elevation float32 `xml:"ele"`
	Time string `xml:"time"`
	Temperature int `xml:"extensions>gpxtpx>atemp"`
}

我在TrackPoint.Temperature的解析中失败了。我无法正确匹配扩展节点下的命名空间节点。

有关我出错的地方有什么建议吗?

英文:

I am relatively new to Go but struggling with a basic task. I am parsing a GPX file using the "encoding/xml" package and have the following example xml data;

&lt;gpx creator=&quot;StravaGPX&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.topografix.com/GPX/1/1&quot; 

xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd&quot; xmlns:gpxtpx=&quot;http://www.garmin.com/xmlschemas/TrackPointExtension/v1&quot; xmlns:gpxx=&quot;http://www.garmin.com/xmlschemas/GpxExtensions/v3&quot;&gt;
 &lt;metadata&gt;
  &lt;time&gt;2013-02-16T10:11:25Z&lt;/time&gt;
 &lt;/metadata&gt;
 &lt;trk&gt;
  &lt;name&gt;Demo Data&lt;/name&gt;
  &lt;trkseg&gt;
   &lt;trkpt lat=&quot;51.6395658&quot; lon=&quot;-3.3623858&quot;&gt;
    &lt;ele&gt;111.6&lt;/ele&gt;
    &lt;time&gt;2013-02-16T10:11:25Z&lt;/time&gt;
    &lt;extensions&gt;
     &lt;gpxtpx:TrackPointExtension&gt;
      &lt;gpxtpx:atemp&gt;8&lt;/gpxtpx:atemp&gt;
      &lt;gpxtpx:hr&gt;136&lt;/gpxtpx:hr&gt;
      &lt;gpxtpx:cad&gt;0&lt;/gpxtpx:cad&gt;
     &lt;/gpxtpx:TrackPointExtension&gt;
    &lt;/extensions&gt;
   &lt;/trkpt&gt;

So far I am able to get at the most basic info with the following types;

type Gpx struct {
	Creator string `xml:&quot;creator,attr&quot;`
	Time string `xml:&quot;metadata&gt;time&quot;`
	Title string `xml:&quot;trk&gt;name&quot;`
	TrackPoints []TrackPoint `xml:&quot;trk&gt;trkseg&gt;trkpt&quot;`
}

type TrackPoint struct {
	Lat float64 `xml:&quot;lat,attr&quot;`
	Lon float64 `xml:&quot;lon,attr&quot;`
	Elevation float32 `xml:&quot;ele&quot;`
	Time string `xml:&quot;time&quot;`
	Temperature int `xml:&quot;extensions&gt;gpxtpx&gt;atemp&quot;`
}

Where I am failing to parse is in TrackPoint.Temperature. I cannot get the tag right to match the namespaced nodes underneath extensions.

Any suggestions as to where I am going wrong?

答案1

得分: 1

你的TrackPoint.Temperature xml指令中,你正在针对一个命名空间而不是一个变量名进行定位。

Temperature int `xml:"extensions>gpxtpx>atemp"`

改为

Temperature int `xml:"extensions>TrackPointExtension>atemp"`

在playground中,这是一个工作副本。

package main

import (
	"fmt"
	"encoding/xml"
)

type Gpx struct {
    Creator string `xml:"creator,attr"`
    Time string `xml:"metadata>time"`
    Title string `xml:"trk>name"`
    TrackPoints []TrackPoint `xml:"trk>trkseg>trkpt"`
}

type TrackPoint struct {
    Lat float64 `xml:"lat,attr"`
    Lon float64 `xml:"lon,attr"`
    Elevation float32 `xml:"ele"`
    Time string `xml:"time"`
    Temperature int `xml:"extensions>TrackPointExtension>atemp"`
}

func main() {
	data := `<gpx creator="StravaGPX" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
 <metadata>
  <time>2013-02-16T10:11:25Z</time>
 </metadata>
 <trk>
  <name>Demo Data</name>
  <trkseg>
   <trkpt lat="51.6395658" lon="-3.3623858">
    <ele>111.6</ele>
    <time>2013-02-16T10:11:25Z</time>
    <extensions>
     <gpxtpx:TrackPointExtension>
      <gpxtpx:atemp>8</gpxtpx:atemp>
      <gpxtpx:hr>136</gpxtpx:hr>
      <gpxtpx:cad>0</gpxtpx:cad>
     </gpxtpx:TrackPointExtension>
    </extensions>
   </trkpt>
  </trkseg>
 </trk>
`
	g := &Gpx{}
	_ = xml.Unmarshal([]byte(data), g)
	fmt.Printf("len: %d\n", len(g.TrackPoints))
	fmt.Printf("temp: %v\n", g.TrackPoints[0].Temperature)
}
英文:

You're targeting a namespace instead of a variable name in your TrackPoint.Temperature xml instructions.

Change

Temperature int `xml:&quot;extensions&gt;gpxtpx&gt;atemp&quot;`

To

Temperature int `xml:&quot;extensions&gt;TrackPointExtension&gt;atemp&quot;`

<a href="http://play.golang.org/p/992Ozf7fn1">Here's a working copy</a> in the playground.

package main

import (
	&quot;fmt&quot;
	&quot;encoding/xml&quot;
	)

type Gpx struct {
    Creator string `xml:&quot;creator,attr&quot;`
    Time string `xml:&quot;metadata&gt;time&quot;`
    Title string `xml:&quot;trk&gt;name&quot;`
    TrackPoints []TrackPoint `xml:&quot;trk&gt;trkseg&gt;trkpt&quot;`
}

type TrackPoint struct {
    Lat float64 `xml:&quot;lat,attr&quot;`
    Lon float64 `xml:&quot;lon,attr&quot;`
    Elevation float32 `xml:&quot;ele&quot;`
    Time string `xml:&quot;time&quot;`
    Temperature int `xml:&quot;extensions&gt;TrackPointExtension&gt;atemp&quot;`
}

func main() {
	data := `&lt;gpx creator=&quot;StravaGPX&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.topografix.com/GPX/1/1&quot; 

xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd&quot; xmlns:gpxtpx=&quot;http://www.garmin.com/xmlschemas/TrackPointExtension/v1&quot; xmlns:gpxx=&quot;http://www.garmin.com/xmlschemas/GpxExtensions/v3&quot;&gt;
 &lt;metadata&gt;
  &lt;time&gt;2013-02-16T10:11:25Z&lt;/time&gt;
 &lt;/metadata&gt;
 &lt;trk&gt;
  &lt;name&gt;Demo Data&lt;/name&gt;
  &lt;trkseg&gt;
   &lt;trkpt lat=&quot;51.6395658&quot; lon=&quot;-3.3623858&quot;&gt;
    &lt;ele&gt;111.6&lt;/ele&gt;
    &lt;time&gt;2013-02-16T10:11:25Z&lt;/time&gt;
    &lt;extensions&gt;
     &lt;gpxtpx:TrackPointExtension&gt;
      &lt;gpxtpx:atemp&gt;8&lt;/gpxtpx:atemp&gt;
      &lt;gpxtpx:hr&gt;136&lt;/gpxtpx:hr&gt;
      &lt;gpxtpx:cad&gt;0&lt;/gpxtpx:cad&gt;
     &lt;/gpxtpx:TrackPointExtension&gt;
    &lt;/extensions&gt;
   &lt;/trkpt&gt;
  &lt;/trkseg&gt;
 &lt;/trk&gt;
`
	g := &amp;Gpx{}
	_ = xml.Unmarshal([]byte(data), g)
	fmt.Printf(&quot;len: %d\n&quot;, len(g.TrackPoints))
	fmt.Printf(&quot;temp: %v\n&quot;, g.TrackPoints[0].Temperature)
}

huangapple
  • 本文由 发表于 2013年2月19日 06:35:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/14946566.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定