我想使用Go来读取XML文件。问题是它是一个糟糕的XML文件 - 它不符合规范。这是一个样本:
<?xml version="1.0" encoding="UTF-8"?>
<something abc="1" def="2">
<0 x="a"/>
<1 x="b"/>
<2 x="c"/>
<26 x="z"/>
</something>
我的Go程序在尝试阅读时正确地给出了错误:
$ go run rs.go <real.xml
chardata: '
'
start: name.local='something'
start {{ something} [{{ abc} 1} {{ def} 2}]}
'abc'='1'
'def'='2'
offset=66
chardata: '
'
XML syntax error on line 3: invalid XML name: 0
exit status 1
这是小Go计划:
package main
import (
"encoding/xml"
"fmt"
"io"
"os"
)
// <something abc="1" def="2">
type Something struct {
abc string `xml:"abc"`
def string `xml:"def"`
spots []Spot
}
// <0 x="a"/>
type Spot struct {
num int // ??
xval string `xml:"x"`
}
func main() {
dec := xml.NewDecoder(os.Stdin)
// dec.Strict = false // doesn't help <0 ...> problem
// dec.Entity = xml.HTMLEntity
for {
tok, err := dec.Token()
if err == io.EOF {
break
} else if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
switch tok := tok.(type) {
case xml.StartElement:
fmt.Printf("start: name.local='%s'\n", tok.Name.Local)
fmt.Printf("start %v\n", tok)
for _, a := range tok.Attr {
fmt.Printf("'%s'='%s'\n", a.Name.Local, a.Value)
}
fmt.Printf("offset=%d\n", dec.InputOffset())
case xml.EndElement:
fmt.Printf("end: name.local='%s'\n", tok.Name.Local)
case xml.CharData:
fmt.Printf("chardata: '%s'\n", tok)
case xml.Comment:
fmt.Printf("comment: '%s'\n", tok)
}
}
}
有没有Go专家可以帮我弄清楚如何让Go阅读这个愚蠢的XML文件?谢谢!
答案 0 :(得分:1)
感谢您的指示和建议,我能够阅读XML文件。 只需将错误的条目重写为好,让Unmarshall完成它的工作。 我的格式错误的文件很小(小于10k), 所以如果XML文件是100 MB,这可能不是一个好的选择。
re := regexp.MustCompile("<([0-9]+)")
s := re.ReplaceAllString(string(raw), "<splat n=\"${1}\"")
x := Something{Abc: "0"}
err = xml.Unmarshal([]byte(s), &x)
谢谢!
答案 1 :(得分:1)
发表评论作为答案。
您似乎无法直接在此处使用Go xml包。但你可以:
isName
函数以允许您的格式,或xml
包进行解析。