Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write XML code to XML file in Go

Tags:

xml

go

I have a script that print-lines XML code, but I need it to write a new XML file and then write the XML code to the file instead of printing it.

Here is the function that prints the XML code

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>")
}

How can I get it to write an XML file and then write the code to that XML file?

like image 567
gomangomango Avatar asked Oct 08 '13 02:10

gomangomango


3 Answers

While printing your XML may be fine, why not use the encoding/xml package? Have your XML structure in 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"`
}

Create your data structure like this (running example on play):

card := &Card{
    Entity: "1234id",
    Facts: Facts{[]Fact{
        Fact{Property: "prop1", Value: "val1"},
        Fact{Property: "prop2", Value: "val2"},
    }},
}

Now you can encode the structure to XML and write it directly to a io.Writer:

writer, err := os.Open("/tmp/tmp.xml")

encoder := xml.NewEncoder(writer)
err := encoder.Encode(data)

if err != nil { panic(err) }
like image 119
nemo Avatar answered Oct 07 '22 08:10

nemo


Use os.Create to open the file and use fmt.Fprintf to write to it.

Example:

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)
// ...
like image 33
Brad Peabody Avatar answered Oct 07 '22 08:10

Brad Peabody


To add to bgp's (+1) correct answer; by changing the function to take a io.Writer as argument, you can output your XML to any type of output implementing the io.Writer interface.

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>")
}

Printing to screen (Stdout):

processTopic(os.Stdout, id, properties)

Writing to file (code taken from bgp's answer):

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
processTopic(f, id, properties)
like image 35
ANisus Avatar answered Oct 07 '22 10:10

ANisus