Reputation: 53
I have an xml, that looks like this
<person>
<name>
<name-first>foo</name-first>
<name-last>bar</name-last>
</name>
<age>20</age>
<city>nowhere</city>
</person>
I want to convert this into
person:
{
name: {
name-first:'foo',
name-last:'bar'
},
age:'20',
city:'nowhere'
}
Thanks in advance.
Upvotes: 2
Views: 113
Reputation: 243579
Here is a simple transformation -- for a start:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pIndents" select="' '"/>
<xsl:template match="*[*]">
<xsl:param name="pcurrentIndents" select="''"/>
<xsl:value-of select="concat($pcurrentIndents, name(), ':')"/>
<xsl:value-of select="concat('
',$pcurrentIndents, '{')"/>
<xsl:apply-templates>
<xsl:with-param name="pcurrentIndents" select=
"concat($pcurrentIndents, $pIndents)"/>
</xsl:apply-templates>
<xsl:value-of select="concat('
',$pcurrentIndents, '}')"/>
</xsl:template>
<xsl:template match="*[not(*)]">
<xsl:param name="pcurrentIndents" select="''"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="concat($pcurrentIndents, name(), ':')"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<person>
<name>
<name-first>foo</name-first>
<name-last>bar</name-last>
</name>
<age>20</age>
<city>nowhere</city>
</person>
the wanted, correct result is produced:
person:
{ name:
{
name-first:foo
name-last:bar
}
age:20
city:nowhere
}
Explanation:
There are two templates that match elements.
The template matching *[*]
matches elements that have elements as children. It produces the name of the currently matched element using the name()
function, then the :
character, then a NL charactr, the current indentation (number of spaces) and finally the {
character. Then templates are applied to the children-nodes of the currently matched element with the $pcurrentIndents
parameter passing the current indentation increased with a predifined increment of space characters (as specified in the global parameter $pIndents
Finally, on a new line and using the current indentation, the closing curly brace is putput.
The template that matches *[not(*)]
(elements that dont have any element as a child) is similar, but simpler. It Outputs the name of the matched element at the current indentation and the :
character. Applying templates here invokes th XSLT built-in templates for non-element nodes -- in this case the built-in template matching a text node is selected and it simply copies the text node to the output.
Upvotes: 1
Reputation: 66781
There are a number of general-purpose XSLT solutions available for converting XML into JSON output.
For instance:
I ran your XML through xml2json-xslt's xml2json.xslt
and generated the following JSON output:
{
"person":
{
"name":
{
"name-first":"foo",
"name-last":"bar"
},
"age":20,
"city":"nowhere"
}
}
Upvotes: 1
Reputation: 274828
Here is an example xsl template which should give you some idea of how to convert your xml to the required output:
<xsl:template match="person">
person:
{
name: {
name-first:<xsl:value-of select="name/name-first"/>,
name-last:<xsl:value-of select="name/name-last"/>
},
age:<xsl:value-of select="age"/>,
city:<xsl:value-of select="city"/>
}
</xsl:template>
Upvotes: 1
Reputation: 35477
What you want is an XML to JSON converter.
Try this one: http://www.thomasfrank.se/xml_to_json.html
Upvotes: 3