解组命名空间 XML 标签 - Golang

Unmarshal namespaced XML tags - Golang

我正在尝试从 .odt 文档中提取元数据。

包含XML的文件名为meta.xml

它有这样的结构:

<?xml version="1.0" encoding="UTF-8"?>
<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"  xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" office:version="1.2">
    <office:meta>
        <meta:creation-date>2016-10-18T15:05:19.137453293</meta:creation-date>
        <dc:title>Document</dc:title>
        <dc:date>2017-01-17T00:59:04.731054728</dc:date>
        <meta:document-statistic meta:page-count="1" meta:word-count="0" meta:character-count="0"/>
    </office:meta>
</office:document-meta>

我正在使用 encoding/xml 包中的 xml.Unmarshal() 来解析 XML 并将值放在结构字段中。

这是我正在使用的结构:

type Query struct {
    CreationDate string `xml:""`
    PageCount int `xml:""`
    WordCount int `xml:""`
    CharCount int `xml:""`
}

我从可用文档中了解到,我可以使用 xml:"tag-name" 类型的字段标签来获取 XML 标签的值,并使用 xml:name,attr 来获取属性值.

但是,由于 XML 文件具有命名空间标签(例如 meta:creation-date),到目前为止我尝试的所有操作都将结构字段留空。虽然,我可能做错了什么。

这是 Go playground 中的整个程序: https://play.golang.org/p/n7C50l1gsV

如果您的结构相当直接地映射到 XML,您会发现事情会进行得更顺利。此代码应该可以帮助您入门:

package main

import (
    "encoding/xml"
    "fmt"
)

type Stats struct {
    XMLName   xml.Name
    PageCount int `xml:"page-count,attr"`
}

type Meta struct {
    XMLName xml.Name
    Date    string `xml:"creation-date"`
    Title   string `xml:"title"`
    Stats   Stats  `xml:"document-statistic"`
}

type DocumentMeta struct {
    XMLName xml.Name
    Meta    Meta `xml:"meta"`
}

var data = []byte(`<?xml version="1.0" encoding="UTF-8"?>
<office:document-meta>
    <office:meta>
        <meta:creation-date>2016-10-18T15:05:19.137453293</meta:creation-date>
        <dc:title>Document</dc:title>
        <dc:date>2017-01-17T00:59:04.731054728</dc:date>
        <meta:document-statistic meta:page-count="1" meta:word-count="0" meta:character-count="0"/>
    </office:meta>
</office:document-meta>`)

func main() {
    var dm DocumentMeta
    xml.Unmarshal(data, &dm)
    fmt.Println(dm)
}