【问题标题】:Unmarshal XML tag that contains mixed contents(e.g. CDATA, other tags)解组包含混合内容的 XML 标记(例如 CDATA、其他标记)
【发布时间】:2019-03-25 10:23:23
【问题描述】:

尝试解组 xml 文件,例如:

<Element>
    <![CDATA[hello]]>
    <image>some_url_here</image>
    <![CDATA[world]]>
    mixed content here
</Element>

Element 标记内有不同类型的数据,我怎样才能将这个 xml 分解为一个结构,例如:

type XMLElement struct {
    XMLName xml.Name `xml:"Element"`
    CDatas []string `....`
    Image string `...`
    PlainText string `...`
}

或任何其他可以解组此 xml 的结构。

【问题讨论】:

  • @SignatureD CDatas 必须是 string[]byte,然后使用 Abdullah 评论中提到的 cdata 标签选项。 play.golang.org/p/uzNWL3mveQg
  • 您可以让您的类型实现 encoding.TextUnmarshaler 接口,然后您的类型将被调用一次,其中包含单独 CDATA 部分中存在的所有内容,这意味着您必须自己解析它然后放入切片中。
  • ... 用于将所有内容解码到一个列表中,不仅是 cdata,还包括普通元素,您必须实现 xml.Unmarshaler 接口,与 TextUnmarshaler 相比,它涉及更多,但它是当然可行,您可以在 github 上查找示例代码:github.com/search?q=language%3Ago+unmarshalxml&type=Code
  • 这是因为 UnmarshalXML 将始终以有效的 xml 元素开头,因此您需要为封闭类型实现它,然后循环解码器的标记。一秒钟后,我将创建一个不完整的示例。

标签: xml go unmarshalling cdata


【解决方案1】:

这个解决方案不是很好,因为xmlqueryCDATA元素作为TEXT节点类型,但我认为它简单易行,它使用XPath查询。

package main

import (
    "fmt"
    "strings"

    "github.com/antchfx/xmlquery"
)

func main() {
    s := `<?xml version="1.0" encoding="UTF-8"?><Element>
<![CDATA[hello]]>
<image>some_url_here</image>
<![CDATA[world]]>
</Element>
`
    doc, err := xmlquery.Parse(strings.NewReader(s))
    if err != nil {
        panic(err)
    }
    elem := xmlquery.FindOne(doc, "//Element")
    for n := elem.FirstChild; n != nil; n = n.NextSibling {
        if n.Data == "image" {
            fmt.Printf("image: %s\n", n.InnerText())
        } else if n.Type == xmlquery.TextNode {
            if len(strings.TrimSpace(n.InnerText())) == 0 {
                // skip it because its' empty node
            } else {
                fmt.Printf("cdata: %s\n", n.InnerText())
            }
        }
    }
    // or using query expression
    image := xmlquery.FindOne(doc, "//image")
    fmt.Printf("image: %s\n", image.InnerText())
}

【讨论】:

    猜你喜欢
    • 2013-11-25
    • 2021-05-02
    • 2011-12-08
    • 1970-01-01
    • 2011-11-29
    • 2016-02-05
    • 2012-08-08
    • 2014-02-28
    • 1970-01-01
    相关资源
    最近更新 更多