Go 的
xml
包非常出色,使得处理 XML 变得非常容易。 有一件事我不知道该怎么做:当从本机结构创建 XML 文档时,如何指定文档类型?
例如,这些结构:
type Person struct {
XMLName xml.Name `xml:"person"`
FirstName string `xml:"firstName"`
MiddleName string `xml:"middleName"`
LastName string `xml:"lastName"`
Age int64 `xml:"age"`
Skills []Skill `xml:"skills"`
}
type Skill struct {
XMLName xml.Name `xml:"skill"`
Name string `xml:"skillName"`
YearsPracticed int64 `xml:"practice"`
}
将生成类似以下 XML 的内容:
<person>
<firstName>Bob</firstName>
<middleName></middleName>
<lastName>Jones</middleName>
<age>23</age>
<skills>
<skill>
<skillName>Cooking</skillName>
<practice>3</practice>
</skill>
<skill>
<skillName>Basketball</skillName>
<practice>4</practice>
</skill>
</skills>
</person>
这很棒,但是我该怎么做才能得到这个:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<firstName>Bob</firstName>
<middleName></middleName>
...
看起来太简单了,但是这是一个字符串追加的问题吗? 反过来,Go 的 XML 解析器如何处理您想要解组到一组结构中的文本块中的文档类型? 忽略它?
中所示,包含一个通用标头:
const (
// A generic XML header suitable for use with the output of Marshal.
// This is not automatically added to any output of this package,
// it is provided as a convenience.
Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
)
所以,这样就可以了:
myString, err := xml.MarshalIndent(...) // abbreviated here
myString = []byte(xml.Header + string(myString))
我发现的一个工作示例(不是我的代码)可在:http://play.golang.org/p/Rbfb717tvh
XML 编码器,在处理 XML 流或计划处理相当大的 XML 时,它比常见的 marshal
函数更合适文件。
*File
引用,然后将
xml.Header
写入其中:
xmlFile, err := os.Create("my-file.xml")
if err != nil {
fmt.Println("Error creating XML file: ", err)
return
}
xmlFile.WriteString(xml.Header)
之后,您需要创建 XML 编码器,设置其缩进,最后将必要的结构编码到 XML 文件中:
encoder := xml.NewEncoder(xmlFile)
encoder.Indent("", "\t")
err = encoder.Encode(&myStruct)
if err != nil {
fmt.Println("Error encoding XML to file: ", err)
return
}
您应该会看到生成的 XML 文件,其中包含您想要的文档标题。
这是使用您提供的示例进行的快速 POC:
package main
import (
"encoding/xml"
"fmt"
"os"
)
// Person represents a <person> node in the XML
type Person struct {
XMLName xml.Name `xml:"person"`
FirstName string `xml:"firstName"`
MiddleName string `xml:"middleName"`
LastName string `xml:"lastName"`
Age int64 `xml:"age"`
Skills []Skill `xml:"skills"`
}
// Skill represents a <skill> node in the XML
type Skill struct {
XMLName xml.Name `xml:"skill"`
Name string `xml:"skillName"`
YearsPracticed int64 `xml:"practice"`
}
func main() {
person := Person{
FirstName: "Bob",
MiddleName: "",
LastName: "Jones",
Age: 23,
Skills: []Skill{
{
Name: "Cooking",
YearsPracticed: 3,
},
{
Name: "Basketball",
YearsPracticed: 4,
},
},
}
xmlFile, err := os.Create("person.xml")
if err != nil {
fmt.Println("Error creating XML file: ", err)
return
}
xmlFile.WriteString(xml.Header)
encoder := xml.NewEncoder(xmlFile)
encoder.Indent("", "\t")
err = encoder.Encode(&person)
if err != nil {
fmt.Println("Error encoding XML to file: ", err)
return
}
}
这将生成以下 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<firstName>Bob</firstName>
<middleName></middleName>
<lastName>Jones</lastName>
<age>23</age>
<skill>
<skillName>Cooking</skillName>
<practice>3</practice>
</skill>
<skill>
<skillName>Basketball</skillName>
<practice>4</practice>
</skill>
</person>