This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
convert xml to jsonx using xslt
Can anyone help me out in getting the below with an array..I have to generate the generalised xsl..
Input XML:
<accounts>
<displayOrdinal>0</displayOrdinal>
<name>String</name>
<account>
<accountNumber>String</accountNumber>
<name>String</name>
<balance>
<balanceAmount>0.0</balanceAmount>
</balance>
<balance>
<balanceAmount>0.0</balanceAmount>
</balance>
<properties>
<displayOrdinal>0</displayOrdinal>
</properties>
<properties>
<displayOrdinal>0</displayOrdinal>
</properties>
<usage>
<type>String</type>
</usage>
<usage>
<type>String</type>
</usage>
</account>
<account>
<accountNumber>String</accountNumber>
<name>String</name>
<balance>
<balanceAmount>0.0</balanceAmount>
</balance>
<balance>
<balanceAmount>0.0</balanceAmount>
</balance>
<properties>
<displayOrdinal>0</displayOrdinal>
</properties>
<properties>
<displayOrdinal>0</displayOrdinal>
</properties>
<usage>
<type>String</type>
</usage>
<usage>
<type>String</type>
</usage>
</account>
</accounts>
Output:
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="accounts">
<json:string name="displayOrdinal">0</json:string>
<json:string name="name">String</json:string>
<json:array name="account">
<json:object>
<json:string name="accountNumber">String</json:string>
<json:string name="name">String</json:string>
<json:array name="balance">
<json:object>
<json:string name="balanceAmount">0.0</json:string>
</json:object>
<json:object>
<json:string name="balanceAmount">0.0</json:string>
</json:object>
</json:array>
<json:array name="properties">
<json:object>
<json:string name="displayOrdinal">0</json:string>
</json:object>
<json:object>
<json:string name="displayOrdinal">0</json:string>
</json:object>
</json:array>
<json:array name="usage">
<json:object>
<json:string name="type">String</json:string>
</json:object>
<json:object name="usage">
<json:string name="type">String</json:string>
</json:object>
</json:array>
</json:object>
<json:object>
<json:string name="accountNumber">String</json:string>
<json:string name="name">String</json:string>
<json:object name="balance">
<json:string name="balanceAmount">0.0</json:string>
</json:object>
<json:array name="balance">
<json:object>
<json:string name="balanceAmount">0.0</json:string>
</json:object>
<json:object>
<json:string name="displayOrdinal">0</json:string>
</json:object>
<json:object>
<json:string name="displayOrdinal">0</json:string>
</json:object>
</json:array>
<json:array name="usage">
<json:object>
<json:string name="type">String</json:string>
</json:object>
<json:object>
<json:string name="type">String</json:string>
</json:object>
</json:array>
</json:object>
</json:array>
</json:object>
</json:object>
I am using the below xslt and output but not as expected above.Could any one please help me.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Array -->
<xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
<json:object name="{name()}">
<json:array name="{name(*[1])}">
<xsl:apply-templates/>
</json:array>
</json:object>
</xsl:template>
<!-- Array member -->
<xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
<json:object>
<xsl:apply-templates/>
</json:object>
</xsl:template>
<!-- Object -->
<xsl:template match="*">
<json:object name="{name()}">
<xsl:apply-templates/>
</json:object>
</xsl:template>
<!-- String -->
<xsl:template match="*[not(*)]">
<json:string name="{name()}">
<xsl:value-of select="."/>
</json:string>
</xsl:template>
</xsl:stylesheet>
May be you meant to say that Groups should be an array and Group should be an object instead of the other way around?
Try this...
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"
exclude-result-prefixes="xsl xs">
<xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<json:object>
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- Array -->
<xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
<json:array name="{name()}">
<xsl:apply-templates />
</json:array>
</xsl:template>
<!-- Object -->
<xsl:template match="*">
<json:object name="{name()}">
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- String -->
<xsl:template match="*[not(*)]">
<json:string name="{name()}">
<xsl:value-of select="." />
</json:string>
</xsl:template>
</xsl:stylesheet>
...the output is this...
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="Login">
<json:array name="Groups">
<json:object name="Group">
<json:string name="Name">john</json:string>
<json:string name="Password"/>
</json:object>
<json:object name="Group">
<json:string name="Name">john</json:string>
<json:string name="Password"/>
</json:object>
</json:array>
</json:object>
</json:object>
Update
In response to the OP's updated requirements, here is a new solution.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<!-- Array -->
<xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
<json:object name="{name()}">
<json:array name="{name(*[1])}">
<xsl:apply-templates />
</json:array>
</json:object>
</xsl:template>
<!-- Array member -->
<xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
<json:object>
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- Object -->
<xsl:template match="*">
<json:object name="{name()}">
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- String -->
<xsl:template match="*[not(*)]">
<json:string name="{name()}">
<xsl:value-of select="." />
</json:string>
</xsl:template>
</xsl:stylesheet>
Output is so...
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="Login">
<json:object name="Groups">
<json:array name="Group">
<json:object>
<json:string name="Name">john</json:string>
<json:string name="Password"></json:string>
</json:object>
<json:object>
<json:string name="Name">john</json:string>
<json:string name="Password"></json:string>
</json:object>
</json:array>
</json:object>
</json:object>
</json:object>
Related
i am trying to transform one xml into another using an xsl.
change input XML's 'name' attribute's value from 'Code' to 'id'
change input XML's 'name' attribute's value from 'Name' to 'name'
copy all nodes under json:array in outpur xml under json:object as
shown in the output xml
I am able to achieve what i have needed using two separate XSLs and trying to figure how I can merge those two XSLs, can you please review and assist me
xsl1:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dp="http://www.datapower.com/extensions" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dp date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#name[.='Name']">
<xsl:attribute name="name"><xsl:value-of select="'name'"/></xsl:attribute>
</xsl:template>
<xsl:template match="#name[.='Code']">
<xsl:attribute name="name"><xsl:value-of select="'id'"/></xsl:attribute>
</xsl:template>
<xsl:template match="#name[.='SimpleCarrier']">
<xsl:variable name="carrierType">
<xsl:value-of select="'airlines'"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$carrierType='airlines'">
<xsl:attribute name="name"><xsl:value-of select="'airlines'"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="name"><xsl:value-of select="'SimpleCarrierNotUpdated'"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
xsl2:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dp="http://www.datapower.com/extensions" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dp date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="//json:array"/>
</xsl:template>
</xsl:stylesheet>
input XML:
<json:object xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="Header">
<json:string name="Action">http://webs.abcd.com/CService</json:string>
<json:string name="RelatesTo">urn:uuid:9455ee68-bc4d-4e6a-9174-fb2000c18e24</json:string>
</json:object>
<json:object name="Body">
<json:object name="GetSimpleCLResponse">
<json:object name="GetSimpleCLResult">
<json:array name="SimpleCarrier">
<json:object>
<json:string name="Code">m9</json:string>
<json:string name="Name">1B9FHQK</json:string>
</json:object>
<json:object>
<json:string name="Code">25</json:string>
<json:string name="Name">1TIME</json:string>
</json:object>
</json:array>
</json:object>
</json:object>
</json:object>
</json:object>
Output XML:
<json:object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd">
<json:array name="airlines">
<json:object>
<json:string name="id">m9</json:string>
<json:string name="name">1B9FHQK</json:string>
</json:object>
<json:object>
<json:number name="id">25</json:number>
<json:string name="name">1TIME</json:string>
</json:object>
</json:array>
</json:object>
AFAICT, all you need to do is add:
<xsl:template match="/">
<xsl:apply-templates select="//json:array"/>
</xsl:template>
to the first stylesheet.
I have an XML that goes like this:
<tu>
<prop type="x-idiom-source-ipath">DOMAIN/SUBDOMAIN/FILENAME</prop>
<tuv xml:lang="IT-IT">
<seg>Prova</seg>
</tuv>
<tuv xml:lang="EN-GB">
<seg>Test</seg>
</tuv>
</tu>
I'd like to copy the prop element twice and rename it:
<tu>
<prop type="domain">DOMAIN/SUBDOMAIN/FILENAME</prop>
<prop type="subdomain">DOMAIN/SUBDOMAIN/FILENAME</prop>
<prop type="filename">DOMAIN/SUBDOMAIN/FILENAME</prop>
<tuv xml:lang="IT-IT">
<seg>Prova</seg>
</tuv>
<tuv xml:lang="EN-GB">
<seg>Test</seg>
</tuv>
</tu>
How would I do that? I don't understand how to copy and duplicate the element, I'm not competent enough.
Thank you
Well, you could do simply:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="prop">
<prop type="domain">
<xsl:value-of select="." />
</prop>
<prop type="subdomain">
<xsl:value-of select="." />
</prop>
<prop type="filename">
<xsl:value-of select="." />
</prop>
</xsl:template>
</xsl:stylesheet>
I have the following input xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<results>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i1</KEY>
<id>Apple</id>
</issue>
<issue>
<KEY>i1</KEY>
<id>Orange</id>
</issue>
<issue>
<KEY>i2</KEY>
<id>Mango</id>
</issue>
</case>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i5</KEY>
<id>Apricot</id>
</issue>
<issue>
<KEY>i5</KEY>
<id>Blueberry</id>
</issue>
<issue>
<KEY>i6</KEY>
<id>blackberry</id>
</issue>
</case>
<case>
<KEY>c2</KEY>
<issue>
<KEY>i3</KEY>
<id>Banana</id>
</issue>
<issue>
<KEY>i3</KEY>
<id>Cherry</id>
</issue>
<issue>
<KEY>i4</KEY>
<id>Grapes</id>
</issue>
</case>
</results>
</root>
Now I want to group by <KEY> of <case> first and then by<KEY> of <issue>. The idea is to group all the <issue>'s by their issue key and case key. Finally I want to move all the <id>'s whose issue keys are same under <sourceInstance> node within the <issue>.
My output xml should be as below:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<results>
<case>
<KEY>c1</KEY>
<issue>
<KEY>i1</KEY>
<sources>
<sourceInstance>
<id>Apple</id>
</sourceInstance>
<sourceInstance>
<id>Orange</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i2</KEY>
<sources>
<sourceInstance>
<id>Mango</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i5</KEY>
<sources>
<sourceInstance>
<id>Apricot</id>
</sourceInstance>
<sourceInstance>
<id>Blueberry</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i6</KEY>
<sources>
<sourceInstance>
<id>Apple</id>
</sourceInstance>
<sourceInstance>
<id>Orange</id>
</sourceInstance>
</sources>
</issue>
</case>
<case>
<KEY>c2</KEY>
<issue>
<KEY>i3</KEY>
<sources>
<sourceInstance>
<id>Banana</id>
</sourceInstance>
<sourceInstance>
<id>Cherry</id>
</sourceInstance>
</sources>
</issue>
<issue>
<KEY>i4</KEY>
<sources>
<sourceInstance>
<id>Grapes</id>
</sourceInstance>
</sources>
</issue>
</case>
</results>
</root>
I have tried by using the following XSLT, but couldn't get the desired xml output.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="case" match="case" use="string(KEY)" />
<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
<xsl:template match="results">
<xsl:copy>
<xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
</xsl:copy>
</xsl:template>
<xsl:template match="case" mode="case">
<xsl:choose>
<xsl:when test="KEY">
<case>
<xsl:copy-of select="KEY" />
<xsl:apply-templates select="key('case', KEY)[generate-id() = generate-id(key('issue', concat(KEY, '|', KEY))[1])]" mode="issue" />
</case>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="case " mode="issue">
<xsl:choose>
<xsl:when test="KEY">
<issue>
<xsl:copy-of select="KEY" />
<sources>
<xsl:apply-templates select="key('issue', id)" />
</sources>
</issue>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="case">
<sourceInstance>
<id>
<xsl:value-of select="id" />
</id>
</sourceInstance>
</xsl:template>
</xsl:stylesheet>
It appears that I am unable to frame the correct combination of a key using the <KEY> of <case> and <issue> as the node with the same name (i.e.<KEY> )exists at both the places.
Can somebody tell me what I am missing in my XSLT?
The main problem is the definition of your key of issue
<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" />
You need to be matching issue elements here, and using a concatenation of the KEY for issue and the parent case element
<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />
Then, to get the grouped issue elements for a given case KEY, you would do this...
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="case" match="case" use="string(KEY)" />
<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" />
<xsl:template match="results">
<xsl:copy>
<xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" />
</xsl:copy>
</xsl:template>
<xsl:template match="case" mode="case">
<xsl:choose>
<xsl:when test="KEY">
<case>
<xsl:copy-of select="KEY" />
<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" />
</case>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="issue" mode="issue">
<xsl:choose>
<xsl:when test="KEY">
<issue>
<xsl:copy-of select="KEY" />
<sources>
<xsl:apply-templates select="key('issue', concat(KEY, '|', ../KEY))" />
</sources>
</issue>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="issue">
<sourceInstance>
<id>
<xsl:value-of select="id" />
</id>
</sourceInstance>
</xsl:template>
</xsl:stylesheet>
My input xml would be like this with json namespaces..
<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:object name="Group">
<json:object name="TargetSystem">
<json:string name="Name">john</json:string>
<json:string name="Password"/>
</json:object>
</json:object>
</json:object>
</json:object>
I need the output like this
<Login>
<Group>
<TargetSystem>
<Name>john</Name>
<Password/>
</TargetSystem>
</Group>
</Login>
I have to create this xml using the attribute name value in the input xml using xslt.
I am using the below xslt.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<xsl:apply-templates select="json:object/*"/>
</xsl:template>
<xsl:template match="json:object">
<xsl:element name="{#name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Using this I am getting only john.
I have to use some looping concept..
Could anyone please help me how can I achieve this?
If minimal XSLT is your thing, it is possible to come up with a generic XSLT that would work with any namespace.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="*[#name]">
<xsl:element name="{#name}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
In other words, this will match any element with a #name attribute, and create an element of that name instead. Because the root element has no such attribute, it won't be output, but the default template match will just continue to process its children.
I think you want
<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:object[#name]">
<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>
Can anyone help me out in getting the below with an array..I have to generate the generalised xsl..
Input XML:
<Login>
<Groups>
<Group>
<Name>john</Name>
<Password/>
</Group>
<Group>
<Name>john</Name>
<Password/>
</Group>
</Groups>
</Login>
Output:
<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:object name="Groups">
<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>
</json:object>
More generalized solution. Requires XSLT 2.0
<xsl:stylesheet version="2.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:element name="json:object">
<xsl:if test="$nodeName">
<xsl:attribute name="name" select="$nodeName" />
</xsl:if>
<xsl:choose>
<xsl:when test="(count(*) > 1) and (every $x in */name() satisfies $x=$firstNodeName)">
<xsl:element name="json:array">
<xsl:attribute name="name" select="$firstNodeName" />
<xsl:apply-templates >
<xsl:with-param name="nodeName" select="''" />
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</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>
Applied to the provided sample XML, produces following output:
<?xml version="1.0" encoding="UTF-8"?>
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:object name="Login">
<json:object name="Groups">
<json:array name="Group">
<json:object>
<json:string name="Name">john</json:string>
<json:string name="Password"></json:string>
</json:object>
<json:object>
<json:string name="Name">john</json:string>
<json:string name="Password"></json:string>
</json:object>
</json:array>
</json:object>
</json:object>
</json:object>
The above solution was tested on this site: http://xslttest.appspot.com/
EDIT:
every $x in */name() satisfies $x=$firstNodeName is XPATH 2.0 construction that checks if all the elements in */name() sequence are equal to $firstNodeName. So this whole condition actually means checking if a node has more than one child with the same name - this is a condition for checking if we're dealing with json:array case.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<!-- Array -->
<xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
<json:object name="{name()}">
<json:array name="{name(*[1])}">
<xsl:apply-templates />
</json:array>
</json:object>
</xsl:template>
<!-- Array member -->
<xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
<json:object>
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- Object -->
<xsl:template match="*">
<json:object name="{name()}">
<xsl:apply-templates />
</json:object>
</xsl:template>
<!-- String -->
<xsl:template match="*[not(*)]">
<json:string name="{name()}">
<xsl:value-of select="." />
</json:string>
</xsl:template>
</xsl:stylesheet>
you can try the below generic xslt :
<?xml version="1.0"?>
<xsl:stylesheet xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Array -->
<xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
<json:object name="{name()}">
<json:array name="{name(*[1])}">
<xsl:apply-templates/>
</json:array>
</json:object>
</xsl:template>
<!-- Array member -->
<xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
<json:object>
<xsl:apply-templates/>
</json:object>
</xsl:template>
<!-- Object -->
<xsl:template match="*">
<json:object name="{name()}">
<xsl:apply-templates/>
</json:object>
</xsl:template>
<!-- String -->
<xsl:template match="*[not(*)]">
<json:string name="{name()}">
<xsl:value-of select="."/>
</json:string>
</xsl:template>
</xsl:stylesheet>