【问题标题】:Golang: Read single XML document from net.ConnGolang:从 net.Conn 读取单个 XML 文档
【发布时间】:2016-09-26 10:47:21
【问题描述】:

我有一个客户端-服务器连接。它们通过 xml 进行通信,并且在一个会话期间传输多个 xml 文档。 xml.Unmarshal 想要一片字节,但我不能只 ReadAll 来自套接字的所有字节(它会尝试读取比单个 xml 更多的字节,因此会阻塞)。

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

【问题讨论】:

    标签: xml parsing networking go xml-parsing


    【解决方案1】:

    您可以为此目的使用标准库中的xml.Decoder。您可以使用xml.NewDecoder() 创建一个新的xml.Decoder,它期望io.Reader 从中读取数据。 net.Conn 符合条件,因为它实现了 io.ReaderDecoder.Decode() 方法将读取和处理 1 个 XML 文档。

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

    XML 源:2 个 XML 文档 (2 <Person>):

    const data = `<Person>
        <Name>Bob</Name>
        <Age>23</Age>
    </Person>
    <Person>
        <Name>Alice</Name>
        <Age>21</Age>
    </Person>
    `
    

    Go struct 对 XML 文档进行建模:

    type Person struct {
        Name string
        Age  int
    }
    

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

    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)
        }
    }
    

    输出(在Go Playground 上试试):

    {Name:Bob Age:23}
    {Name:Alice Age:21}
    

    请注意,如果没有更多可用数据,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()

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 2016-06-17
      相关资源
      最近更新 更多