代码之家  ›  专栏  ›  技术社区  ›  RedGrittyBrick

通过解组和封送缩进的往返xml

  •  1
  • RedGrittyBrick  · 技术社区  · 6 年前

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

    然而 this code

    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 lang="en">
         <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 回复  |  直到 6 年前
        1
  •  1
  •   RayfenWindspear    6 年前

    对于初学者来说,您没有正确使用attribute struct标记,因此这是一个简单的解决方法。

    https://godoc.org/encoding/xml#Unmarshal

    • 如果XML元素具有上一个 规则和结构有一个字段,该字段有一个包含 “,any,attr”,Unmarshal在第一行记录属性值

    第二,因为标签 xml:",chardata" 甚至没有穿过那个区域 UnmarshalXML xml.Unmarshaller Text 并为其实现相同文档中所述的接口(请注意,除[]字节或字符串以外的任何类型都将强制执行错误)

    • 如果XML元素包含字符数据,则该数据为 在第一个带有标记“chardata”的结构字段中累积。

    因此,处理不需要的字符最简单的方法就是事后替换它们。

    https://play.golang.org/p/VSDskgfcLng

    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解析,而且还要处理它是一个递归结构的事实。最简单的方法是在事后删除不需要的字符。