CDATA support
estronnom opened this issue · 4 comments
Hi! I was wondering is there any way to use CDATA element with your lib?
Thanks
What exactly do you want to achieve? Could you give an exact example with code and example output?
The KML structure I'm trying to get should look like this:
<ExtendedData>
<Data name="extraImage">
<![CDATA[files/image_1.jpg]]>
</Data>
</ExtendedData>
So, the code example to generate it with go-kml may look like this:
kml.ExtendedData(
kml.Data(
"extraImage",
kml.CharacterData("files/image_1.jpg"), //CDATA
),
)
Also, an xml struct to parse such structure should utilize chardata
encoding/xml tag:
type DataWithCDATA struct {
ChardataValue string `xml:",chardata"`
}
Thanks for the follow-up.
CDATA elements are used to escape character data. The standard library's encoding/xml
(on which github.com/twpayne/go-kml
is based) automatically escapes character data if needed, so, as a user you never need to think about whether you have to use CDATA.
As files/image_1.jpg
does not need escaping, the following two XML documents are equivalent:
<ExtendedData>
<Data name="extraImage">
<![CDATA[files/image_1.jpg]]>
</Data>
</ExtendedData>
<ExtendedData>
<Data name="extraImage">files/image_1.jpg</Data>
</ExtendedData>
However, if the KML you are generated is consumed by a broken code that expects a CDATA directive, then you can pass any Go value that implements encoding/xml.Marshaler
as a KML child element, so you can force use of a CDATA directive.
For example:
package main
import (
"encoding/xml"
"os"
"github.com/twpayne/go-kml/v3"
)
type CData string
func (c CData) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
directive := xml.Directive([]byte("[CDATA[" + string(c) + "]]"))
return e.EncodeToken(directive)
}
func main() {
extendedData := kml.ExtendedData(
kml.Data(
"extraImage",
CData("files/image1.jpg"),
),
)
e := xml.NewEncoder(os.Stdout)
e.Indent("", "\t")
e.Encode(extendedData)
}
which outputs:
<ExtendedData>
<Data name="extraImage"><![CDATA[files/image1.jpg]]></Data>
</ExtendedData>
You can see this example in the Go playground.
If you can avoid using a broken XML parser then you don't need CDATA.
Thank you! That does exactly what I needed, closing this.