解组命名空间的XML标签 - Golang

时间:2017-02-13 16:57:21

标签: xml go unmarshalling

我正在尝试从.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>

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

这是我正在使用的结构:

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游乐场内的整个程序: https://play.golang.org/p/n7C50l1gsV

1 个答案:

答案 0 :(得分:3)

如果你的结构直接映射到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)
}