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?
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) }
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)
// ...
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With