xml - golang XML 以 'invalid UTF-8' 错误结束解析

标签 xml go utf-8

我在使用 Unicode 字符解码 XML 时遇到问题。

当尝试用标准英文字符解析 XML 时,它会解析整个文件并正确解码,没有任何问题。但是,如果 XML 文件包含 ñ、á 或 – (em-dash) 等字符,它将停止解析 XML 并仅返回数组中 的项目之前的项目那个角色。

例如,这里是 XML:

<items>
  <item>
    <ID value="1" name="Item 1" GCName="Item 1" />
  </item>
  <item>
    <ID value="2" name="Item 2" GCName="Item 2" />
  </item>
  <item>
    <ID value="3" name="Item 3" GCName="Item 3 With ñ" />
  </item>
  <item>
    <ID value="4" name="Item 4" GCName="Item 4" />
  </item>
</items>

这是我的 Go 代码(粗略的,没有任何导入):

# main.go

type Response struct {
    Items []Items `xml:"items"`
}

type Items struct {
    Item []Item `xml:"item"`
}

type Item struct {
    ID    ItemID `xml:"ID"`
}

type ItemID struct {
    Value  string `xml:"value,attr"`
    Name   string `xml:"name,attr"`
    GCName string `xml:"GCName,attr"`
}

func main() {
    xmlFile, err := os.Open("C:\path\to\xml\file.xml")
    if err != nil {
        fmt.Println("Error opening file!")
        fmt.Println(err.Error())
    }
    defer xmlFile.Close()

    xmlData, err := io.ReadAll(xmlFile)
    if err != nil {
        fmt.Println("Error reading file!")
        fmt.Println(err.Error())
    }

    var response Response
    err := xml.Unmarshal(xmlData, &response)
    if err != nil {
        fmt.Println("Error unmarshaling XML")
        fmt.Println(err.Error())
    }
    fmt.Println(response)
}

此代码将打印出 前两项,就好像它们是仅有的两项一样。它还会输出:

Error unmarshaling XML
XML syntax error on line 9; Invalid UTF-8

我也尝试过将 xml.Decoder 与使用不同编码的 CharsetReader 结合使用,但这并没有产生任何不同的结果。 FWIW,我正在使用 Windows

有什么办法可以解决这个错误吗?将“坏”角色换成其他东西?据我了解,这些字符有效的 UTF-8...那么是什么原因呢??

提前致谢!

最佳答案

过滤掉无效UTF-8字符的阅读器

package main

    import (
    "bufio"
    "io"
    "unicode"
    "unicode/utf8"
    )

    // ValidUTF8Reader implements a Reader which reads only bytes that constitute valid UTF-8
    type ValidUTF8Reader struct {
        buffer *bufio.Reader
    }

    // Function Read reads bytes in the byte array b. n is the number of bytes read.
    func (rd ValidUTF8Reader) Read(b []byte) (n int, err error) {
        for {
            var r rune
            var size int
            r, size, err = rd.buffer.ReadRune()
            if err != nil {
                return
            }
            if r == unicode.ReplacementChar && size == 1 {
                continue
            } else if n+size < len(b) {
                utf8.EncodeRune(b[n:], r)
                n += size
            } else {
                rd.buffer.UnreadRune()
                break
            }
        }
        return
    }

    // NewValidUTF8Reader constructs a new ValidUTF8Reader that wraps an existing io.Reader
    func NewValidUTF8Reader(rd io.Reader) ValidUTF8Reader {
        return ValidUTF8Reader{bufio.NewReader(rd)}
    }

取自here

关于xml - golang XML 以 'invalid UTF-8' 错误结束解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096958/

相关文章:

go - Go可以用于BotFramework SDK吗?还是需要移植?

string - 为什么简单的 Go 应用程序占用大量内存

html - 从 VBA 代码中请求带有 UTF-8 字符的 URL

xml - 如何在对象中列出 Powershell 中复杂 xml 中的两个元素

javascript - 如何使用 Javascript 从 XML 文档中提取值

xml - WSO2 ESB 以 XML 为中心?

ruby-on-rails - Rails 3 - 如何处理 PG 错误不完整的多字节字符

c# - XNode.DeepEquals 意外返回 false

arrays - 从 slice 中删除特定元素

java - 如何正确计算字符串字节数?