Convert XML to JSON using XSLT

How about that for acronym soup?  In the spirit of doing smaller posts but more often, here is a handy little XSLT. 

Assuming you have the following XML,

 

<Customers>
    <Customer Id="99">
        <Name>Bob</Name>
        <Age>39</Age>
        <Address>
            <Street>10 Idle Lane</Street>
            <City>Yucksville</City>
            <PostalCode>xxxyyy</PostalCode>
        </Address>
    </Customer>
    <Customer Id="101">
        <Name>Bill</Name>
        <Age>39</Age>
        <Address>
            <Street>10 Idle Lane</Street>
            <City>Yucksville</City>
            <PostalCode>xxxyyy</PostalCode>
        </Address>
    </Customer>

</Customers>

 

Using this XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/">{
        <xsl:apply-templates select="*"/>}
    </xsl:template>
    
    <!-- Object or Element Property-->
    <xsl:template match="*">
        "<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/>
    </xsl:template>

    <!-- Array Element -->
    <xsl:template match="*" mode="ArrayElement">
        <xsl:call-template name="Properties"/>
    </xsl:template>

    <!-- Object Properties -->
    <xsl:template name="Properties">
        <xsl:variable name="childName" select="name(*[1])"/>
        <xsl:choose>
            <xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</xsl:when>
            <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
            <xsl:otherwise>{
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates select="*"/>
    }</xsl:otherwise>
        </xsl:choose>
        <xsl:if test="following-sibling::*">,</xsl:if>
    </xsl:template>

    <!-- Attribute Property -->
    <xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
    </xsl:template>
</xsl:stylesheet>

You can generate this JSON

{
    "Customers" : {
        "Customer" : [
            {
                "Id" : "99",
                "Name" : "Bob",
                "Age" : "39",
                "Address" : {
                    "Street" : "10 Idle Lane",
                    "City" : "Yucksville",
                    "PostalCode" : "xxxyyy" 
                } 
            },
            {
                "Id" : "101",
                "Name" : "Bill",
                "Age" : "39",
                "Address" : {
                    "Street" : "10 Idle Lane",
                    "City" : "Yucksville",
                    "PostalCode" : "xxxyyy" 
                } 
            }
        ] 
    }
} 

It would be really interesting to try and use this Javascript XSLT processor to do the transform directly in the browser.  That way any web api that generates XML could be flipped into a JSON representation for direct access in Javascript.

No Comments

Add a Comment

comments powered by Disqus