HagaSpa
HagaSpa

Reputation: 11

How do I use the xml package to new line the closing tag when element is empty

My goal is to break closing tag to new line when element is empty, and use Go xml package.

Also I want to indent the end tag to the same depth as the start tag when the element is empty, regardless of the nested depth.

go version go1.15.2 darwin/amd64

want

<aaa>
  <bbb>
  </bbb>
</aaa>

However, Go xml EncodeElement will generate closing tag without line breaks if the content is empty.

https://play.golang.org/p/fa76aeZ9Xss

func main() {
    var b bytes.Buffer
    e := xml.NewEncoder(&b)
    e.Indent("", "  ")
    
    aaa := xml.StartElement{Name: xml.Name{Local: "aaa"}}
    e.EncodeToken(aaa)
    
    bbb := xml.StartElement{Name: xml.Name{Local: "bbb"}}
    e.EncodeToken(bbb)
    e.EncodeToken(bbb.End())
    
    e.EncodeToken(aaa.End())

    // execute
    e.Flush()
    fmt.Println(b.String())
}
<aaa>
  <bbb></bbb>
</aaa>

I tried insert \n at <bbb>. But </bbb> is not indented.

    c := xml.CharData([]byte("\n"))
    e.EncodeToken(c)

https://play.golang.org/p/ekShCtPXBWR

<aaa>
  <bbb>
</bbb>
</aaa>

Also I want the closing tag to be indented in the same depth as the starting tag, no matter how nested.

<xxx> 
  <aaa>
  <yyy>
    <bbb>
    </bbb>
  </yyy>
  </aaa>
</xxx>

Does anyone know the solution?

Upvotes: 0

Views: 306

Answers (1)

HagaSpa
HagaSpa

Reputation: 11

Self-solved based on the information received.

Save the number of times the EncodeToken was called because you need to know how many spaces to indent.

    aaa := xml.StartElement{Name: xml.Name{Local: "aaa"}}
    e.EncodeToken(aaa)
    cnt++
    e.EncodeToken(aaa.End())

Insert an indent using the saved count.

        // insert new line, and indent
        c := "\n"
        for i := 0; i < cnt; i++ {
            c = c + "  "
        }
        e.EncodeToken(xml.CharData([]byte(c)))

https://play.golang.org/p/2-5qEHjT2B4

thank you.

Upvotes: 1

Related Questions