[已解决]Golang中XML解析器的问题求助

[已解决]Golang中XML解析器的问题求助 大家好,

很抱歉我的英语不好,因为我是法国人,英语水平很差。

我尝试用GO解析一个XML文件。 这个XML文件是JIRA导出的。

我使用了在网上找到的代码。

示例的简单XML文件:

<balise version="1.0">
    <title>JIRA</title>
</balise>

以及Go代码:

package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

// 全局结构
type RSS struct {
    XMLName xml.Name `xml:"balise"`
    version string   `xml:"version,attr"`
    titre   string   `xml:"title"`
}

func main() {

    // 打开我们的xmlFile
    xmlFile, err := os.Open("test.xml")
    // 如果os.Open返回错误则处理它
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("Successfully Opened users.xml")
    // 延迟关闭xmlFile,以便稍后解析
    defer xmlFile.Close()

    // 将打开的xmlFile读取为字节数组
    byteValue, err := ioutil.ReadAll(xmlFile)

    if err != nil {

        fmt.Println(err)
    }

    // 初始化我们的Users数组
    var rss RSS

    err = xml.Unmarshal(byteValue, &rss)
    fmt.Println(rss)
}

运行程序时,结果只是"{{ balise} }" 为什么我在响应中看不到版本和标题?

感谢您的帮助,我已经搜索了两天,但到目前为止还没有找到答案。


更多关于[已解决]Golang中XML解析器的问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

我猜XML结构定义中缺少了一些反引号。 另外,请发布你XML文件中的几行内容以便检查。

更多关于[已解决]Golang中XML解析器的问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


NobbZ:

一切看起来都符合预期:

非常感谢 NobbZ,我刚刚在结构定义中将 version 改为 Version,将 titre 改为 Titre,现在一切正常了!

能否在 play.golang.org 上提供能重现你问题的代码?你创建代码和 XML 的方式让人难以复制。

或者你也可以在论坛中使用 Markdown 代码块来正确格式化和显示代码,这样我们就可以直接复制粘贴了。

Yamil_Bracho: 我猜XML结构定义中缺少了一些反引号。

感谢您的快速回复。 实际文件内容更复杂,但目前我仅在文件中写了这些内容 (为便于展示已添加空格):

< balise version="0.92">
< title>
JIRA
< /title>
< /balise>

我在Playground上尝试过,在修复了论坛魔改引号导致的错误后,我不得不硬编码XML内容。同时我使用了fmt.Printf("%#v", rss),因为我更喜欢这类场景下的调试输出方式。虽然更冗长,但也更明确。

不管怎样,第一次尝试显示了一些警告:

prog.go:13:2: struct field version has xml tag but is not exported
prog.go:14:2: struct field titre has xml tag but is not exported

所以在导出这些字段后,结果看起来符合预期:

Successfully Opened users.xml
main.RSS{XMLName:xml.Name{Space:"", Local:"balise"}, Version:"0.92", Titre:"\n    JIRA\n  "}

您的XML解析问题很常见,通常是由于Go结构体字段的可见性规则导致的。在Go语言中,只有首字母大写的字段才能被外部包(如encoding/xml)访问和序列化。

以下是修正后的代码:

package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

// 修正后的结构体 - 所有字段首字母大写
type RSS struct {
    XMLName xml.Name `xml:"balise"`
    Version string   `xml:"version,attr"`  // 改为大写
    Titre   string   `xml:"title"`         // 改为大写
}

func main() {
    // 打开XML文件
    xmlFile, err := os.Open("test.xml")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer xmlFile.Close()

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

    // 读取文件内容
    byteValue, err := ioutil.ReadAll(xmlFile)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 解析XML
    var rss RSS
    err = xml.Unmarshal(byteValue, &rss)
    if err != nil {
        fmt.Println("解析错误:", err)
        return
    }

    // 打印解析结果
    fmt.Printf("XMLName: %s\n", rss.XMLName.Local)
    fmt.Printf("Version: %s\n", rss.Version)
    fmt.Printf("Titre: %s\n", rss.Titre)
    
    // 或者直接打印整个结构体
    fmt.Printf("完整结构体: %+v\n", rss)
}

对于您的XML示例:

<balise version="1.0">
    <title>JIRA</title>
</balise>

修正后的代码将输出:

Successfully Opened test.xml
XMLName: balise
Version: 1.0
Titre: JIRA
完整结构体: {XMLName:{Space: Local:balise} Version:1.0 Titre:JIRA}

关键修改点:

  1. 将结构体字段version改为Version
  2. 将结构体字段titre改为Titre
  3. 添加了错误处理,确保在出现错误时程序会提前返回

这个修改确保了encoding/xml包能够正确访问和填充结构体字段。

回到顶部