问题
I'm writing XML from the following struct:
type OrderLine struct {
LineNumber string `xml:"LineNumber"`
Product string `xml:"Product"`
Ref string `xml:"Ref"`
Quantity string `xml:"Quantity"`
Price string `xml:"Price"`
LineTotalGross string `xml:"LineTotalGross"`
}
If the Ref
field is empty, I'd like the element to display, but be self-closing, i.e.
<Ref />
and not:
<Ref></Ref>
AFAIK, these two are semantically equivalent, but I would prefer a self-closing tag, as it matches the output from other systems. Is this possible?
回答1:
I found a way to do it "hacking" marshal package, but I didn't test it. If you want me to show you the link, let me now, then I post it in comments of this reply.
I did some manually code:
package main
import (
"encoding/xml"
"fmt"
"regexp"
"strings"
)
type ParseXML struct {
Person struct {
Name string `xml:"Name"`
LastName string `xml:"LastName"`
Test string `xml:"Abc"`
} `xml:"Person"`
}
func main() {
var err error
var newPerson ParseXML
newPerson.Person.Name = "Boot"
newPerson.Person.LastName = "Testing"
var bXml []byte
var sXml string
bXml, err = xml.Marshal(newPerson)
checkErr(err)
sXml = string(bXml)
r, err := regexp.Compile(`<([a-zA-Z0-9]*)><(\\|\/)([a-zA-Z0-9]*)>`)
checkErr(err)
matches := r.FindAllString(sXml, -1)
fmt.Println(sXml)
if len(matches) > 0 {
r, err = regexp.Compile("<([a-zA-Z0-9]*)>")
for i := 0; i < len(matches); i++ {
xmlTag := r.FindString(matches[i])
xmlTag = strings.Replace(xmlTag, "<", "", -1)
xmlTag = strings.Replace(xmlTag, ">", "", -1)
sXml = strings.Replace(sXml, matches[i], "<"+xmlTag+" />", -1)
}
}
fmt.Println("")
fmt.Println(sXml)
}
func checkErr(chk error) {
if chk != nil {
panic(chk)
}
}
来源:https://stackoverflow.com/questions/38118100/go-encoding-xml-how-can-i-marshal-self-closing-elements