一个简单的 XML 元素如何解组为 Golang 结构体?

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

How does a simple xml element unmarshal to a golang struct?

问题

假设有以下的 XML 元素,其中包含一个属性和一个浮点数值:

<thing prop="1">
  1.23
</thing>
<thing prop="2">
  4.56
</thing>

为了解析它,我应该如何定义我的结构体?

type ThingElem struct {
    Prop  int   `xml:"prop,attr"`
    Value float64 // ???
}

type ThingWrapper struct {
    T ThingElem `xml:"thing"`
}

// 或者

type ThingElem struct {
    XMLName xml.Name `xml:"thing"` // 我是否需要这个属性?
    Prop    int      `xml:"prop,attr"`
    Value   float64  // ???
}

XMLName 属性的使用让我感到困惑。它应该放在结构体中的哪个位置?还是应该作为标签放在一个包装器中?

英文:

Assume the following xml element, with an attribute and a floating point value:

&lt;thing prop=&quot;1&quot;&gt;
  1.23
&lt;/thing&gt;
&lt;thing prop=&quot;2&quot;&gt;
  4.56
&lt;/thing&gt;

In order to unmarshal it, how should I define my struct?

type ThingElem struct {
    Prop  int   `xml:&quot;prop,attr&quot;`
    Value float // ???
}

type ThingWrapper struct {
    T ThingElem `xml:&quot;thing&quot;`
}

// VS

type ThingElem struct {
    XMLName xml.Name `xml:&quot;thing&quot;` // Do I even need this?
    Prop    int      `xml:&quot;prop,attr&quot;`
    Value   float    // ???
}

The usage of the XMLName Property confuses me. When should it be placed in the struct, and when in a wrapper as tag?

答案1

得分: 7

以下是解析给定数据的代码。

  1. 在消除空格之前,无法正确解析浮点值。
  2. 可以使用",chardata"注释引用标签的内容。
  3. 只要不会产生歧义,就不需要在结构中指定xml.Name字段。
package main

import (
	"encoding/xml"
	"fmt"
)

type Root struct {
	Things []Thing `xml:"thing"`
}

type Thing struct {
	Prop  int     `xml:"prop,attr"`
	Value float64 `xml:",chardata"`
}

func main() {
	data := `
<root>
<thing prop="1">1.23</thing>
<thing prop="2">4.56</thing>
</root>
`
	thing := &Root{}
	err := xml.Unmarshal([]byte(data), thing)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(thing)
}

希望对你有帮助!

英文:

Below you can find the code to unmarshal the given data.

  1. The float values cannot be correctly unmarshalled until you get rid of spaces.
  2. The contents of the tag can be referenced using ",chardata" annotation.
  3. You do not need to specify xml.Name field in structure as long as it is not ambiguous which structure should be used.

package main

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

type Root struct {
	Things []Thing `xml:&quot;thing&quot;`
}

type Thing struct {
	Prop  int     `xml:&quot;prop,attr&quot;`
	Value float64 `xml:&quot;,chardata&quot;`
}

func main() {
	data := `
&lt;root&gt;
&lt;thing prop=&quot;1&quot;&gt;1.23&lt;/thing&gt;
&lt;thing prop=&quot;2&quot;&gt;4.56&lt;/thing&gt;
&lt;/root&gt;
`
	thing := &amp;Root{}
	err := xml.Unmarshal([]byte(data), thing)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(thing)
}

huangapple
  • 本文由 发表于 2014年11月13日 22:55:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/26911763.html
匿名

发表评论

匿名网友

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

确定