为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Go 读取错误的 XML

如何使用 Go 读取错误的 XML

Go
森栏 2021-12-13 18:48:58
我想使用 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,然后使用 Goxml包进行解析。

  • 另一种选择(可能是一个不错的选择,取决于您的“XML”输入有多疯狂)是实现您自己的解析器,如 Gopher Academy 博客中所述:advent-2014/parsers-lexers


查看完整回答
反对 回复 2021-12-13
?
慕斯王

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)


查看完整回答
反对 回复 2021-12-13
  • 2 回答
  • 0 关注
  • 363 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信