Beautify XML

1,538 views
Skip to first unread message

Tong Sun

unread,
Nov 4, 2016, 5:32:24 PM11/4/16
to golang-nuts
How to beautify a given XML string in GO? 

The xml.MarshalIndent() only apply to a GO structure, not XML strings. 

Thanks

C Banning

unread,
Nov 4, 2016, 5:57:48 PM11/4/16
to golang-nuts

Sam Whited

unread,
Nov 5, 2016, 11:40:33 AM11/5/16
to Tong Sun, golang-nuts
On Fri, Nov 4, 2016 at 4:32 PM, Tong Sun <sunto...@gmail.com> wrote:
> How to beautify a given XML string in GO?
>
> The xml.MarshalIndent() only apply to a GO structure, not XML strings.

Aside: Note that the language is called "Go", not "GO".

I've been playing around with an XML token stream processing API:

https://godoc.org/mellium.im/xmlstream

It's still experimental, and likely to change, but it would probably
be pretty easy to write a transformer that keeps track of iindentation
and adds/removes whitespace tokens as necessary (in fact, that's one
of the things I wanted something like this for in the first place).

—Sam

--
Sam Whited
pub 4096R/54083AE104EA7AD3

Tong Sun

unread,
Nov 5, 2016, 11:58:05 AM11/5/16
to Sam Whited, golang-nuts

On Sat, Nov 5, 2016 at 11:39 AM, Sam Whited <s...@samwhited.com> wrote:
I've been playing around with an XML token stream processing API:

https://godoc.org/mellium.im/xmlstream

It's still experimental, and likely to change, but it would probably
be pretty easy to write a transformer that keeps track of iindentation
and adds/removes whitespace tokens as necessary (in fact, that's one
of the things I wanted something like this for in the first place).

So any plan to add beautify a given XML string feature soon? Thx. 

Sam Whited

unread,
Nov 5, 2016, 12:15:04 PM11/5/16
to Tong Sun, golang-nuts
On Sat, Nov 5, 2016 at 10:57 AM, Tong Sun <sunto...@gmail.com> wrote:
> So any plan to add beautify a given XML string feature soon? Thx.

No, sorry, I was just pointing out that by manipulating a token stream
you could probably do it yourself fairly easily. Eg. something like
this simple example (most of the error handling was ignored here,
obviously that would not be ideal in a real implementation):

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

Sam Whited

unread,
Nov 5, 2016, 12:17:00 PM11/5/16
to Tong Sun, golang-nuts
I should also state that in this example you could of course just use
MarshalIndent, the point was to show that you could do it manually if
you need more customized formatting.

Sam Whited

unread,
Nov 5, 2016, 12:27:40 PM11/5/16
to Tong Sun, golang-nuts
On Fri, Nov 4, 2016 at 4:32 PM, Tong Sun <sunto...@gmail.com> wrote:
> How to beautify a given XML string in GO?
>
> The xml.MarshalIndent() only apply to a GO structure, not XML strings.

Sorry, third time's the charm. I think I didn't understand what you
were asking. If all you need is the bulit in indentation you can use
an encoder and its indent method:

https://godoc.org/encoding/xml#Encoder.Indent

This is what MarshalIndent is doing under the hood. My example still
applies, but you don't have to do it yourself. Instead you can just
set the indentation on the encoder:

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

Tong Sun

unread,
Nov 5, 2016, 12:29:06 PM11/5/16
to Sam Whited, golang-nuts
Oh, thank you Sam for both of your points. Each is very valuable to me!

Oh, and the third one too. :-) 

Thanks again!

On Sat, Nov 5, 2016 at 12:16 PM, Sam Whited <s...@samwhited.com> wrote:
I should also state that in this example you could of course just use
MarshalIndent, the point was to show that you could do it manually if
you need more customized formatting.

Eric Johnson

unread,
Nov 7, 2016, 12:20:55 PM11/7/16
to golang-nuts

On Friday, November 4, 2016 at 2:32:24 PM UTC-7, Tong Sun wrote:
How to beautify a given XML string in GO? 

As someone who has spent a fair amount of time in the complexities of XML, it is worth noting that XML is not equivalent to JSON in the context of your question.

Only with a schema or a DTD for the XML instance in question can you be certain of whether or not white-space is significant.

There's also considerations like canonicalization and normalization, which also don't apply to JSON.

When generating XML from a data structure, you can already know where the data structure would ignore white-space. So it would be possible to generate "beautiful" XML in that context, but it has to be done as part of the generation. The beautification cannot be done safely by some tool after-the-fact, at least not without much further context (schemas, DTDs, etc.), or without assumptions by the user of such an API.


The xml.MarshalIndent() only apply to a GO structure, not XML strings. 

Yes. See my points above.

Eric.

Justin Wilson

unread,
Nov 7, 2016, 4:57:28 PM11/7/16
to golang-nuts
I needed this a while back, for both JSON and XML.

JSON was the easy part =)

Here's my repo for an XML prettifier https://github.com/juztin/xmlfmt
  (ignore the install directions in my readme, the domain is wrong)

You can install it via:
go get install https://github.com/juztin/xmlfmt
Then just pass it whatever XML:
curl -s http://www.w3schools.com/xml/note.xml | xmlfmt
echo "<xml><test>blah</test></xml>" | xmlfmt

Or... Here's the actual code:
package main

import (
   
"bufio"
   
"encoding/xml"
   
"fmt"
   
"os"
)

type node
struct {
   
Attr     []xml.Attr
   
XMLName  xml.Name
   
Children []node `xml:",any"`
   
Text     string `xml:",chardata"`
}

/* Usage:
 * % echo "<xml><test>blah</test></xml>" | go run xmlfmt.go
 */

func main
() {
    reader
:= bufio.NewReader(os.Stdin)
    decoder
:= xml.NewDecoder(reader)

    n
:= node{}
   
if err := decoder.Decode(&n); err != nil {
        fmt
.Println(err)
        os
.Exit(1)
   
}

    b
, err := xml.MarshalIndent(n, "", "  ")
   
if err != nil {
        fmt
.Println(err)
        os
.Exit(1)
   
}
    fmt
.Println(string(b))
}

Hope that helps =)




On Friday, November 4, 2016 at 3:32:24 PM UTC-6, Tong Sun wrote:
Reply all
Reply to author
Forward
0 new messages