0

My input XML would be like this

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <json:object name="Login">
        <json:array name="Group">
            <json:object>
                <json:string name="Name">john</json:string>
                <json:string name="Password"/>
            </json:object>
            <json:object>
                <json:string name="Name">john</json:string>
                <json:string name="Password"/>
            </json:object>
        </json:array> 
    </json:object>
</json:object>
    <alice xmlns="http://some-namespace" xmlns:charlie="http://some-other-namespace">
    <bob>david</bob>
    <charlie:edgar>frank</charlie:edgar>
</alice>
    {
   "alice":{
      "bob":{
         "$":"david",
         "@xmlns":{
            "charlie":"http:\/\/some-other-namespace",
            "$":"http:\/\/some-namespace"
         }
      },
      "charlie:edgar":{
         "$":"frank",
         "@xmlns":{
            "charlie":"http:\/\/some-other-namespace",
            "$":"http:\/\/some-namespace"
         }
      },
      "@xmlns":{
         "charlie":"http:\/\/some-other-namespace",
         "$":"http:\/\/some-namespace"
      }
   }
}

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd">
    <json:object name="alice">
        <json:object name="bob">
            <json:string name="$">david</json:string>
            <json:object name="@xmlns">
                <json:string name="charlie">http://some-other-namespace</json:string>
                <json:string name="$">http://some-namespace</json:string>
            </json:object>
        </json:object>
        <json:object name="charlie:edgar">
            <json:string name="$">frank</json:string>
            <json:object name="@xmlns">
                <json:string name="charlie">http://some-other-namespace</json:string>
                <json:string name="$">http://some-namespace</json:string>
            </json:object>
        </json:object>
        <json:object name="@xmlns">
            <json:string name="charlie">http://some-other-namespace</json:string>
            <json:string name="$">http://some-namespace</json:string>
        </json:object>
    </json:object>
</json:object>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:json="http://www.ibm.com/xmlns/prod/2010/jsonx" xmlns:b="http://www.ibm.com/xmlns/prod/2009/jsonx" exclude-result-prefixes="json #default">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/json:object">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="json:array[@name]">
        <xsl:apply-templates mode="noname">
            <xsl:with-param name="nme" select="name()"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="json:object" mode="noname">
        <xsl:param name="nme"/>
        <xsl:element name="{../@name}" namespace="{namespace-uri()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:array">
        <xsl:element name="{../@name}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:object[@name]">
        <xsl:if test="not(*[namespace-uri()=''])">
            <xsl:element name="{@name}" namespace="{namespace-uri()}">
                <!--                <xsl:copy-of select="namespace::*[name()]"/>
                <xsl:apply-templates select="node()"/>-->
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:if>
        <!--        <xsl:element name="{@name}">
            <xsl:apply-templates/>
        </xsl:element>-->
    </xsl:template>
    <xsl:template match="json:string[@name]">
        <xsl:if test="not(*[namespace-uri()=''])">
            <xsl:element name="{@name}" namespace="{namespace-uri()}">
                <def>
                    <xsl:copy-of select="namespace-uri-for-prefix(json)"/>
                </def>
                <xsl:value-of select="."/>
            </xsl:element>
        </xsl:if>
    </xsl:template>
    <xsl:template match="json:string">
        <xsl:element name="{../@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:number[@name]">
        <xsl:element name="{@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:null[@name]">
        <xsl:element name="{@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:boolean[@name]">
        <xsl:element name="{@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:boolean[@name]">
        <xsl:element name="{@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

I need the output as below:

<Login>
    <Group>
        <Group>
            <Name>john</Name>
            <Password/>
        </Group>
        <Group>
            <Name>jack</Name>
            <Password/>
        </Group>
    </Group>
</Login>

