【问题标题】:Parse Xml in GO for atttribute with ":" in tag在 GO 中解析 Xml 以获取标签中带有“:”的属性
【发布时间】:2018-07-27 13:59:00
【问题描述】:

我想解析一个 XML 文件的属性。 它适用于任何“正常”属性,例如 <application name="AppName">

但如果属性中包含“:”,我将无法检索该属性的值。例如<application name:test="AppName">

这是我用来解析这个的代码:

package main

import "fmt"
import "encoding/xml"

type Application struct {
    Event Event `xml:"application"`
    Package   string    `xml:"package,attr"`
}

type Event struct {
    IsValid   string `xml:"test:isValid,attr"`
}

var doc = []byte(`<?xml version="1.0" encoding="utf-8" standalone="no"?>
    <application package="leNomDuPackage">
            <event test:isValid="true">
        </application>
</manifest>`)

func main() {
    application := Application{}
    xml.Unmarshal(doc, &application)

    fmt.Println("Application:  ", application)
    fmt.Println("isValid:", application.Event)
}

你也可以在 Golang 操场上找到它:[https://play.golang.org/p/R6H80xPezhm

我想检索isValid 属性的值。

目前,我收到该错误消息,但无法解决。

struct field tag xml:"test\:isValid,attr not compatible with reflect.StructTag.Get: struct tag value 语法错误

我也尝试了以下值

type Event struct {
    IsValid   string `xml:"test isValid,attr`
}

type Event struct {
    IsValid   string `xml:"test\:isValid,attr`
}

但它并不能正常工作。

【问题讨论】:

  • 您在标签中缺少结束 ",这就是来自 Go vet 的警告消息的原因。并不是说它会使其工作或任何事情,它只会摆脱警告。
  • 要真正解决您的问题,只需删除标签中的测试前缀,并让 Event 字段的标签名称为 event,与 xml 元素相同,而不是 application。例如。 (play.golang.org/p/cYDHw1LCklK)
  • XMLName 字段不是必需的,这不是使它起作用的原因。但输入应该是有效的 XML。

标签: xml go xml-parsing


【解决方案1】:

您可以在标签定义中省略"test:" 前缀。只需确保您的 XML 有效,您的 XML 没有 &lt;event&gt; 的结束标签,并且有一个不匹配的结束标签 &lt;/manifest&gt;。您还缺少标记定义中的右引号。

型号:

type Application struct {
    Event   Event  `xml:"event"`
    Package string `xml:"package,attr"`
}

type Event struct {
    IsValid string `xml:"isValid,attr"`
}

一个有效的 XML 示例:

var doc = `
<application package="leNomDuPackage">
    <event test:isValid="true" />
</application>`

代码解析:

application := Application{}
err := xml.Unmarshal([]byte(doc), &application)
if err != nil {
    fmt.Println(err)
}

fmt.Printf("Application: %#v\n", application)

输出(在Go Playground上试试):

Application: main.Application{Event:main.Event{IsValid:"true"},
    Package:"leNomDuPackage"}

注意,如果你有多个同名但前缀不同的属性,比如这个例子:

var doc = `
<application package="leNomDuPackage">
    <event test:isValid="true" test2:isValid="false" />
</application>`

然后你可以在标签值中添加命名空间前缀,名称之间用空格隔开,如下所示:

type Event struct {
    IsValid1 string `xml:"test isValid,attr"`
    IsValid2 string `xml:"test2 isValid,attr"`
}

解析代码是一样的。输出(在Go Playground上试试):

Application: main.Application{Event:main.Event{IsValid1:"true", 
    IsValid2:"false"}, Package:"leNomDuPackage"}

【讨论】:

  • 如果你真的需要定义的命名空间,只需在后面添加一个空格(这样你就可以有两个相同的命名空间)像这样play.golang.org/p/HrPyhMJATwZ
  • @Kent 好主意,用它改进了答案。
  • 很好用。 xml 不是很好,但我做了它而不是我必须为我的程序解析的大量文件。 :-) 感谢您顺便指出所有内容。
猜你喜欢
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 2011-12-13
相关资源
最近更新 更多