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 = `