From eaeeffe4176737e84fcfaa936d75cb38df2d97ae Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sun, 2 Jan 2022 12:51:30 +1100 Subject: [PATCH] wip --- pkg/yqlib/decoder_xml.go | 29 ++-- pkg/yqlib/doc/usage/xml.md | 270 ------------------------------------- pkg/yqlib/xml_test.go | 174 ++++++++++++++---------- 3 files changed, 117 insertions(+), 356 deletions(-) diff --git a/pkg/yqlib/decoder_xml.go b/pkg/yqlib/decoder_xml.go index 49dc222c..31fcf033 100644 --- a/pkg/yqlib/decoder_xml.go +++ b/pkg/yqlib/decoder_xml.go @@ -233,6 +233,7 @@ func (dec *xmlDecoder) decodeXml(root *xmlNode) error { elem.n.Data = trimNonGraphic(string(se)) if elem.n.Data != "" { elem.state = "chardata" + log.Debug("chardata [%v] for %v", elem.n.Data, elem.label) } case xml.EndElement: log.Debug("end element %v", elem.label) @@ -249,18 +250,7 @@ func (dec *xmlDecoder) decodeXml(root *xmlNode) error { commentStr := string(xml.CharData(se)) if elem.state == "started" { log.Debug("got a foot comment for %v: [%v]", elem.label, commentStr) - // elem.n.FootComment = elem.n.FootComment + commentStr - // put the comment on the foot of the last child - if len(elem.n.Children) > 0 { - - child := elem.n.Children[len(elem.n.Children)-1] - log.Debug("putting it here: %v", child.K) - child.V[len(child.V)-1].FootComment = joinFilter([]string{child.V[len(child.V)-1].FootComment, commentStr}) - } else { - log.Debug("putting it on the element") - elem.n.FootComment = joinFilter([]string{elem.n.FootComment, commentStr}) - } - + dec.placeFootCommentOnLastChild(elem.n, commentStr) } else if elem.state == "chardata" { log.Debug("got a line comment for (%v) %v: [%v]", elem.state, elem.label, commentStr) elem.n.LineComment = joinFilter([]string{elem.n.LineComment, commentStr}) @@ -275,6 +265,21 @@ func (dec *xmlDecoder) decodeXml(root *xmlNode) error { return nil } +func (dec *xmlDecoder) placeFootCommentOnLastChild(n *xmlNode, commentStr string) { + if len(n.Children) > 0 { + child := n.Children[len(n.Children)-1] + log.Debug("putting it here: %v", child.K) + dec.placeFootCommentOnLastChild(child.V[len(child.V)-1], commentStr) + } else { + log.Debug("putting it on the element") + if n.FootComment != "" { + n.FootComment = n.FootComment + "\n" + strings.TrimSpace(commentStr) + } else { + n.FootComment = commentStr + } + } +} + func joinFilter(rawStrings []string) string { stringsToJoin := make([]string, 0) for _, str := range rawStrings { diff --git a/pkg/yqlib/doc/usage/xml.md b/pkg/yqlib/doc/usage/xml.md index 9b49b961..eee366c4 100644 --- a/pkg/yqlib/doc/usage/xml.md +++ b/pkg/yqlib/doc/usage/xml.md @@ -22,273 +22,3 @@ XML nodes that have attributes then plain content, e.g: The content of the node will be set as a field in the map with the key "+content". Use the `--xml-content-name` flag to change this. -## Parse xml: simple -Given a sample.xml file of: -```xml - -meow -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -cat: meow -``` - -## Parse xml: array -Consecutive nodes with identical xml names are assumed to be arrays. - -Given a sample.xml file of: -```xml - -1 -2 -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -animal: - - "1" - - "2" -``` - -## Parse xml: attributes -Attributes are converted to fields, with the attribute prefix. - -Given a sample.xml file of: -```xml - - - 7 - -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -cat: - +legs: "4" - legs: "7" -``` - -## Parse xml: attributes with content -Content is added as a field, using the content name - -Given a sample.xml file of: -```xml - -meow -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -cat: - +content: meow - +legs: "4" -``` - -## Parse xml: with comments -A best attempt is made to preserve comments. - -Given a sample.xml file of: -```xml - - - - - 3 - - - - z - - - - - - - -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -# before cat -cat: - # in cat before - x: "3" # multi - # line comment - # for x - # before y - - y: - # in y before - # in d before - d: z # in d after - # in y after - -# after cat -``` - -## Encode xml: simple -Given a sample.yml file of: -```yaml -cat: purrs -``` -then -```bash -yq e -o=xml '.' sample.yml -``` -will output -```xml -purrs -``` - -## Encode xml: array -Given a sample.yml file of: -```yaml -pets: - cat: - - purrs - - meows -``` -then -```bash -yq e -o=xml '.' sample.yml -``` -will output -```xml - - purrs - meows - -``` - -## Encode xml: attributes -Fields with the matching xml-attribute-prefix are assumed to be attributes. - -Given a sample.yml file of: -```yaml -cat: - +name: tiger - meows: true - -``` -then -```bash -yq e -o=xml '.' sample.yml -``` -will output -```xml - - true - -``` - -## Encode xml: attributes with content -Fields with the matching xml-content-name is assumed to be content. - -Given a sample.yml file of: -```yaml -cat: - +name: tiger - +content: cool - -``` -then -```bash -yq e -o=xml '.' sample.yml -``` -will output -```xml -cool -``` - -## Encode xml: comments -A best attempt is made to copy comments to xml. - -Given a sample.yml file of: -```yaml -# above_cat -cat: # inline_cat - # above_array - array: # inline_array - - val1 # inline_val1 - # above_val2 - - val2 # inline_val2 -# below_cat - -``` -then -```bash -yq e -o=xml '.' sample.yml -``` -will output -```xml - - val1 - val2 - -``` - -## Round trip: with comments -A best effort is made, but comment positions and white space are not preserved perfectly. - -Given a sample.xml file of: -```xml - - - - - 3 - - - - z - - - - - - - -``` -then -```bash -yq e -p=xml '.' sample.xml -``` -will output -```yaml -# before cat -cat: - # in cat before - x: "3" # multi - # line comment - # for x - # before y - - y: - # in y before - # in d before - d: z # in d after - # in y after - -# after cat -``` - diff --git a/pkg/yqlib/xml_test.go b/pkg/yqlib/xml_test.go index 12fb81bc..15b32255 100644 --- a/pkg/yqlib/xml_test.go +++ b/pkg/yqlib/xml_test.go @@ -86,7 +86,7 @@ for x --> - + @@ -95,6 +95,25 @@ for x --> ` +var expectedDecodeYamlWithSubChild = `D0, P[], (doc)::# before cat +cat: + # in cat before + x: "3" # multi + # line comment + # for x + # before y + + y: + # in y before + # in d before + d: + z: + sweet: cool + # in d after + # in y after + # after cat +` + var inputXmlWithCommentsWithArray = ` @@ -159,82 +178,89 @@ var expectedXmlWithComments = `