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

在 Golang 中解组一个简单的 xml 时出错

在 Golang 中解组一个简单的 xml 时出错

Go
犯罪嫌疑人X 2023-06-12 15:04:38
我正在尝试在 Go 中为大型 xml 文件( dblp.xml )编写一个非常简单的解析器,其摘录如下:<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE dblp SYSTEM "dblp.dtd"><dblp>    <article key="journals/cacm/Gentry10" mdate="2010-04-26">        <author>Craig Gentry</author>        <title>Computing arbitrary functions of encrypted data.</title>        <pages>97-105</pages>        <year>2010</year>        <volume>53</volume>        <journal>Commun. ACM</journal>        <number>3</number>        <ee>http://doi.acm.org/10.1145/1666420.1666444</ee>        <url>db/journals/cacm/cacm53.html#Gentry10</url>    </article>    <article key="journals/cacm/Gentry10" mdate="2010-04-26">        <author>Craig Gentry Number2</author>        <title>Computing arbitrary functions of encrypted data.</title>        <pages>97-105</pages>        <year>2010</year>        <volume>53</volume>        <journal>Commun. ACM</journal>        <number>3</number>        <ee>http://doi.acm.org/10.1145/1666420.1666444</ee>        <url>db/journals/cacm/cacm53.html#Gentry10</url>    </article></dblp>我的代码如下,看起来好像在 发生了一些事情xml.Unmarshal(byteValue, &articles),因为我无法在输出中获取任何 xml 的值。你能帮我解决我的代码有什么问题吗?
查看完整描述

1 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

您的代码中有特定行返回错误


xml.Unmarshal(byteValue, &articles)

如果你把它改成


err = xml.Unmarshal(byteValue, &articles)

if err != nil {

    fmt.Println(err.Error())

}

您会看到报告的错误:xml: encoding "ISO-8859-1" declared but Decoder.CharsetReader is nil。作为最佳实践,您应该始终检查返回的错误。


要解决此问题,您可以从 XML 中删除编码属性 ( encoding="ISO-8859-1") 或稍微更改解组代码:


package main


import (

    "encoding/xml"

    "fmt"

    "io"

    "os"


    "golang.org/x/text/encoding/charmap"

)


// Contains the array of articles in the dblp xml

type Dblp struct {

    XMLName xml.Name  `xml:"dblp"`

    Dblp    []Article `xml:"article"`

}


// Contains the article element tags and attributes

type Article struct {

    XMLName xml.Name `xml:"article"`

    Key     string   `xml:"key,attr"`

    Year    string   `xml:"year"`

}


func main() {

    xmlFile, err := os.Open("dblp.xml")

    if err != nil {

        fmt.Println(err)

    }


    fmt.Println("Successfully Opened TestDblp.xml")

    // defer the closing of our xmlFile so that we can parse it later on

    defer xmlFile.Close()


    var articles Dblp

    decoder := xml.NewDecoder(xmlFile)

    decoder.CharsetReader = makeCharsetReader

    err = decoder.Decode(&articles)

    if err != nil {

        fmt.Println(err)

    }


    for i := 0; i < len(articles.Dblp); i++ {

        fmt.Println("Entered loop")

        fmt.Println("get title: " + articles.Dblp[i].Key)

        fmt.Println("get year: " + articles.Dblp[i].Year)

    }

}


func makeCharsetReader(charset string, input io.Reader) (io.Reader, error) {

    if charset == "ISO-8859-1" {

        // Windows-1252 is a superset of ISO-8859-1, so should do here

        return charmap.Windows1252.NewDecoder().Reader(input), nil

    }

    return nil, fmt.Errorf("Unknown charset: %s", charset)

}

运行上面的程序会导致:


Successfully Opened TestDblp.xml

Entered var

Entered loop

get title: journals/cacm/Gentry10

get year: 2010

Entered loop

get title: journals/cacm/Gentry10

get year: 2010


查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 60 浏览
慕课专栏
更多

添加回答

举报

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