Golang:从net.Conn读取单个XML文档

Golang:从net.Conn读取单个XML文档,xml,parsing,networking,go,xml-parsing,Xml,Parsing,Networking,Go,Xml Parsing,我有一个客户机-服务器连接。它们通过xml进行通信,在一个会话中传输多个xml文档xml.Unmarshal需要一个字节片,但我不能从套接字读取所有字节(它将尝试读取更多的xml,因此会阻塞) 是否有一个标准的xml解析器或库,可以从字节流中进行解析,并且读取的数据不会超过实际需要?您可以从标准库中使用它。您可以使用创建一个新的xml.Decoder,该解码器期望从中读取数据。当它实现io.Reader时合格。该方法将读取并处理1个XML文档 让我们看一个例子。源代码将包含两个串联的XML文档,

我有一个客户机-服务器连接。它们通过xml进行通信,在一个会话中传输多个xml文档
xml.Unmarshal
需要一个字节片,但我不能从套接字读取所有字节(它将尝试读取更多的xml,因此会阻塞)

是否有一个标准的xml解析器或库,可以从字节流中进行解析,并且读取的数据不会超过实际需要?

您可以从标准库中使用它。您可以使用创建一个新的
xml.Decoder
,该解码器期望从中读取数据。当它实现io.Reader时合格。该方法将读取并处理1个XML文档

让我们看一个例子。源代码将包含两个串联的XML文档,我们调用
Decoder.Decode()
两次来读取和解析这两个文档

XML源:2个XML文档(2
):

读取这两个XML文档的代码:

type Person struct {
    Name string
    Age  int
}
buf := bytes.NewBuffer([]byte(data))
d := xml.NewDecoder(buf)

for i := 0; i < 2; i++ {
    p := Person{}
    if err := d.Decode(&p); err != nil {
        fmt.Println(err)
    } else {
        fmt.Printf("%+v\n", p)
    }
}
请注意,如果没有更多数据可用,则
Decoder.Decode()
将返回
io.EOF
。要从输入中读取所有XML文档,可以按如下方式执行:

for {
    p := Person{}
    if err := d.Decode(&p); err != nil {
        if err == io.EOF {
            fmt.Println("EOF, breaking")
            break
        }
        fmt.Println(err)
    } else {
        fmt.Printf("%+v\n", p)
    }
}
回到你的例子 如果要读取通过TCP连接传输的XML文档,只需将
net.Conn
值(实现
io.Reader
)传递到
XML.NewDecoder()

{Name:Bob Age:23}
{Name:Alice Age:21}
for {
    p := Person{}
    if err := d.Decode(&p); err != nil {
        if err == io.EOF {
            fmt.Println("EOF, breaking")
            break
        }
        fmt.Println(err)
    } else {
        fmt.Printf("%+v\n", p)
    }
}
var con net.Conn
// Initialize / obtain connection

d := xml.NewDecoder(con)
var doc YourDocType
if err := d.Decode(&doc); err != nil {
    // Handle error
    return
}
// No error, use doc:
fmt.Printf("%+v", doc)