From c1b333b2c25f45b9265cf229611b2253fb424b35 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Tue, 18 Oct 2022 14:15:25 +1100 Subject: [PATCH] Added xml support for proc instructions --- examples/mike.xml | 20 ++++++-------------- pkg/yqlib/decoder_xml.go | 8 ++++++-- pkg/yqlib/encoder_xml.go | 38 +++++++++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/examples/mike.xml b/examples/mike.xml index 94773b86..75a65193 100644 --- a/examples/mike.xml +++ b/examples/mike.xml @@ -1,14 +1,6 @@ - - - - 3 - - - 4 - - - - - \ No newline at end of file + + + +Cats are cgreat +things + \ No newline at end of file diff --git a/pkg/yqlib/decoder_xml.go b/pkg/yqlib/decoder_xml.go index d053f6ca..7ff1bcee 100644 --- a/pkg/yqlib/decoder_xml.go +++ b/pkg/yqlib/decoder_xml.go @@ -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)}) } } diff --git a/pkg/yqlib/encoder_xml.go b/pkg/yqlib/encoder_xml.go index b84b59de..39cf1bfc 100644 --- a/pkg/yqlib/encoder_xml.go +++ b/pkg/yqlib/encoder_xml.go @@ -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,11 +94,23 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) er 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) - if err != nil { - return err + log.Debugf("recursing") + + err = e.doEncode(encoder, value, start) + if err != nil { + return err + } } err = e.encodeComment(encoder, footComment(key)) if err != nil { @@ -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 {