Added xml support for proc instructions

This commit is contained in:
Mike Farah 2022-10-18 14:15:25 +11:00
parent c640888133
commit c1b333b2c2
3 changed files with 41 additions and 25 deletions

View File

@ -1,14 +1,6 @@
<!-- before cat -->
<cat>
<!-- in cat before -->
<x>3<!-- multi
line comment
for x --></x>
<y>
<!-- in y before -->
<d><!-- in d before -->4<!-- in d after --></d>
<!-- in y after -->
</y>
<!-- in_cat_after -->
</cat>
<!-- after cat -->
<?xml version="1.0"?>
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
<apple>
Cats are cgreat
<b>things</b>
</apple>

View File

@ -15,6 +15,8 @@ type xmlDecoder struct {
reader io.Reader
readAnything bool
attributePrefix string
directivePrefix string
procInstPrefix string
contentName string
strictMode bool
keepNamespace bool
@ -33,6 +35,8 @@ func NewXMLDecoder(attributePrefix string, contentName string, strictMode bool,
strictMode: strictMode,
keepNamespace: keepNamespace,
useRawToken: useRawToken,
directivePrefix: "_directive_",
procInstPrefix: "_procInst_",
}
}
@ -86,9 +90,7 @@ func (dec *xmlDecoder) createMap(n *xmlNode) (*yaml.Node, error) {
}
// if i == len(n.Children)-1 {
labelNode.FootComment = dec.processComment(keyValuePair.FootComment)
// }
log.Debug("len of children in %v is %v", label, len(children))
if len(children) > 1 {
@ -282,6 +284,8 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
elem.n.HeadComment = joinFilter([]string{elem.n.HeadComment, commentStr})
}
case xml.ProcInst:
elem.n.AddChild(dec.procInstPrefix+se.Target, &xmlNode{Data: string(se.Inst)})
}
}

View File

@ -15,6 +15,8 @@ type xmlEncoder struct {
attributePrefix string
contentName string
indentString string
directivePrefix string
procInstPrefix string
}
func NewXMLEncoder(indent int, attributePrefix string, contentName string) Encoder {
@ -23,7 +25,7 @@ func NewXMLEncoder(indent int, attributePrefix string, contentName string) Encod
for index := 0; index < indent; index++ {
indentString = indentString + " "
}
return &xmlEncoder{attributePrefix, contentName, indentString}
return &xmlEncoder{attributePrefix, contentName, indentString, "_directive_", "_procInst_"}
}
func (e *xmlEncoder) CanHandleAliases() bool {
@ -44,7 +46,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
switch node.Kind {
case yaml.MappingNode:
err := e.encodeTopLevelMap(encoder, node)
err := e.encodeTopLevelMap(encoder, node, writer)
if err != nil {
return err
}
@ -53,7 +55,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
if err != nil {
return err
}
err = e.encodeTopLevelMap(encoder, unwrapDoc(node))
err = e.encodeTopLevelMap(encoder, unwrapDoc(node), writer)
if err != nil {
return err
}
@ -76,7 +78,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
}
func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) error {
func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node, writer io.Writer) error {
err := e.encodeComment(encoder, headAndLineComment(node))
if err != nil {
return err
@ -92,12 +94,24 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) er
return err
}
if strings.HasPrefix(key.Value, e.procInstPrefix) && key.Value != e.contentName {
name := strings.Replace(key.Value, e.procInstPrefix, "", 1)
procInst := xml.ProcInst{Target: name, Inst: []byte(value.Value)}
if err := encoder.EncodeToken(procInst); err != nil {
return err
}
if _, err := writer.Write([]byte("\n")); err != nil {
log.Warning("Unable to write newline, skipping: %w", err)
}
} else {
log.Debugf("recursing")
err = e.doEncode(encoder, value, start)
if err != nil {
return err
}
}
err = e.encodeComment(encoder, footComment(key))
if err != nil {
return err
@ -212,8 +226,14 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.
if err != nil {
return err
}
if strings.HasPrefix(key.Value, e.procInstPrefix) && key.Value != e.contentName {
name := strings.Replace(key.Value, e.procInstPrefix, "", 1)
procInst := xml.ProcInst{Target: name, Inst: []byte(value.Value)}
if err := encoder.EncodeToken(procInst); err != nil {
return err
}
if !strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
} else if !strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
start := xml.StartElement{Name: xml.Name{Local: key.Value}}
err := e.doEncode(encoder, value, start)
if err != nil {