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 --> <?xml version="1.0"?>
<cat> <!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
<!-- in cat before --> <apple>
<x>3<!-- multi Cats are cgreat
line comment <b>things</b>
for x --></x> </apple>
<y>
<!-- in y before -->
<d><!-- in d before -->4<!-- in d after --></d>
<!-- in y after -->
</y>
<!-- in_cat_after -->
</cat>
<!-- after cat -->

View File

@ -15,6 +15,8 @@ type xmlDecoder struct {
reader io.Reader reader io.Reader
readAnything bool readAnything bool
attributePrefix string attributePrefix string
directivePrefix string
procInstPrefix string
contentName string contentName string
strictMode bool strictMode bool
keepNamespace bool keepNamespace bool
@ -33,6 +35,8 @@ func NewXMLDecoder(attributePrefix string, contentName string, strictMode bool,
strictMode: strictMode, strictMode: strictMode,
keepNamespace: keepNamespace, keepNamespace: keepNamespace,
useRawToken: useRawToken, 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) labelNode.FootComment = dec.processComment(keyValuePair.FootComment)
// }
log.Debug("len of children in %v is %v", label, len(children)) log.Debug("len of children in %v is %v", label, len(children))
if len(children) > 1 { if len(children) > 1 {
@ -282,6 +284,8 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
elem.n.HeadComment = joinFilter([]string{elem.n.HeadComment, commentStr}) 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 attributePrefix string
contentName string contentName string
indentString string indentString string
directivePrefix string
procInstPrefix string
} }
func NewXMLEncoder(indent int, attributePrefix string, contentName string) Encoder { 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++ { for index := 0; index < indent; index++ {
indentString = indentString + " " indentString = indentString + " "
} }
return &xmlEncoder{attributePrefix, contentName, indentString} return &xmlEncoder{attributePrefix, contentName, indentString, "_directive_", "_procInst_"}
} }
func (e *xmlEncoder) CanHandleAliases() bool { func (e *xmlEncoder) CanHandleAliases() bool {
@ -44,7 +46,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
switch node.Kind { switch node.Kind {
case yaml.MappingNode: case yaml.MappingNode:
err := e.encodeTopLevelMap(encoder, node) err := e.encodeTopLevelMap(encoder, node, writer)
if err != nil { if err != nil {
return err return err
} }
@ -53,7 +55,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
if err != nil { if err != nil {
return err return err
} }
err = e.encodeTopLevelMap(encoder, unwrapDoc(node)) err = e.encodeTopLevelMap(encoder, unwrapDoc(node), writer)
if err != nil { if err != nil {
return err 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)) err := e.encodeComment(encoder, headAndLineComment(node))
if err != nil { if err != nil {
return err return err
@ -92,11 +94,23 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) er
return err return err
} }
log.Debugf("recursing") 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 {
err = e.doEncode(encoder, value, start) log.Debugf("recursing")
if err != nil {
return err err = e.doEncode(encoder, value, start)
if err != nil {
return err
}
} }
err = e.encodeComment(encoder, footComment(key)) err = e.encodeComment(encoder, footComment(key))
if err != nil { if err != nil {
@ -212,8 +226,14 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.
if err != nil { if err != nil {
return err 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}} start := xml.StartElement{Name: xml.Name{Local: key.Value}}
err := e.doEncode(encoder, value, start) err := e.doEncode(encoder, value, start)
if err != nil { if err != nil {