通过 UnMarshal 和 MarshalIndent 往返 xml

我想使用 golang 的 xml.MarshalIndent() 快速创建一个实用程序来格式化任何 XML 数据

然而这段代码

package main


import (

    "encoding/xml"

    "fmt"

)


func main() {


    type node struct {

        XMLName  xml.Name

        Attrs    []xml.Attr `xml:",attr"`

        Text     string     `xml:",chardata"`

        Children []node     `xml:",any"`

    }


    x := node{}

    _ = xml.Unmarshal([]byte(doc), &x)

    buf, _ := xml.MarshalIndent(x, "", "  ") // prefix, indent


    fmt.Println(string(buf))

}


const doc string = `<book>

     <title>The old man and the sea</title>

       <author>Hemingway</author>

</book>`

产品


<book>&#xA;     &#xA;       &#xA;

  <title>The old man and the sea</title>

  <author>Hemingway</author>

</book>

请注意打开元素后的外来物质<book>。


我失去了我的属性 - 为什么?

我想避免收集虚假的元素间字符数据 - 怎么做?


扬帆大鱼
浏览 104回答 1
1回答

慕的地8271018

对于初学者,您没有正确使用属性 struct 标签,所以这是一个简单的解决方法。如果 XML 元素具有先前规则未处理的属性,并且结构具有包含“,any,attr”的关联标记的字段,则 Unmarshal 会在第一个此类字段中记录属性值。其次,因为标记xml:",chardata"甚至不通过接口传递该字段UnmarshalXML,xml.Unmarshaller所以您不能简单地为它创建一个新类型Text并为它实现该接口,如同一文档中所述。(注意除 []byte 或 string 以外的任何类型都会强制报错)如果 XML 元素包含字符数据,则该数据将累积在具有标记“,chardata”的第一个结构字段中。struct 字段的类型可以是 []byte 或 string。如果没有这样的字段,字符数据将被丢弃。因此,处理不需要的字符的最简单方法是在事后替换它们。var Replacer = strings.NewReplacer("&#xA;","","&#x9;","","\n","","\t","")func recursiveReplace(n *Node) {    n.Text = Replacer.Replace(n.Text)    for i := range n.Children {        recursiveReplace(&n.Children[i])    }}理论上可以实现xml.Unmarshaller的接口Node,但是您不仅要处理手动 xml 解析,还要处理它是递归结构这一事实。事后删除不需要的字符是最简单的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go