1

I have to do the transformation using xsl to generate arrays,objects,strings of json.. I am failing to produce the arrays.. Actually my requirement is I have to transform the XML to JXML and JXML to json.. I have the generalized xslt for jxml to json..Now I need the generalized solution for converting XMLto JXML.. For reference I am producing sample xml's.. IP

<planexml>        
    <def/>
    <xyz>
        <Number>123</Number>
        <name>sen</name>
        <c>
            <type/>
        </c>
        <c>
            <type/>
        </c>
        <e>
            <wsx/>
        </e>
        <e>
            <wsx/>
        </e>
    </xyz>
        <xyz>
        <Number>123</Number>
        <name>sen</name>
        <c>
            <type/>
        </c>
        <c>
            <type/>
        </c>
        <e>
            <wsx/>
        </e>
        <e>
            <wsx/>
        </e>
    </xyz>
<planexml>

Result should be

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <json:object name="planexml">
        <json:string name="def"/>
        <json:array name="xyz">
            <json:object>
                <json:string name="number"/>
                <json:string name="name"/>
                <json:array name="c">
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                </json:array>
                <json:array name="e">
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                </json:array>
            </json:object>
            <json:object>
                <json:string name="number"/>
                <json:string name="name"/>
                <json:array name="c">
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                </json:array>
                <json:array name="e">
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                </json:array>
            </json:object>
        </json:array>
    </json:object>
</json:object>

Need the solution asap.. :(

j0k
  • 22,600
  • 28
  • 79
  • 90
  • 1
    I have a solution for this. Please repost with more clarity, and state as a question. Also, consider leaving out your XSL - I was confused until I realized that is your incomplete solution. – wst Nov 14 '12 at 18:11
  • @wst--Could you please post the solution that you had... I am removing the xsl to avoid confusion – user1823969 Nov 15 '12 at 04:12
  • I am new to this site...Could nayone please tell me how can I reopen this... – user1823969 Nov 15 '12 at 04:17

2 Answers2

1

Your example output excludes the values of strings if they exist. I'm assuming this is incorrect, since you would probably want to keep those values when converting to JSON. If you don't want them, you can modify the string template below.

XML to JXML XSL

<xsl:template match="/" mode="#default">
    <json:object>
        <xsl:apply-templates/>
    </json:object>
</xsl:template>

<xsl:template match="*" mode="#default">
    <xsl:param name="display-name" select="true()" />
    <json:object>
        <xsl:if test="$display-name">
            <xsl:attribute name="name" select="name()" />
        </xsl:if>
        <xsl:apply-templates select="*[not(*)]" mode="string"/>            
        <xsl:for-each select="*[*]">
            <xsl:variable name="name" select="name()"/>
            <xsl:if test="not(preceding-sibling::*[name() eq $name])">
                <xsl:apply-templates select="." mode="array"/>
            </xsl:if>
        </xsl:for-each>
    </json:object>
</xsl:template>

<xsl:template match="*[not(*)]" mode="string">
    <json:string name="{name()}">
        <xsl:value-of select="."/>
    </json:string>
</xsl:template>

<xsl:template match="*" mode="array">
    <xsl:variable name="array-name" select="name()"/>
    <json:array name="{$array-name}">
        <xsl:for-each select=".|following-sibling::*[name() eq $array-name]">
            <xsl:apply-templates mode="#default" select=".">
                <xsl:with-param name="display-name" select="false()"/>
            </xsl:apply-templates>
        </xsl:for-each>
    </json:array>
</xsl:template>    

Output

<?xml version="1.0" encoding="UTF-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <json:object name="planexml">
        <json:string name="def"/>
        <json:array name="xyz">
            <json:object>
                <json:string name="Number">123</json:string>
                <json:string name="name">sen</json:string>
                <json:array name="c">
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                </json:array>
                <json:array name="e">
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                </json:array>
            </json:object>
            <json:object>
                <json:string name="Number">123</json:string>
                <json:string name="name">sen</json:string>
                <json:array name="c">
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                    <json:object>
                        <json:string name="type"/>
                    </json:object>
                </json:array>
                <json:array name="e">
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                    <json:object>
                        <json:string name="wsx"/>
                    </json:object>
                </json:array>
            </json:object>
        </json:array>
    </json:object>
</json:object>
wst
  • 11,681
  • 1
  • 24
  • 39
0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:element name="json:object">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="*[*]">
        <xsl:param name="nodeName" select="name()"/>
        <xsl:variable name="firstNodeName" select="name(*[1])"/>
        <xsl:choose>
            <xsl:when test="count(../*[name(current()) = name()]) &gt;1">
                <xsl:variable name="el" select="name()"/>
                <xsl:if test="not(following-sibling::*[name()=$el])">
                    <json:array name="{name()}">
                        <xsl:for-each select="../*[name()=$el]">
                            <xsl:if test="position()!=1">
                                <json:object>
                                    <xsl:choose>
                                        <xsl:when test="not(child::node())">
                                            <xsl:text>null</xsl:text>
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:apply-templates>
                                                <xsl:with-param name="nodeName" select="''"/>
                                            </xsl:apply-templates>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </json:object>
                            </xsl:if>
                            <xsl:if test="position()=1">
                                <json:object>
                                    <xsl:choose>
                                        <xsl:when test="not(child::node())">
                                            <xsl:text>null</xsl:text>
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:apply-templates>
                                                <xsl:with-param name="nodeName" select="''"/>
                                            </xsl:apply-templates>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </json:object>
                            </xsl:if>
                        </xsl:for-each>
                    </json:array>
                </xsl:if>
            </xsl:when>
            <xsl:otherwise>
                <json:object name="{name()}">
                    <xsl:apply-templates/>
                </json:object>
            </xsl:otherwise>
        </xsl:choose>
        <!--</xsl:element>-->
    </xsl:template>
    <xsl:template match="*[not(*)]">
        <xsl:element name="json:string">
            <xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
            <xsl:value-of select="text()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

This also provides the expected output