将XML代码写入Go中的XML文件
我有一个脚本可以打印行XML代码,但我需要它来编写一个新的XML文件,然后将XML代码写入该文件,而不是打印它 下面是打印XML代码的函数将XML代码写入Go中的XML文件,xml,go,Xml,Go,我有一个脚本可以打印行XML代码,但我需要它来编写一个新的XML文件,然后将XML代码写入该文件,而不是打印它 下面是打印XML代码的函数 func processTopic(id string, properties map[string][]string) { fmt.Printf("<card entity=\"%s\">\n", id) fmt.Println(" <facts>") for k, v := range propertie
func processTopic(id string, properties map[string][]string) {
fmt.Printf("<card entity=\"%s\">\n", id)
fmt.Println(" <facts>")
for k, v := range properties {
for _,value := range v {
fmt.Printf(" <fact property=\"%s\">%s</fact>\n", k, value)
}
}
fmt.Println(" </facts>")
fmt.Println("</card>")
}
func processTopic(id字符串,属性映射[string][]string){
fmt.Printf(“\n”,id)
格式打印项次(“”)
对于k,v:=范围属性{
对于u,值:=范围v{
fmt.Printf(“%s\n”,k,值)
}
}
格式打印项次(“”)
格式打印项次(“”)
}
如何让它编写一个XML文件,然后将代码写入该XML文件?用于打开该文件并对其进行写入
例如:
f, err := os.Create("out.xml") // create/truncate the file
if err != nil { panic(err) } // panic if error
defer f.Close() // make sure it gets closed after
fmt.Fprintf(f, "<card entity=\"%s\">\n", id)
// ...
f,err:=os.Create(“out.xml”)//创建/截断文件
如果出错!=nil{panic(err)}//如果发生错误,则为panic
defer f.Close()//确保在
fmt.Fprintf(f,“\n”,id)
// ...
添加到bgp的(+1)正确答案中;通过将函数更改为以io.Writer作为参数,可以将XML输出到实现接口的任何类型的输出
func processTopic(w io.Writer, id string, properties map[string][]string) {
fmt.Fprintf(w, "<card entity=\"%s\">\n", id)
fmt.Fprintln(w, " <facts>")
for k, v := range properties {
for _,value := range v {
fmt.Fprintf(w, " <fact property=\"%s\">%s</fact>\n", k, value)
}
}
fmt.Fprintln(w, " </facts>")
fmt.Fprintln(w, "</card>")
}
写入文件(代码取自bgp的答案):
虽然打印XML可能很好,但为什么不使用
编码/XML
包呢?
将您的XML结构置于go中:
type Card struct {
Entity string `xml:"entity,attr"`
Facts Facts
}
type Facts struct {
Fact []Fact
}
type Fact struct {
Property string `xml:"property,attr"`
Value string `xml:",innerxml"`
}
创建如下()所示的数据结构:
现在,您可以将结构编码为XML,并将其直接写入io.Writer
:
writer, err := os.Open("/tmp/tmp.xml")
encoder := xml.NewEncoder(writer)
err := encoder.Encode(data)
if err != nil { panic(err) }
支持nemo对
编码/xml
的评论;根据您接收事实
数据的方式,如果它作为map[string]字符串
接收,则您还可以为事实
映射创建封送器和解封送器。这稍微复杂一点,如果您处理的是较大的数据集,而不是以有序方式接收的数据集(即无序映射与有序数组/切片),那么这可能会有所帮助
是的,很好的观点-这在关注点分离方面更好。生成XML肯定不需要与输出XML处于同一个函数中。+1,因为它还可以帮助确保字符串值被正确转义。另外还有编译时类型检查。
type Card struct {
Entity string `xml:"entity,attr"`
Facts Facts
}
type Facts struct {
Fact []Fact
}
type Fact struct {
Property string `xml:"property,attr"`
Value string `xml:",innerxml"`
}
card := &Card{
Entity: "1234id",
Facts: Facts{[]Fact{
Fact{Property: "prop1", Value: "val1"},
Fact{Property: "prop2", Value: "val2"},
}},
}
writer, err := os.Open("/tmp/tmp.xml")
encoder := xml.NewEncoder(writer)
err := encoder.Encode(data)
if err != nil { panic(err) }
package main
import (
"encoding/xml"
"io"
"os"
)
type FactMap map[string]string
type factXml struct {
XMLName xml.Name `xml:"fact"`
Prop string `xml:"property,attr"`
Value string `xml:",innerxml"`
}
// Marshal the fact map
func (fm FactMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if len(fm) == 0 {
return nil
}
err := e.EncodeToken(start)
if err != nil {
return err
}
for k, v := range fm {
// XML encoding the `fact` XML entry
e.Encode(factXml{Prop: k, Value: v})
}
return e.EncodeToken(start.End())
}
// Unmarshal the fact map
func (fm *FactMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
*fm = FactMap{}
for {
var f factXml
err := d.Decode(&f)
if err == io.EOF {
break
} else if err != nil {
return err
}
(*fm)[f.Prop] = f.Value
}
return nil
}
// Note usage of xml.Name to set the outer XML to `card`, as well as setting Entity as an `entity,attr`
type Card struct {
XMLName xml.Name `xml:"card"`
Entity int `xml:"entity,attr"`
Facts FactMap `xml:"facts"`
}
func main() {
props1 := map[string]string{"key1": "val1", "key2": "val2"}
// Populate the Card struct and marshal it
card := Card{Entity: 5, Facts: props1}
// Append to the file
var f *os.File
// Check if thet file exists, err != nil if the file does not exist
_, err := os.Stat("my.xml")
if err != nil {
// if the file doesn't exist, open it with write and create flags
f, err = os.OpenFile("my.xml", os.O_WRONLY|os.O_CREATE, 0666)
} else {
// if the file does exist, open it with append and write flags
f, err = os.OpenFile("my.xml", os.O_APPEND|os.O_WRONLY, 0666)
}
if err != nil {
panic(err)
}
defer f.Close()
e := xml.NewEncoder(f)
// Write marshal the card struct to the file
err = e.Encode(card)
if err != nil {
panic(err)
}
}