使用Golang解析XML(滥用实体属性)

标签 xml go xml-parsing

我有一个像这样格式化的 XML,来自数据库转储

<table name="table1">
    <row>
        <col name="col1">value</col>
        <col name="col2">value</col>
        <col name="col3">value</col>
    </row>
   ...
</table>
<table name="table2">
    <row>
        <col name="col1">value</col>
        <col name="col2">value</col>
        <col name="col3">value</col>
        <col name="col4">value</col>
    </row>
   ...
</table>

我试图在 Go 中使用 xml.Decode() 函数解析它,但我无法处理这样的 XML。 我尝试匹配一些在 Golang 中通过谷歌搜索 XML 解析找到的示例,但没有任何内容适合这种格式(所有实体都有 name 属性)。

更新

谢谢各位的解答!我想要实现的是:假设我有一个名为“users”的表和一个名为“categories”的表,我想创建尽可能多的 UserCategory 从该 XML 开始的对象。 根据您的第一个答案,我可以轻松使用解析的 Table 对象,然后创建我自己的对象,但我想知道是否可以跳过它并直接解码我的对象。

最佳答案

xml.Unmarshal() 的文档函数描述了 XML 文档和结构之间的映射如何工作(由 json.Marshal() 的文档补充)。如果您不熟悉结构标签,请查看此答案:What are the use(s) for tags in Go?

首先您需要对 XML 文档进行建模。请注意,如果您没有包装所有其他 XML 元素,那么这不是 1 个 XML 文档,而是多个 XML 文档,例如您的情况。您有多个<table>文件。

你可以像这样建模它们:

type Col struct {
    Name  string `xml:"name,attr"`
    Value string `xml:",chardata"`
}

type Row struct {
    Cols []Col `xml:"col"`
}

type Table struct {
    Name string `xml:"name,attr"`
    Rows []Row  `xml:"row"`
}

既然你有多个 <table>元素,最简单的是创建一个 xml.Decoder() 并用 Decoder.Decode() 分别解析每个调用( Decoder.Decode() 将尝试从其源读取器解析 1 个 XML 文档)。

这是可以做到的:

d := xml.NewDecoder(strings.NewReader(data))
for {
    var table Table
    if err := d.Decode(&table); err != nil {
        fmt.Println(err)
        break
    }
    fmt.Printf("%+v\n", table)
}

当源中没有更多数据时string , Decoder.Decode()将报告 io.EOF 。使用以下命令运行上述 cod data字符串:

const data = `<table name="table1">
    <row>
        <col name="col1">value1</col>
        <col name="col2">value2</col>
        <col name="col3">value3</col>
    </row>
    <row>
        <col name="col1">value4</col>
        <col name="col2">value5</col>
        <col name="col3">value6</col>
    </row>
</table>
<table name="table2">
    <row>
        <col name="col1">value7</col>
        <col name="col2">value8</col>
        <col name="col3">value9</col>
        <col name="col4">valueA</col>
    </row>
</table>`

输出为:

{Name:table1 Rows:[{Cols:[{Name:col1 Value:value1} {Name:col2 Value:value2} {Name:col3 Value:value3}]} {Cols:[{Name:col1 Value:value4} {Name:col2 Value:value5} {Name:col3 Value:value6}]}]}
{Name:table2 Rows:[{Cols:[{Name:col1 Value:value7} {Name:col2 Value:value8} {Name:col3 Value:value9} {Name:col4 Value:valueA}]}]}
EOF

Go Playground 上尝试一下.

关于使用Golang解析XML(滥用实体属性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40214265/

相关文章:

Golang kubernetes go-client 将 Deployment 转换到 DeploymentList

go - 如何清除 Go 中的终端屏幕?

image - 异步加载的图像在同一 View 内不可重用

java - 安卓 :Parse XML Data: Tags with arguments

c# - 如何获取表示两个 XML 文本之间差异的对象集合?

java - 通过java比较xml并像diff工具一样呈现

java - 不允许实体声明但允许 DTD

Android XML 解析错误。新用户。

go - Python 在 golang 中的 setdefault 模拟

php - 在 php 中解析 SOAP 响应