在Go语言中解析带有编号的XML标签

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

Unmarshal numbered XML tags in Go

问题

我尝试了很多结构体来解析这个XML,但是我无法弄清楚:

package main

import (
	"bytes"
	"encoding/xml"
	"fmt"
)

type SettingContainer struct {
	XMLName  xml.Name  `xml:"Settings"`
	Settings []Setting `xml:",any"`
}

type Setting struct {
	XMLName          xml.Name          `xml:",any"`
	SettingRegisters []SettingRegister `xml:",any"`
}

type SettingRegister struct {
	XMLName xml.Name `xml:",any"`
	Value   string   `xml:"value,attr"`
}

func main() {
	var xmlData = bytes.NewBufferString(`
	<Settings>
		<Setting0>
			<Setting0_register value="0x20" />
			<Setting0ArbitraryName value="0x0" />
		</Setting0>
		<Setting1>
			<Setting1_register value="0x60" />
			<Setting1WhateverEnable value="0x0" />
		</Setting1>
		<Setting2>
			<Setting2_register value="0x80" />
			<Setting2blahblah value="0x1" />
		</Setting2>
		<Setting4>
			<Setting4_register value="0x2fffff8" />
			<Setting4ThisCanBeAnything value="0x0" />
		</Setting4>
	</Settings>`)

	var s []SettingContainer
	xml.Unmarshal(xmlData.Bytes(), &s)

	for _, i := range s {
		fmt.Println(i)
	}
}

我无法打印任何内容。我实际需要的字段是SettingN_register的value属性以及SettingN标签的名称。我该如何正确地将XML解析到这些字段中?我正在研究创建一个自定义的解析函数,但是我无法找到正确的方法。我只能获取到"Settings"标签的名称。

英文:

I've tried quite a lot of structs to try and unmarshal this XML, but I couldn't really figure it out:

package main

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

type SettingContainer struct {
	XMLName  xml.Name  `xml:&quot;Settings&quot;`
	Settings []Setting `xml:&quot;,any&quot;`
}

type Setting struct {
	XMLName          xml.Name          `xml:&quot;,any&quot;`
	SettingRegisters []SettingRegister `xml:&quot;,any&quot;`
}

type SettingRegister struct {
	XMLName xml.Name `xml:&quot;,any&quot;`
	Value   string   `xml:&quot;value,attr&quot;`
}

func main() {
	var xmlData = bytes.NewBufferString(`
	&lt;Settings&gt;
		&lt;Setting0&gt;
			&lt;Setting0_register value=&quot;0x20&quot; /&gt;
			&lt;Setting0ArbitraryName value=&quot;0x0&quot; /&gt;
		&lt;/Setting0&gt;
		&lt;Setting1&gt;
			&lt;Setting1_register value=&quot;0x60&quot; /&gt;
			&lt;Setting1WhateverEnable value=&quot;0x0&quot; /&gt;
		&lt;/Setting1&gt;
		&lt;Setting2&gt;
			&lt;Setting2_register value=&quot;0x80&quot; /&gt;
			&lt;Setting2blahblah value=&quot;0x1&quot; /&gt;
		&lt;/Setting2&gt;
		&lt;Setting4&gt;
			&lt;Setting4_register value=&quot;0x2fffff8&quot; /&gt;
			&lt;Setting4ThisCanBeAnything value=&quot;0x0&quot; /&gt;
		&lt;/Setting4&gt;
	&lt;/Settings&gt;`)

	var s []SettingContainer
	xml.Unmarshal(xmlData.Bytes(), &amp;s)

	for _, i := range s {
		fmt.Println(i)
	}
}

I just can't get it to print anything. The fields I actually need are the value attr of the SettingN_register as well as the SettingN tag names. How can I make it so the xml is unmarshalled into these fields properly? I was looking into making a custom unmarshal function, but I couldn't really find how to make one properly. All I was able to get from this XML was the "Settings" tag name.

答案1

得分: 2

XMLName字段中的xml:&quot;,any&quot;标签移除(这会导致解码器尝试将额外的子元素映射到该字段),并将其解组为SettingContainer而不是[]SettingContainer,因为XML文档只能有一个根元素。工作示例在这里:https://go.dev/play/p/dItnmEGH8oM

type SettingContainer struct {
    XMLName  xml.Name  `xml:"Settings"`
    Settings []Setting `xml:",any"`
}

type Setting struct {
    XMLName          xml.Name
    SettingRegisters []SettingRegister `xml:",any"`
}

type SettingRegister struct {
    XMLName xml.Name
    Value   string `xml:"value,attr"`
}

func main() {
    var xmlData = bytes.NewBufferString(`...`)

    var s SettingContainer
    xml.Unmarshal(xmlData.Bytes(), &s)

    fmt.Println(s)
}
英文:

Remove the xml:&quot;,any&quot; tags from the XMLName fields (this is causing the decoder to try to map the extra child elements to this field), and unmarshal into a SettingContainer instead of []SettingContainer as an XML document can only have one root element. Working example here: https://go.dev/play/p/dItnmEGH8oM

type SettingContainer struct {
	XMLName  xml.Name  `xml:&quot;Settings&quot;`
	Settings []Setting `xml:&quot;,any&quot;`
}

type Setting struct {
	XMLName          xml.Name
	SettingRegisters []SettingRegister `xml:&quot;,any&quot;`
}

type SettingRegister struct {
	XMLName xml.Name
	Value   string `xml:&quot;value,attr&quot;`
}

func main() {
	var xmlData = bytes.NewBufferString(`...`)

	var s SettingContainer
	xml.Unmarshal(xmlData.Bytes(), &amp;s)

	fmt.Println(s)
}

huangapple
  • 本文由 发表于 2023年6月7日 21:03:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76423596.html
匿名

发表评论

匿名网友

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

确定