我希望使用github.com/mattn/go-xmpp
Golang包对XMPP用户进行操作。我改变了一个小官员example并得到了类似的东西:
switch v := chat.(type) {
case xmpp.IQ:
if len(v.Query) != 0 {
fmt.Printf("Query: %s", v.Query)
}
default:
fmt.Printf("detect default type: %T\n", v)
}
v.Query
是一个XML文档,其名称空间如
<query xmlns="jabber:iq:roster">
<item jid="JID1" name="Name" subscription="none" ask="subscribe">
<group></group>
</item>
<item jid="JID2" name="Another name" subscription="both">
<group>Group</group>
</item>
<item jid="JID3" name="Eman" subscription="both">
<group>AnotherGroup</group>
</item>
</query>
如何解析此文档并迭代jid
个元素?
答案 0 :(得分:0)
标准库中有两种解析XML文档的机制,一种是流传输机制,另一种是基于结构的机制。
流API
使用流传输机制会有点冗长,但对于大型文档(例如大型花名册)也非常有效。基本思想是创建一个解码器,遍历令牌并提取所需的数据。在这种情况下,您只需要仅在起始元素上的JID属性,因此您还需要遍历每个起始元素的属性以找到一个名为“ jid”的属性。以下是执行此操作的最小示例,对于真实项目,您可能还需要验证每个起始元素是否为“ item”:
func main() {
d := xml.NewDecoder(strings.NewReader(v.Query))
var jids []string
for {
tok, err := d.Token()
if err != nil && err != io.EOF {
panic(err)
}
if tok == nil {
break
}
start, ok := tok.(xml.StartElement)
if !ok {
// We'll skip anything that's not a start element in this example.
continue
}
jid := getAttr("jid", start.Attr)
if jid != "" {
jids = append(jids, jid)
}
}
fmt.Println(jids)
}
func getAttr(name string, attr []xml.Attr) string {
for _, a := range attr {
if a.Name.Local == name {
return a.Value
}
}
return ""
}
您可以在以下操场上运行此示例:https://play.golang.org/p/s6flTADDsnT
基于结构的API
基于结构的API稍微容易一些,但对于庞大的名册而言,效率可能较低。我们将创建一个表示有效负载的结构,将数据解组到其中,然后遍历它并取出JID,而不是逐个令牌地流化XML有效负载令牌。表示名册响应的结构如下所示:
type rosterResponse struct {
XMLName xml.Name `xml:"jabber:iq:roster query"`
Items []struct {
JID string `xml:"jid,attr"`
} `xml:"item"`
}
可以在此处找到拆封示例:
https://play.golang.org/p/g2qLUkdZ7qt
为了更好地理解这两个示例中发生的情况,我强烈建议您阅读encoding/xml
的软件包级别的文档,其中涵盖了所有这些内容以及许多有用的信息!