为了账号安全,请及时绑定邮箱和手机立即绑定

通过 UnMarshal 和 MarshalIndent 往返 xml

通过 UnMarshal 和 MarshalIndent 往返 xml

Go
扬帆大鱼 2023-04-17 16:29:52
我想使用 golang 的 xml.MarshalIndent() 快速创建一个实用程序来格式化任何 XML 数据然而这段代码package mainimport (    "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>。我失去了我的属性 - 为什么?我想避免收集虚假的元素间字符数据 - 怎么做?
查看完整描述

1 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

对于初学者,您没有正确使用属性 struct 标签,所以这是一个简单的解决方法。

  • 如果 XML 元素具有先前规则未处理的属性,并且结构具有包含“,any,attr”的关联标记的字段,则 Unmarshal 会在第一个此类字段中记录属性值。

其次,因为标记xml:",chardata"甚至不通过接口传递该字段UnmarshalXMLxml.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 解析,还要处理它是递归结构这一事实。事后删除不需要的字符是最简单的。


查看完整回答
反对 回复 2023-04-17
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信