Golang – 使用属性进行XML解码

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

Golang - XML decoding with attr

问题

我遇到了一个问题,尝试从一个旧设备中解析一些XML数据,但我无法将元素和属性映射到我的输出模型。

设备以ISO-8859-1格式生成XML。我已经成功进行了转码,但在映射元素和属性到输出模型时遇到了困难。

我没有找到任何结合这些问题的问题,并且不知道这是否导致了问题。

问题在于并非所有的XML细节都被映射到我的对象中。

Tmps只保存了最后一个重复项,并且AOS和AIS没有被映射。

以下是一个带有示例XML输出的独立测试包装器。

package main

// go-webbrck is a lightweight package that is used to control a variety the legacy webbrick products

import (
	"bytes"
	"code.google.com/p/go-charset/charset" // For XML conversion
	_ "code.google.com/p/go-charset/data"  // Specs for dataset conversion
	"encoding/xml"                         // For XML work
	"fmt"                                  // For outputting stuff
)

type Clock struct {
	Date string
	Time string
	Day  string
}

type Tmps struct {
	Tmp Tmp `xml:"Tmp"`
}

type Tmp struct {
	ID    string `xml:"id,attr"`
	low   string `xml:"low,attr"`
	high  string `xml:"high,attr"`
	value string `xml:",chardata"`
}

type AOs struct {
	AO string `xml:"AO"`
}

type AO struct {
	id string `xml:"id,attr"`
	AO string `xml:",chardata"`
}

type AIs struct {
	AI string `xml:"AI"`
}

type AI struct {
	id   string `xml:"id,attr"`
	low  string `xml:"low,attr"`
	high string `xml:"high,attr"`
	AI   string `xml:",chardata"`
}

type WebbrickStatus struct {
	Error      string
	Context    string
	LoginState string
	DI         string
	DO         string
	Clock      Clock `xml:"Clock"`
	OWbus      string
	Tmps       Tmps `xml:"Tmps"`
	AOS        AOs  `xml:"AOs"`
	AIS        AIs  `xml:"AIs"`
}

func main() {
	fmt.Println("Hello, playground")
	GetWBStatus()
}

// Get WB Status on Initilisation
func GetWBStatus() bool {

	//var msg string
	var strMsg string
	strMsg = `<?xml version="1.0" encoding="ISO-8859-1"?>
<WebbrickStatus Ver="6.1.614">
<Error>0</Error>
<Context>2</Context>
<LoginState>3</LoginState>
<DI>0</DI>
<DO>0</DO>
<Clock>
  <Date>0/0/0</Date>
  <Time>12:54:52</Time>
  <Day>3</Day>
</Clock>
<OWBus>1</OWBus>
<Tmps>
  <Tmp id="1" lo="-800" hi="384">283</Tmp>
  <Tmp id="2" lo="-800" hi="1600">0</Tmp>
  <Tmp id="3" lo="-800" hi="1600">0</Tmp>
  <Tmp id="4" lo="-800" hi="1600">0</Tmp>
  <Tmp id="5" lo="-800" hi="1600">0</Tmp>
</Tmps>
<AOs>
  <AO id="0">0</AO>
  <AO id="1">0</AO>
  <AO id="2">0</AO>
  <AO id="3">0</AO>
</AOs>
<AIs>
  <AI id="0" lo="0" hi="100">1</AI>
  <AI id="1" lo="0" hi="100">0</AI>
  <AI id="2" lo="0" hi="100">0</AI>
  <AI id="3" lo="0" hi="100">0</AI>
</AIs>
</WebbrickStatus>`

	fmt.Println("\n\n*** Setting up\n==============\n\n")
	fmt.Printf("%v", strMsg)
	msg := []byte(strMsg)

	// // Decode XML encoding
	var _wbs WebbrickStatus                   // create container to load the xml
	reader := bytes.NewReader(msg)            // create a new reader for transcoding to utf-8
	decoder := xml.NewDecoder(reader)         // create a new xml decoder
	decoder.CharsetReader = charset.NewReader // bind the reader to the decoder
	fmt.Println("*** Decoding\n")
	xmlerr := decoder.Decode(&_wbs) // unmarshall the xml
	if xmlerr != nil {
		fmt.Printf("error: %v", xmlerr)
		return false
	}

	fmt.Println("*** Result\n")

	fmt.Printf("%+v\n\n\n", _wbs)

	return true

}

