How to convert a xml content to map[string]interface?

5,127 views
Skip to first unread message

mail...@gmail.com

unread,
Nov 5, 2015, 11:13:07 AM11/5/15
to golang-nuts
I noticed golang can convert a json string to a map[string]interface by json.Unmarshal, but I cannot find the similar method in encoding/xml .
Anyone knows how to convert it?   BTW, I do not want to use any third library since the project requirement.

Thanks in advance.

James Bardin

unread,
Nov 5, 2015, 11:18:23 AM11/5/15
to golang-nuts, mail...@gmail.com


On Thursday, November 5, 2015 at 11:13:07 AM UTC-5, mail...@gmail.com wrote:
I noticed golang can convert a json string to a map[string]interface by json.Unmarshal, but I cannot find the similar method in encoding/xml .
Anyone knows how to convert it?   BTW, I do not want to use any third library since the project requirement.


You have to decode it manually, because there is no standard way to map XML to a key-value relationship.

What do you want to translate to the map keys and values?

Konstantin Khomoutov

unread,
Nov 5, 2015, 12:22:29 PM11/5/15
to mail...@gmail.com, golang-nuts
To elaborate on what James told you, the general problem with XML is
that this format has no semantic encoded in the markup used:

* In any XML element, you might have simple values encoded
either with attributes on this element or with child elements,
and you can have an attribute and a child element with the same
names.

<foo bar="baz">
<bar>baz</bar>
</foo>

How do you map this to a map?

* XML elements on the save level (that is, children elements of any XML
element) might perfectly have the same names:

<foo>
<bar>1</bar>
<bar>2</bar>
...
<bar>42</bar>
</foo>

As you can see, it's impossible to automatically map the contents of
<foo>...</foo> to a map.

* Ordering of XML elements on the same level (see above) may or may not
matter.

Again, if you take the example above, the semantics of processing
XML documents of this type might dictate that all those <bar> elements
for an ordered list or they form an unordered set.

* If the bytes between the two tags of an element do not contain any
other XML elements, there's still no way to infer the "type" of this
value, that is, given <bar>42</bar>, you can't tell if 42 must be
a string or an integer or a float, so basically there's no sense
to unmarshal an XML document to map[string]interface{} because you
can only sensibly unmarshal to map[string]string. JSON at least
differentiates between objects, arrays, strings and numbers.

* An often forgotten fact (especially when dealing with XML produced
by in-house tools) is that XML uses namespaces for everything, that
is, each element and attribute of any XML document you're working with
has a namespace which may be specified either explicitly or via a
prefix or implied from the context.

It also worth citing the encoding/xml manual:

| Mapping between XML elements and data structures is inherently
| flawed: an XML element is an order-dependent collection of anonymous
| values, while a data structure is an order-independent collection of
| named values. See package json for a textual representation more
| suitable to data structures.

Konstantin Khomoutov

unread,
Nov 5, 2015, 12:56:01 PM11/5/15
to Konstantin Khomoutov, mail...@gmail.com, golang-nuts
On Thu, 5 Nov 2015 20:21:54 +0300
Konstantin Khomoutov <flat...@users.sourceforge.net> wrote:

> > I noticed golang can convert a json string to a map[string]interface
> > by json.Unmarshal, but I cannot find the similar method in
> > encoding/xml . Anyone knows how to convert it? BTW, I do not want
> > to use any third library since the project requirement.
>
> To elaborate on what James told you, the general problem with XML is
> that this format has no semantic encoded in the markup used:
[...]

Oh, and one more fun point I forgot to present in my response.

This

<foo>42<bar/>42</foo>

is a perfectly valid XML document, and it's perfectly parsable [1].
Here, the contents of the <foo> element contains a character data block
followed by an (empty) element followed by another character data block.

Coming up with a generic way of mapping this stuff onto a
map[string]whatever would be an excercise of inventing arbitrary
conversion policies which would obviously have no place in the standard
library.

1. http://play.golang.org/p/Bq9g_YznSP

mail...@gmail.com

unread,
Nov 5, 2015, 8:39:23 PM11/5/15
to golang-nuts, flat...@users.sourceforge.net

Thank you very much, you make me more clearly to understand why encoding/xml has no the feature.  
Anyway, thanks again,  your reply so fast.


在 2015年11月6日星期五 UTC+8上午1:56:01,Konstantin Khomoutov写道:

C Banning

unread,
Nov 6, 2015, 8:31:55 AM11/6/15
to golang-nuts, mail...@gmail.com
What's wrong with using https://github.com/clbanning/mxj?

mail...@gmail.com

unread,
Nov 7, 2015, 8:04:13 PM11/7/15
to golang-nuts, mail...@gmail.com
Thanks, It is what I want. Let me see more detail in this project.

在 2015年11月6日星期五 UTC+8下午9:31:55,C Banning写道:

grub...@gmail.com

unread,
Jan 22, 2018, 12:19:19 PM1/22/18
to golang-nuts
Your lib works great and proves that actually there is a way to decode an XML stream into a generic map avoiding the need to declare the data model.
(for the ones who know Perl is kinda XML::Simple...)

Thanks!
Reply all
Reply to author
Forward
0 new messages