我在使用 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/