golang [xml] xml解析与创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang [xml] xml解析与创建相关的知识,希望对你有一定的参考价值。

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
)

type Post struct {
	XMLName xml.Name `xml:"post"`
	Id      string   `xml:"id,attr"`
	Content string   `xml:"content"`
	Author  Author   `xml:"author"`
}

type Author struct {
	Id   string `xml:"id,attr"`
	Name string `xml:",chardata"`
}

func main() {
	post := Post{
		Id:      "1",
		Content: "Hello World!",
		Author: Author{
			Id:   "2",
			Name: "Sau Sheong",
		},
	}
  // output, err := xml.Marshal(&post)
  output, err := xml.MarshalIndent(&post, "", "\t\t")
	if err != nil {
		fmt.Println("Error marshalling to XML:", err)
		return
	}
	err = ioutil.WriteFile("post.xml", []byte(xml.Header + string(output)), 0644)
	if err != nil {
		fmt.Println("Error writing XML to file:", err)
		return
	}
}

/*
<?xml version="1.0" encoding="UTF-8"?>
<post id="1">
		<content>Hello World!</content>
		<author id="2">Sau Sheong</author>
</post>
*/
package main

import (
	"encoding/xml"
	"fmt"
	"os"
)

type Post struct {
	XMLName xml.Name `xml:"post"`
	Id      string   `xml:"id,attr"`
	Content string   `xml:"content"`
	Author  Author   `xml:"author"`
}

type Author struct {
	Id   string `xml:"id,attr"`
	Name string `xml:",chardata"`
}

func main() {
	post := Post{
		Id:      "1",
		Content: "Hello World!",
		Author: Author{
			Id:   "2",
			Name: "Sau Sheong",
		},
	}

	xmlFile, err := os.Create("post.xml")
	if err != nil {
		fmt.Println("Error creating XML file:", err)
		return
	}
	encoder := xml.NewEncoder(xmlFile)
	encoder.Indent("", "\t")
	err = encoder.Encode(&post)
	if err != nil {
		fmt.Println("Error encoding XML to file:", err)
		return
	}
}

/*
<?xml version="1.0" encoding="UTF-8"?>
<post id="1">
		<content>Hello World!</content>
		<author id="2">Sau Sheong</author>
</post>
*/
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

type Post struct {
	XMLName  xml.Name  `xml:"post"`
	Id       string    `xml:"id,attr"`
	Content  string    `xml:"content"`
	Author   Author    `xml:"author"`
	Xml      string    `xml:",innerxml"`
	Comments []Comment `xml:"comments>comment"`
}

type Author struct {
	Id   string `xml:"id,attr"`
	Name string `xml:",chardata"`
}

type Comment struct {
	Id      string `xml:"id,attr"`
	Content string `xml:"content"`
	Author  Author `xml:"author"`
}

func main() {
	xmlFile, err := os.Open("post.xml")
	if err != nil {
		fmt.Println("Error opening XML file:", err)
		return
	}
	defer xmlFile.Close()
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		fmt.Println("Error reading XML data:", err)
		return
	}

	var post Post
	xml.Unmarshal(xmlData, &post)
	fmt.Println(post)
}

/*
<?xml version="1.0" encoding="utf-8"?>
<post id="1">
  <content>Hello World!</content>
  <author id="2">Sau Sheong</author>
  <comments>
    <comment id="1">
      <content>Have a great day!</content>
      <author>Adam</author>
    </comment>
    <comment id="2">
      <content>How are you today?</content>
      <author>Betty</author>
    </comment>
  </comments>
</post>
*/
package main

import (
	"encoding/xml"
	"fmt"
	"io"
	"os"
)

type Post struct {
	XMLName  xml.Name  `xml:"post"`
	Id       string    `xml:"id,attr"`
	Content  string    `xml:"content"`
	Author   Author    `xml:"author"`
	Xml      string    `xml:",innerxml"`
	Comments []Comment `xml:"comments>comment"`
}

type Author struct {
	Id   string `xml:"id,attr"`
	Name string `xml:",chardata"`
}

type Comment struct {
	Id      string `xml:"id,attr"`
	Content string `xml:"content"`
	Author  Author `xml:"author"`
}

func main() {
	xmlFile, err := os.Open("post.xml")
	if err != nil {
		fmt.Println("Error opening XML file:", err)
		return
	}
	defer xmlFile.Close()

	decoder := xml.NewDecoder(xmlFile)
	for {
		t, err := decoder.Token()
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Println("Error decoding XML into tokens:", err)
			return
		}

		switch se := t.(type) {
		case xml.StartElement:
			if se.Name.Local == "comment" {
				var comment Comment
				decoder.DecodeElement(&comment, &se)
				fmt.Println(comment)
			}
		}
	}
}

/*
<?xml version="1.0" encoding="utf-8"?>
<post id="1">
  <content>Hello World!</content>
  <author id="2">Sau Sheong</author>
  <comments>
    <comment id="1">
      <content>Have a great day!</content>
      <author id="3">Adam</author>
    </comment>
    <comment id="2">
      <content>How are you today?</content>
      <author id="4">Betty</author>
    </comment>
  </comments>
</post>
*/

golang XML解析动态标签名称

我必须解析遗留系统的xml输出,因为它们出于某种原因认为将值的ID添加为标记名称是明智的。

像这样:

<ValueList>
  <ArraySize>2</ArraySize>
  <v89BNZMpdlWXkuv>value1</v89BNZMpdlWXkuv>
  <v89N83oCrGhI7jh>value2</v89N83oCrGhI7jh>
</ValueList>

我想将它解析为这样的结构:

type ValueList struct {
    Values []Value
}

type Value struct {
    ID string
    Value String
}

我已经开始使用自定义unmarshal函数了

func (vl *ValueList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    ...
}

并从xml.Decoder获得令牌,但这是丑陋的。有没有更好的办法?

答案

是的,您可以使用xmlquery来解析XML并提取数据,甚至是动态标记名称。像这样的代码:

doc,err:=xmlquery.Parse(`<xml>..`)
node:=xmlquery.FindOne(doc,"//ValueList")
// Travel all child-node of ValueList
for n:=node.FirstChild;n!=nil;n=n.NextSibling{
  fmt.Println(n.Data) // Ouptut name: ArraySize,v89BNZMpdlWXkuv,v89N83oCrGhI7jh
  fmt.Println(n.InnerText())// Value of child-node.
}

希望可以帮到你。

以上是关于golang [xml] xml解析与创建的主要内容,如果未能解决你的问题,请参考以下文章

超危Golang XML解析器漏洞可导致SAML身份验证绕过

如何使用golang解析其中没有字段名的xml行

Golang,XML解析为结构?

golang XML解析动态标签名称

Xml Unmarshalling 导致 golang 中的垃圾字符

Android 创建与解析XML—— 概述