parsing xml text in golang

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

parsing xml text in golang

问题

我还没有运行代码,但是我可以帮你翻译你的代码和问题。以下是翻译好的代码:

package main

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

var data = []byte(`
	<ports><extraports state="filtered" count="65526">
		<extrareasons reason="no-responses" count="65526"/>
		</extraports>
		<port protocol="tcp" portid="1"><state state="closed" reason="conn-refused" reason_ttl="0"/><service name="tcpmux" method="table" conf="3"/></port>
		<port protocol="tcp" portid="2"><state state="closed" reason="conn-refused" reason_ttl="0"/><service name="compressnet" method="table" conf="3"/></port>
		<port protocol="tcp" portid="8"><state state="closed" reason="conn-refused" reason_ttl="0"/><service name="unknown" method="table" conf="3"/></port>
		<port protocol="tcp" portid="2709"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		<port protocol="tcp" portid="7748"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		<port protocol="tcp" portid="12946"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		<port protocol="tcp" portid="53094"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		<port protocol="tcp" portid="58137"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		<port protocol="tcp" portid="63139"><state state="closed" reason="conn-refused" reason_ttl="0"/></port>
		</ports>
`)

type PortData struct {
	Protocol string `xml:"protocol,attr"`
	Port     uint32 `xml:"portid,attr"`
}

type Nmap struct {
	IgnoreMe xml.Name   `xml:"ports"`
	Data     []PortData `xml:"port"`
}

func main() {
	var m Nmap
	if err := xml.Unmarshal(data, &m); err != nil {
		log.Fatalln(err)
	}
	log.Println("Succeeded")
	fmt.Printf("%#v\n", m)
}

你可以尝试使用上面的代码来解析你的 XML 文本。希望对你有帮助!如果你有任何其他问题,请随时问我。

英文:

Haven't had any luck parsing this snippet of xml text from the output of nmap. I'm interested in parsing the protocol, portid and reason fields out of the xml text. Initially, I tried extracting only the first two fields:

var data = []byte(`
 &lt;ports&gt;&lt;extraports state=&quot;filtered&quot; count=&quot;65526&quot;&gt;
    &lt;extrareasons reason=&quot;no-responses&quot; count=&quot;65526&quot;/&gt;
    &lt;/extraports&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;1&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;service name=&quot;tcpmux&quot; method=&quot;table&quot; conf=&quot;3&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;2&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;service name=&quot;compressnet&quot; method=&quot;table&quot; conf=&quot;3&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;8&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;service name=&quot;unknown&quot; method=&quot;table&quot; conf=&quot;3&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;2709&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;7748&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;12946&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;53094&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;58137&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;port protocol=&quot;tcp&quot; portid=&quot;63139&quot;&gt;&lt;state state=&quot;closed&quot; reason=&quot;conn-refused&quot; reason_ttl=&quot;0&quot;/&gt;&lt;/port&gt;
    &lt;/ports&gt;
`)

I defined my structures as below:

type PortData struct {
	Protocol string `xml:&quot;protocol,attr&quot;`
	Port uint32 `xml:&quot;portid,attr&quot;`
}

type Nmap struct {
	IgnoreMe xml.Name `xml:&quot;ports&quot;`
	Data []PortData `xml:&quot;port&quot;`	
}

func main() {
	var m Nmap
	if err := xml.Unmarshal(data, &amp;m); err == nil {
		log.Fatalln(err)
	}
	log.Println(&quot;Succeeded&quot;)
	fmt.Printf(&quot;%#v\n&quot;, m)
}

How can I fix my struct definitions to extract the fields of interest? Thanks

答案1

得分: 2

你可以通过更新你的结构体来提取reason字段:

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

type PortData struct {
    Protocol string `xml:"protocol,attr"`
    Port     uint32 `xml:"portid,attr"`
    State    State  `xml:"state"`
}

不幸的是,你不能将reason属性解码为PortData字段。虽然该包支持选择嵌套元素,但它不允许将其与属性选择结合使用(即xml:"state>reason,attr"将导致Unmarshal出错)。

其次,你的测试程序中有一个小错误:当errnil时,你应该退出,而不是相反。通过这两个更改,你应该能够提取你想要的数据。

你可以在这里进行实验:http://play.golang.org/p/hVxLzZ03cC

英文:

You can extract the reason field by updating your structs to read:

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

type PortData struct {
	Protocol string `xml:&quot;protocol,attr&quot;`
	Port     uint32 `xml:&quot;portid,attr&quot;`
	State    State  `xml:&quot;state&quot;`
}

Unfortunately you can't decode the reason attribute into a PortData field. While the package does support picking nested elements, it won't let you combine that with attribute selection (i.e. xml:&quot;state&gt;reason,attr&quot; will result in an error from Unmarshal).

Secondly, there is a small error in your test program: you are bailing out when err is nil, rather than the reverse. With those two changes you should be able to extract the data you're after.

You can experiment with this at: http://play.golang.org/p/hVxLzZ03cC

答案2

得分: 1

你只是打错了一个字。应该是err != nil

英文:

You just have a typo. It should be err != nil.

huangapple
  • 本文由 发表于 2015年3月4日 09:44:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/28845321.html
匿名

发表评论

匿名网友

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

确定