Go's xml
package is excellent and makes dealing with XML very easy. There's one thing I'm not sure how to do: when creating an XML document from a native struct, how do you specify the doctype?
For example, these structs:
type Person struct {
XMLName xml.Name `xml:"person"`
FirstName string `xml:"firstName"`
MiddleName string `xml:"middleName"`
LastName string `xml:"lastName"`
Age int64 `xml:"age"`
Skills []Skill `xml:"skills"`
}
type Skill struct {
XMLName xml.Name `xml:"skill"`
Name string `xml:"skillName"`
YearsPracticed int64 `xml:"practice"`
}
Will generate something like this XML:
<person>
<firstName>Bob</firstName>
<middleName></middleName>
<lastName>Jones</middleName>
<age>23</age>
<skills>
<skill>
<skillName>Cooking</skillName>
<practice>3</practice>
</skill>
<skill>
<skillName>Basketball</skillName>
<practice>4</practice>
</skill>
</skills>
</person>
Which is great, but what do I do to get this:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<firstName>Bob</firstName>
<middleName></middleName>
...
It almost seems too simple, but is this a matter of doing a string append?
And, on the reverse, how would Go's XML parser handle a doctype in a block of text that you wanted to unmarshal into a set of structs? Ignore it?
DOCTYPE> is not mandatory in XML. It is mandatory in XHTML as @Lashane has answered. It ( doctypedecl ) is optional in XML: [1] document ::= prolog element Misc* [22] prolog ::= XMLDecl?
XML documents can contain an XML declaration that if present, must be the first construct in the document. An XML declaration is made up of as many as three name/value pairs, syntactically identical to attributes. The three attributes are a mandatory version attribute and optional encoding and standalone attributes.
When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".
Simply append your marshalled bytes to the header. As seen in the XML Package Source, a generic header is included:
const (
// A generic XML header suitable for use with the output of Marshal.
// This is not automatically added to any output of this package,
// it is provided as a convenience.
Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
)
So, this would do it:
myString, err := xml.MarshalIndent(...) // abbreviated here
myString = []byte(xml.Header + string(myString))
A working example I'd found (not my code) available at: http://play.golang.org/p/Rbfb717tvh
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