如何使用 Go 读取错误的 XML

我想使用 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 文件?谢谢!


森栏
浏览 364回答 2
2回答

慕妹3242003

发表我的评论作为答案。您似乎无法在此处直接使用 Go xml 包。但你可以:考虑分叉 xml 包并更改isName函数以允许您的格式,或者首先清理 XML,将其更改为有效的 XML,然后使用 Goxml包进行解析。另一种选择(可能是一个不错的选择,取决于您的“XML”输入有多疯狂)是实现您自己的解析器,如 Gopher Academy 博客中所述:advent-2014/parsers-lexers

慕斯王

我能够阅读 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go