I am using the below xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="http://exslt.org/functions" xmlns:xalan="http://xml.apache.org/xslt" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:regexp="http://exslt.org/regular-expressions">
    <xsl:output method="text" encoding="utf-8"/>
    <xsl:template match="/*[node()]">
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="." mode="detect"/>
        <xsl:text>}</xsl:text>
    </xsl:template>
    <xsl:template match="*" mode="detect">
        <xsl:choose>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
                <xsl:apply-templates select="." mode="obj-content"/>
                <xsl:text>]</xsl:text>
                <xsl:if test="count(following-sibling::*[name() != name(current())]) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current())">
                <xsl:apply-templates select="." mode="obj-content"/>
                <xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
            </xsl:when>
            <xsl:when test="following-sibling::*[1][name() = name(current())]">
                <xsl:text>"</xsl:text>
                <xsl:value-of select="name()"/>
                <xsl:text>" : [</xsl:text>
                <xsl:apply-templates select="." mode="obj-content"/>
                <xsl:text>, </xsl:text>
            </xsl:when>
            <xsl:when test="count(./child::*) > 0 or count(@*) > 0">
                <xsl:text>"</xsl:text>
                <xsl:value-of select="name()"/>" : <xsl:apply-templates select="." mode="obj-content"/>
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="count(./child::*) = 0">
                <xsl:text>"</xsl:text>
                <xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/>
                <xsl:text>"</xsl:text>
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*" mode="obj-content">
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="@*" mode="attr"/>
        <xsl:if test="count(@*) &gt; 0 and (count(child::*) &gt; 0 or text())">, </xsl:if>
        <xsl:apply-templates select="./*" mode="detect"/>
        <xsl:if test="count(child::*) = 0 and text() and not(@*)">
            <xsl:text>"</xsl:text>
            <xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/>
            <xsl:text>"</xsl:text>
        </xsl:if>
        <xsl:if test="count(child::*) = 0 and text() and @*">
            <xsl:text>"text" : "</xsl:text>
            <xsl:value-of select="text()"/>
            <xsl:text>"</xsl:text>
        </xsl:if>
        <xsl:text>}</xsl:text>
        <xsl:if test="position() &lt; last()">, </xsl:if>
    </xsl:template>
    <xsl:template match="@*" mode="attr">
        <xsl:text>"</xsl:text>
        <xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
        <xsl:if test="position() &lt; last()">,</xsl:if>
    </xsl:template>
    <xsl:template match="node/@TEXT | text()" name="removeBreaks">
        <xsl:param name="pText" select="normalize-space(.)"/>
        <xsl:variable name="myVar" select="regexp:replace($pText,'\\','gi','\\')"/>
        <xsl:variable name="myVar2" select="regexp:replace($myVar,'&#x22;','gi','\&#x23;')"/>
        <xsl:variable name="myVar3" select="regexp:replace($myVar2,'&#x2F;','gi','&#x5C;&#x2F;')"/>
        <xsl:variable name="myVar4" select="regexp:replace($myVar3,'\t','gi','\t')"/>
        <xsl:variable name="myVar5" select="regexp:replace($myVar4,'\n','gi','\n')"/>
        <xsl:variable name="myVar6" select="regexp:replace($myVar5,'\r','gi','\r')"/>
        <xsl:choose>
            <xsl:when test="not(contains($myVar6, '&#xA;'))">
                <xsl:copy-of select="$myVar6"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(substring-before($myVar6, '&#xD;&#xA;'), ' ')"/>
                <xsl:call-template name="removeBreaks">
                    <xsl:with-param name="pText" select="substring-after($myVar6, '&#xD;&#xA;')"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Here I am using the name as "object" in the template json:object but I need the arrayname,arrayname...so on.Could anyone please help me to get this output?

https://datatracker.ietf.org/doc/html/draft-rsalz-jsonx-00#page-4 http://controlfreak.net/xml-to-json-in-xslt-a-toolkit/ extracting information from a JSON file using XSLT version 1.0 http://badgerfish.ning.com/

3
  • Square brackets [ and ] are not valid in element names in XML. Are you sure this is what you require? Commented Oct 15, 2012 at 8:39
  • Also, your input XML contains json:object elements, which your current XSLT converts to just object elements, but these aren't actually shown in your output XML. Do you want your numbering on the group or object then? Thanks! Commented Oct 15, 2012 at 8:43
  • The numbering is not there also fine but I need the arrayname and the object that we are using in the array names to be same.. <Login> <Group><!-- Nameshould be same--> <Group><!-- Nameshould be same--> <Name>john</Name> <Password/> </Group> <Group> <Name>john</Name> <Password/> </Group> </Group> </Login> Commented Oct 15, 2012 at 8:54

1 Answer 1

1

If you are ok with this :-

<?xml version="1.0" encoding="utf-8"?>
<Login>
    <Group>
        <Group>
            <Name>john</Name>
            <Password/>
        </Group>
        <Group>
            <Name>john</Name>
            <Password/>
        </Group>
    </Group>
</Login>

Then the following works :-

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" exclude-result-prefixes="json">
    <xsl:template match="/json:object">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="json:array[@name]">
        <xsl:element name="{@name}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:object">
        <xsl:element name="{../@name}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="json:string[@name]">
        <xsl:element name="{@name}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

5 Comments

I want to specify that name in general way like if the array name is user I have to use the same name for the json:object element name aslo
Updated to pick the name from parent.
@Himanshu There is a template match="json:object[@name]" missing, which must generate elements for object input with specified names. See for example Login element in wish output.
Its working thank you... I need one general xslt that converts XML to JSONX formate "stackoverflow.com/questions/12892266/…" Could you please look into the below link and help me out to achieve..
@Himanshu, Could you please look into this link "stackoverflow.com/questions/12892266/…" and help me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.