Correct layout of structs to parse xml in go

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

Correct layout of structs to parse xml in go

问题

尝试使用Golang解析一些nmap数据,但是我的结构体布局不太对。代码链接:https://play.golang.org/p/kODRGiH71W

package main

import (
	"encoding/xml"
	"fmt"
)

type Extrareasons struct {
	Reason string `xml:"reason,attr"`
	Count  uint32 `xml:"count,attr"`
}

type Extraports struct {
	State  string       `xml:"state,attr"`
	Count  uint32       `xml:"count,attr"`
	Reason Extrareasons `xml:"extrareasons"`
}

type StateProps struct {
	State  string `xml:"state,attr"`
	Reason string `xml:"reason,attr"`
}

type PortProps struct {
	Protocol    string      `xml:"protocol,attr"`
	Port        uint32      `xml:"portid,attr"`
	StateStuff  StateProps  `xml:"state"`
}

type PortInfo struct {
	Extra    Extraports `xml:"extraports"`
	PortProp PortProps  `xml:"port"`
}

type Ports struct {
	Port PortInfo `xml:"ports"`
}

func main() {
	xmlString := `<ports>
             <extraports state="closed" count="64">
                <extrareasons reason="conn-refused" count="64" />
             </extraports>
             <port protocol="tcp" portid="22">
                <state state="open" reason="syn-ack" reason_ttl="0" />
                <service name="ssh" method="table" conf="3" />
             </port>
          </ports>`

	var x Ports
	if err := xml.Unmarshal([]byte(xmlString), &x); err == nil {
		fmt.Printf("%+v\n", x)
	} else {
		fmt.Println("err:", err)
	}

}

运行结果:

{Port:{Extra:{State:closed Count:64 Reason:{Reason:conn-refused Count:64}} PortProp:{Protocol:tcp Port:22 StateStuff:{State:open Reason:syn-ack}}}}
英文:

Trying to parse some nmap data with golang, but the layout of my structs isn't quite working. Link to code on playground: https://play.golang.org/p/kODRGiH71W

package main

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

type Extrareasons struct {
	Reason string `xml:&quot;reason,attr&quot;`
	Count  uint32 `xml:&quot;count,attr&quot;`
}

type Extraports struct {
	State  string       `xml:&quot;state,attr&quot;`
	Count  uint32       `xml:&quot;count,attr&quot;`
	Reason Extrareasons `xml:&quot;extrareasons&quot;`
}

type StateProps struct {
	State  string `xml:&quot;state,attr&quot;`
	Reason string `xml:&quot;reason,attr&quot;`
}

type PortProps struct {
	Protocol string `xml:&quot;protocol,attr&quot;`
	Port     uint32 `xml:&quot;portid,attr&quot;`
	StateStuff StateProps `xml:&quot;state&quot;`
}

type PortInfo struct {
	Extra    Extraports `xml:&quot;extraports&quot;`
	PortProp PortProps  `xml:&quot;port&quot;`
}

type Ports struct {
	Port PortInfo `xml:&quot;ports&quot;`
}

func main() {
	xmlString := `&lt;ports&gt;
         &lt;extraports state=&quot;closed&quot; count=&quot;64&quot;&gt;
            &lt;extrareasons reason=&quot;conn-refused&quot; count=&quot;64&quot; /&gt;
         &lt;/extraports&gt;
         &lt;port protocol=&quot;tcp&quot; portid=&quot;22&quot;&gt;
            &lt;state state=&quot;open&quot; reason=&quot;syn-ack&quot; reason_ttl=&quot;0&quot; /&gt;
            &lt;service name=&quot;ssh&quot; method=&quot;table&quot; conf=&quot;3&quot; /&gt;
         &lt;/port&gt;
      &lt;/ports&gt;`

	var x Ports
	if err := xml.Unmarshal([]byte(xmlString), &amp;x); err == nil {
		fmt.Printf(&quot;%+v\n&quot;, x)
	} else {
		fmt.Println(&quot;err:&quot;, err)
	}

}

$ go run test.go 
{Port:{Extra:{State: Count:0 Reason:{Reason: Count:0}} PortProp:{Protocol: Port:0 StateStuff:{State: Reason:}}}}

答案1

得分: 1

Ports包装结构创建的层是不必要的,请删除它。您只需要对根XML元素<ports>及其内容进行建模,该内容由PortInfo描述/建模。不需要包装根元素的类型。

只需将

var x Ports

更改为

var x PortInfo

然后它就会工作。在Go Playground上尝试一下。输出(已包装):

{Extra:{State:closed Count:64 Reason:{Reason:conn-refused Count:64}}
    PortProp:{Protocol:tcp Port:22 StateStuff:{State:open Reason:syn-ack}}}
英文:

The layer that the Ports wrapper struct creates is unnecessary, drop it. You only need to model the contents of the root xml element which is &lt;ports&gt; and its content is described / modeled by PortInfo. There is no need for a type that wraps the root element.

Simply change

var x Ports

to

var x PortInfo 

And it will work. Try it on the Go Playground. Output (wrapped):

{Extra:{State:closed Count:64 Reason:{Reason:conn-refused Count:64}}
    PortProp:{Protocol:tcp Port:22 StateStuff:{State:open Reason:syn-ack}}}

huangapple
  • 本文由 发表于 2016年4月28日 07:12:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/36902518.html
匿名

发表评论

匿名网友

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

确定