使用Go解析XML,其中包含多个小写元素。

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

Parsing XML with Go, having multiple elements in lowercase

问题

我不知道如何使这段代码工作。我只是尝试解析一个简单的XML文件,像这样:

package main

import (
	"encoding/xml"
	"fmt"
)

type Data struct {
	XMLName xml.Name `xml:"data"`
	Nam     string   `xml:"nam,attr"`
}

type Struct struct {
	XMLName xml.Name `xml:"struct"`
	Data    []Data
}

func main() {

	x := `
		<struct>
			<data nam="MESSAGE_TYPE">     
			</data>
			<data nam="MESSAGE_TYPE2">
			</data>
		</struct>
	`
	s := Struct{}
	err := xml.Unmarshal([]byte(x), &s)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v\n", s)
	fmt.Println(s.Data)
}

我得到的结果是:

{{ struct} []}
[]

但是当我将"data"元素改为大写时,像这样:

```go
package main

import (
	"encoding/xml"
	"fmt"
)

type Data struct {
	XMLName xml.Name `xml:"Data"`
	Nam     string   `xml:"nam,attr"`
}

type Struct struct {
	XMLName xml.Name `xml:"struct"`
	Data    []Data
}

func main() {

	x := `
		<struct>
			<Data nam="MESSAGE_TYPE">     
			</Data>
			<Data nam="MESSAGE_TYPE2">
			</Data>
		</struct>
	`
	s := Struct{}
	err := xml.Unmarshal([]byte(x), &s)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v\n", s)
	fmt.Println(s.Data)
}

我得到的结果是:

{{ struct} [{{ Data} MESSAGE_TYPE} {{ Data} MESSAGE_TYPE2}]}
[{{ Data} MESSAGE_TYPE} {{ Data} MESSAGE_TYPE2}]

有人能告诉我为什么吗?

英文:

I don't know how to make this code work. I'm just trying to parse a simple XML file like this:

package main

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

type Data struct {
    XMLName xml.Name `xml:&quot;data&quot;`
    Nam     string   `xml:&quot;nam,attr&quot;`
}

type Struct struct {
    XMLName xml.Name `xml:&quot;struct&quot;`
    Data    []Data
}

func main() {

    x := `  
		&lt;struct&gt;
            &lt;data nam=&quot;MESSAGE_TYPE&quot;&gt;     
            &lt;/data&gt;
			&lt;data nam=&quot;MESSAGE_TYPE2&quot;&gt;
            &lt;/data&gt;
        &lt;/struct&gt;
    `
    s := Struct{}
    err := xml.Unmarshal([]byte(x), &amp;s)
    if err != nil {
	    panic(err)
    }
    fmt.Printf(&quot;%v\n&quot;, s)
    fmt.Println(s.Data)
}

what I got is:

{{ struct} []}
[]

But when I change the "data" elements to uppercase, like this:

package main

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

type Data struct {
    XMLName xml.Name `xml:&quot;Data&quot;`
    Nam     string   `xml:&quot;nam,attr&quot;`
}

type Struct struct {
    XMLName xml.Name `xml:&quot;struct&quot;`
    Data    []Data
}

func main() {

    x := `  
		&lt;struct&gt;
            &lt;Data nam=&quot;MESSAGE_TYPE&quot;&gt;     
            &lt;/Data&gt;
			&lt;Data nam=&quot;MESSAGE_TYPE2&quot;&gt;
            &lt;/Data&gt;
        &lt;/struct&gt;
    `
    s := Struct{}
    err := xml.Unmarshal([]byte(x), &amp;s)
    if err != nil {
	    panic(err)
    }
    fmt.Printf(&quot;%v\n&quot;, s)
    fmt.Println(s.Data)
}

I got this:

{{ struct} [{{ Data} MESSAGE_TYPE} {{ Data} MESSAGE_TYPE2}]}
[{{ Data} MESSAGE_TYPE} {{ Data} MESSAGE_TYPE2}]

Can anybody tell me why?

答案1

得分: 7

如果您在结构字段上没有放置XML注释,字段的名称将被视为XML元素的名称。

在encoding/xml包的Unmarshal文档中,我们可以找到以下内容:

Unmarshal使用以下规则将XML元素映射到结构体。在规则中,字段的标签指的是结构体字段标签中与键'xml'关联的值(参见上面的示例)。

  • 如果XML元素包含一个子元素,其名称与没有任何模式标志(",attr"、",chardata"等)的字段匹配,Unmarshal将该子元素映射到该结构体字段。

匹配是区分大小写的,所以在您的情况下会有所区别。

我建议像这样对结构进行注释以适应实际数据:

type Struct struct {
    XMLName xml.Name `xml:"struct"`
    Data    []Data   `xml:"data"`
}
英文:

If you do not put XML annotation on the structure field the name of the field is taken as name of XML element.

In the documentation on Unmarshal in endoding/xml package we can find the following:

> Unmarshal maps an XML element to a struct using the following rules. In the rules, the tag of a field refers to the value associated with the key 'xml' in the struct field's tag (see the example above).

> - If the XML element contains a sub-element whose name matches a
field without any mode flags (",attr", ",chardata", etc), Unmarshal
maps the sub-element to that struct field.

The matching is case sensitive so it makes a difference in your case.

I recommend annotating the structure like this to fit the actual data:

type Struct struct {
    XMLName xml.Name `xml:&quot;struct&quot;`
    Data    []Data   `xml:&quot;data&quot;`
}

huangapple
  • 本文由 发表于 2014年11月2日 23:15:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/26700825.html
匿名

发表评论

匿名网友

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

确定