我想使用 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.xmlchardata: ''start: name.local='something'start {{ something} [{{ abc} 1} {{ def} 2}]}'abc'='1''def'='2'offset=66chardata: ' 'XML syntax error on line 3: invalid XML name: 0exit status 1这是小 Go 程序:package mainimport ( "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 文件?谢谢!
2 回答
慕妹3242003
TA贡献1824条经验 获得超6个赞
发表我的评论作为答案。
您似乎无法在此处直接使用 Go xml 包。但你可以:
考虑分叉 xml 包并更改
isName
函数以允许您的格式,或者首先清理 XML,将其更改为有效的 XML,然后使用 Go
xml
包进行解析。另一种选择(可能是一个不错的选择,取决于您的“XML”输入有多疯狂)是实现您自己的解析器,如 Gopher Academy 博客中所述:advent-2014/parsers-lexers
慕斯王
TA贡献1864条经验 获得超2个赞
我能够阅读 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)
- 2 回答
- 0 关注
- 363 浏览
添加回答
举报
0/150
提交
取消