Reputation: 11
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
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