Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将XML代码写入Go中的XML文件_Xml_Go - Fatal编程技术网

将XML代码写入Go中的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

我有一个脚本可以打印行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 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)
    }
}