希望对你有所帮助!

英文:

I've got stuck with trying to unmarshall some XML from an old device I'm trying to read from.

The device produces XML in ISO-8859-1 format. I've managed to transcode, but am struggling to map the elements and attributes to my output model.

I've not found any questions that combine these, and don't know if this is causing the issue.

The issue is that not all of the XML details are being mapped to my object

{Error:0 Context:2 LoginState:3 DI:0 DO:0 Clock:{Date:0/0/0 Time:12:54:52 Day:3} OWbus: Tmps:{Tmp:{ID:5 low: high: value:}} AOS:{AO:0} AIS:{AI:0}}

The Tmps only holds the last repeat, and the AOS and AIS are not being mapped.

Here's a standalone test wrapper with an example xml output.

    package main
// go-webbrck is a lightweight package that is used to control a variety the legacy webbrick products
import (
&quot;bytes&quot;
&quot;code.google.com/p/go-charset/charset&quot; // For XML conversion
_ &quot;code.google.com/p/go-charset/data&quot;  // Specs for dataset conversion
&quot;encoding/xml&quot;                         // For XML work
&quot;fmt&quot;                                  // For outputting stuff
)
type Clock struct {
Date string
Time string
Day  string
}
type Tmps struct {
Tmp Tmp `xml:&quot;Tmp&quot;`
}
type Tmp struct {
ID    string `xml:&quot;id,attr&quot;`
low   string `xml:&quot;low,attr&quot;`
high  string `xml:&quot;high,attr&quot;`
value string `xml:&quot;,chardata&quot;`
}
type AOs struct {
AO string `xml:&quot;AO&quot;`
}
type AO struct {
id string `xml:&quot;id,attr&quot;`
AO string `xml:&quot;,chardata&quot;`
}
type AIs struct {
AI string `xml:&quot;AI&quot;`
}
type AI struct {
id   string `xml:&quot;id,attr&quot;`
low  string `xml:&quot;low,attr&quot;`
high string `xml:&quot;high,attr&quot;`
AI   string `xml:&quot;,chardata&quot;`
}
type WebbrickStatus struct {
Error      string
Context    string
LoginState string
DI         string
DO         string
Clock      Clock `xml:&quot;Clock&quot;`
OWbus      string
Tmps       Tmps `xml:&quot;Tmps&quot;`
AOS        AOs  `xml:&quot;AOs&quot;`
AIS        AIs  `xml:&quot;AIs&quot;`
}
func main() {
fmt.Println(&quot;Hello, playground&quot;)
GetWBStatus()
}
// Get WB Status on Initilisation
func GetWBStatus() bool {
//var msg string
var strMsg string
strMsg = `&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
&lt;WebbrickStatus Ver=&quot;6.1.614&quot;&gt;
&lt;Error&gt;0&lt;/Error&gt;
&lt;Context&gt;2&lt;/Context&gt;
&lt;LoginState&gt;3&lt;/LoginState&gt;
&lt;DI&gt;0&lt;/DI&gt;
&lt;DO&gt;0&lt;/DO&gt;
&lt;Clock&gt;
&lt;Date&gt;0/0/0&lt;/Date&gt;
&lt;Time&gt;12:54:52&lt;/Time&gt;
&lt;Day&gt;3&lt;/Day&gt;
&lt;/Clock&gt;
&lt;OWBus&gt;1&lt;/OWBus&gt;
&lt;Tmps&gt;
&lt;Tmp id=&quot;1&quot; lo=&quot;-800&quot; hi=&quot;384&quot;&gt;283&lt;/Tmp&gt;
&lt;Tmp id=&quot;2&quot; lo=&quot;-800&quot; hi=&quot;1600&quot;&gt;0&lt;/Tmp&gt;
&lt;Tmp id=&quot;3&quot; lo=&quot;-800&quot; hi=&quot;1600&quot;&gt;0&lt;/Tmp&gt;
&lt;Tmp id=&quot;4&quot; lo=&quot;-800&quot; hi=&quot;1600&quot;&gt;0&lt;/Tmp&gt;
&lt;Tmp id=&quot;5&quot; lo=&quot;-800&quot; hi=&quot;1600&quot;&gt;0&lt;/Tmp&gt;
&lt;/Tmps&gt;
&lt;AOs&gt;
&lt;AO id=&quot;0&quot;&gt;0&lt;/AO&gt;
&lt;AO id=&quot;1&quot;&gt;0&lt;/AO&gt;
&lt;AO id=&quot;2&quot;&gt;0&lt;/AO&gt;
&lt;AO id=&quot;3&quot;&gt;0&lt;/AO&gt;
&lt;/AOs&gt;
&lt;AIs&gt;
&lt;AI id=&quot;0&quot; lo=&quot;0&quot; hi=&quot;100&quot;&gt;1&lt;/AI&gt;
&lt;AI id=&quot;1&quot; lo=&quot;0&quot; hi=&quot;100&quot;&gt;0&lt;/AI&gt;
&lt;AI id=&quot;2&quot; lo=&quot;0&quot; hi=&quot;100&quot;&gt;0&lt;/AI&gt;
&lt;AI id=&quot;3&quot; lo=&quot;0&quot; hi=&quot;100&quot;&gt;0&lt;/AI&gt;
&lt;/AIs&gt;
&lt;/WebbrickStatus&gt;`
fmt.Println(&quot;\n\n*** Setting up\n==============\n\n&quot;)
fmt.Printf(&quot;%v&quot;, strMsg)
msg := []byte(strMsg)
// // Decode XML encoding
var _wbs WebbrickStatus                   // create container to load the xml
reader := bytes.NewReader(msg)            // create a new reader for transcoding to utf-8
decoder := xml.NewDecoder(reader)         // create a new xml decoder
decoder.CharsetReader = charset.NewReader // bind the reader to the decoder
fmt.Println(&quot;*** Decoding\n&quot;)
xmlerr := decoder.Decode(&amp;_wbs) // unmarshall the xml
if xmlerr != nil {
fmt.Printf(&quot;error: %v&quot;, xmlerr)
return false
}
fmt.Println(&quot;*** Result\n&quot;)
fmt.Printf(&quot;%+v\n\n\n&quot;, _wbs)
return true
}

Thanks

答案1

得分: 2

你的建模非常接近,你只需要修复 "array holder" 结构元素(Tmps、AOs、AIs)的类型。尝试这样做:

type Tmps struct {
  Tmp []Tmp
}
type AOs struct {
  AO []AO
}
type AIs struct {
  AI []AI
}

还要注意,XML 包期望 XML 元素名称与结构字段名称匹配,除非另有指定,所以你可以省略一些 xml:"..." 标签。

这里有一个在 Go Playground 上的简化示例:https://play.golang.org/p/jqlU4PSncA

英文:

Your modeling is very close, you just need to fix the type of the "array holder" struct elements (Tmps, AOs, AIs). Try this:

type Tmps struct {
Tmp []Tmp
}
type AOs struct {
AO []AO
}
type AIs struct {
AI []AI
}

Note also that the XML package will expect the XML element name to match the struct field name unless otherwise specified, so you can omit some xml:&quot;...&quot; tags.

Here is a simplified example on the go playground.

huangapple
  • 本文由 发表于 2015年3月28日 01:35:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/29306782.html
匿名

发表评论

匿名网友

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

确定