Go:解析包含不同实体的 XML 列表

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

Go : Unmarshall XML List containing different entities

问题

我已经给出了以下的XML结构:

<properties>
    <property name="element1">data1</property>
    <property name="element2">data2</property>
    <datetime name="start">13 Jan 2015 14:13:15GMT</datetime>
    <property name="element3">data3</property>
    <property name="element4">data4</property>
    <property name="element5">data5</property>
    <categorisation name="category">cat1</categorisation>
    <property name="element6">data6</property>
    <property name="element7">data7</property>
</properties>

我想要将其解组成以下结构:

type Property struct {
    Name string
    Value string
}

type Properties struct {
    Props []Property 
    DateTime time.Time
    Category string
}

但是我不知道如何处理无序的Properties。

英文:

I have been given the following XML structure

&lt;properties&gt;
    &lt;property name=&quot;element1&quot;&gt;data1&lt;/property&gt;
    &lt;property name=&quot;element2&quot;&gt;data2&lt;/property&gt;
    &lt;datetime name=&quot;start&quot;&gt;13 Jan 2015 14:13:15GMT&lt;/datetime&gt;
    &lt;property name=&quot;element3&quot;&gt;data3&lt;/property&gt;
    &lt;property name=&quot;element4&quot;&gt;data4&lt;/property&gt;
    &lt;property name=&quot;element5&quot;&gt;data5&lt;/property&gt;
    &lt;categorisation name=&quot;category&quot;&gt;cat1&lt;/categorisation&gt;
    &lt;property name=&quot;element6&quot;&gt;data6&lt;/property&gt;
    &lt;property name=&quot;element7&quot;&gt;data7&lt;/property&gt;
&lt;/properties&gt;

I want to unmarshall it into the following:

type Property string {
    Name string
    Value string
}

type Properties struct {
    Props []Property 
    DateTime time.Time
    Category string
}

but I don't know how to process the out of order Properties

答案1

得分: 2

encoding/xml 包可以帮助你处理这个问题。你只需要正确地为结构体字段添加标签,告诉 xml 包它们在 XML 源中的位置:

type Property struct {
    Name  string `xml:"name,attr"`
    Value string `xml:",cdata"`
}

type Properties struct {
    Props    []Property `xml:"property"`
    DateTime string     `xml:"datetime"`
    Category string     `xml:"categorisation"`
}

请注意,我将 DateTime 字段的类型更改为 string,因为 XML 中的时间戳(13 Jan 2015 14:13:15GMT)不符合标准格式(标准格式应为 ISO 8601,在 Go 中的布局为 2006-01-02T15:04:05Z07:00,对应 time.RFC3339)。

解析的代码如下:

ps := Properties{}
if err := xml.Unmarshal([]byte(src), &ps); err != nil {
    panic(err)
}
fmt.Printf("%+v", ps)

输出结果如下(你可以在 Go Playground 上尝试运行):

{Props:[{Name:element1 Value:data1} {Name:element2 Value:data2} {Name:element3 Value:data3}
 {Name:element4 Value:data4} {Name:element5 Value:data5} {Name:element6 Value:data6}
 {Name:element7 Value:data7}] DateTime:13 Jan 2015 14:13:15GMT Category:cat1}

你可以看到,Props 字段正确地按照顺序包含了所有 7 个属性,即使在它们之间插入了 <datetime><categorisation> 标签。

英文:

The encoding/xml package handles that for you. You just have to properly tag your struct fields to tell the xml package how they are found in the XML source:

type Property struct {
	Name  string `xml:&quot;name,attr&quot;`
	Value string `xml:&quot;,cdata&quot;`
}

type Properties struct {
	Props    []Property `xml:&quot;property&quot;`
	DateTime string     `xml:&quot;datetime&quot;`
	Category string     `xml:&quot;categorisation&quot;`
}

Note that I changed the type of DateTime field to string because the timestamp in the XML (13 Jan 2015 14:13:15GMT) does not conform to standard (which would be ISO 8601, in Go layout: 2006-01-02T15:04:05Z07:00 which is time.RFC3339).

Code to unmarshal:

ps := Properties{}
if err := xml.Unmarshal([]byte(src), &amp;ps); err != nil {
	panic(err)
}
fmt.Printf(&quot;%+v&quot;, ps)

Output (try it on the Go Playground):

{Props:[{Name:element1 Value:data1} {Name:element2 Value:data2} {Name:element3 Value:data3}
 {Name:element4 Value:data4} {Name:element5 Value:data5} {Name:element6 Value:data6}
 {Name:element7 Value:data7}] DateTime:13 Jan 2015 14:13:15GMT Category:cat1}

You can see that Props properly contains all 7 properties in correct order even though &lt;datetime&gt; and &lt;categorisation&gt; tags are inserted between them.

huangapple
  • 本文由 发表于 2016年3月3日 21:06:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/35773044.html
匿名

发表评论

匿名网友

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

确定