如何将具有不同名称空间的相同XML元素反序列化为结构中的不同元素

时间:2017-01-04 22:57:30

标签: xml go

我正在使用以下类型的XML结构

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" 
    xmlns:content="http://purl.org/rss/1.0/modules/content/" 
    xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title>TITLE</title>
        <link>http://something.com</link>
        <description>description</description>
        <lastBuildDate>Mon, 19 Dec 2016 16:48:54 +0000</lastBuildDate>
        <language>en</language>
        <item>
            <title>Title</title>
            <description>description</description>
            <author>
                <name>Name</name>
                <uri></uri>
            </author>
            <pubDate>Mon, 19 Dec 2016 16:42:32 +0000</pubDate>
            <link>http://google.com</link>
            <image>...</image>
            <media:description><![CDATA[Natalie Massenet]]></media:description>
            <media:credit>David Fisher/REX/Shutterstock</media:credit>
            <category>Category1</category>
            <category>Category2</category>
            <guid isPermaLink="false">http://something.com/?p=10730393</guid>
            <media:group></media:group>
            <content:encoded>content</content:encoded>
        </item>
    </channel>
</rss>

我无法弄清楚如何将<description><media:description>反序列化为结构中的两个不同元素。

我尝试过以下类型的结构来表示<item>,但media:description的值最终会出现在结构中。

type Item struct {
    // ...other fields
    Description           string   `xml:"description"`
    MediaDescription      string   `xml:"media:description"`
    // ...other fields
}

最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

所以Go目前无法支持这一点(正如@JimB所指出的那样),但您仍然可以使用一些内置功能来提取正确的元素。首先定义一个新的结构XMLElement

type XMLElement struct {
    XMLName xml.Name
    Data    string `xml:",chardata"`
}

此结构可以捕获xml数据以及命名空间和元素名称。接下来将地图xml:"description"映射到XMLElement的数组。这将最终捕获列表中的所有<*:description>元素。然后,您可以定义函数以提取正确的函数。

type Item struct {
    // ...other fields
    Descriptions           []XMLElement   `xml:"description"`
    // ...other fields
}

// GetDescription returns the description in the <description> tag
func (i *Item) GetDescription() string {
    for _, elem := range i.Descriptions {
        if elem.XMLName.Space == "" {
            return elem.Data
        }
    }
    return ""
}

// GetMediaDescription returns the description in the <media:description> tag
func (i *Item) GetMediaDescription() string {
    for _, elem := range i.Descriptions {
        if elem.XMLName.Space == "http://search.yahoo.com/mrss/" {
            return elem.Data
        }
    }
    return ""
}