convert xml to jsonx using xslt - xslt

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>

Related

xml to xml transformation - trying to merge two XSLs

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.

XSLT - extract all text but last subsection

Looking to parse out a namespace from a full class name in xml.
Data example:
<results>
<test-case name="Co.Module.Class.X">
</results>
End result (going to csv format):
,Co.Module.Class
Stylesheet:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="text" indent="yes" encoding="ISO-8859-1"/>
<xsl:param name="delim" select="','" />
<xsl:param name="quote" select="'"'" />
<xsl:param name="break" select="'
'" />
<xsl:template match="/">
FullTestName, Namespace
<xsl:apply-templates select="//test-case" />
</xsl:template>
<xsl:template match="test-case">
<xsl:apply-templates />
<xsl:value-of select="#name" />
<xsl:value-of select="$delim" />
<xsl:value-of select="function to go here for nameWithJustNamespace" />
<xsl:value-of select="$break" />
</xsl:template>
I understand the process would need a last index of "." to be called once, yet I'm not finding XSLT to have that function. How to best accomplish this?
To do this in pure XSLT 1.0, you need to call a named recursive template, e.g.:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/results">
<xsl:call-template name="remove-last-token">
<xsl:with-param name="text" select="test-case/#name"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="remove-last-token">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'.'"/>
<xsl:value-of select="substring-before($text, $delimiter)"/>
<xsl:if test="contains(substring-after($text, $delimiter), $delimiter)">
<xsl:value-of select="$delimiter"/>
<xsl:call-template name="remove-last-token">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
This pure XSLT 1.0 transformation (shorter, no conditional XSLT operations, single template):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="test-case[contains(#name, '.')]">
<xsl:param name="pDotIndex" select="0"/>
<xsl:variable name="vNextToken"
select="substring-before(substring(#name, $pDotIndex+1), '.')"/>
<xsl:value-of select="concat(substring('.', 2 - ($pDotIndex > 0)),$vNextToken)"/>
<xsl:variable name="vNewDotIndex" select="$pDotIndex+string-length($vNextToken)+1"/>
<xsl:apply-templates
select="self::node()[contains(substring(#name,$vNewDotIndex+1), '.')]">
<xsl:with-param name="pDotIndex" select="$vNewDotIndex"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<results>
<test-case name="Co.Module.Class.X"/>
</results>
produces the wanted, correct result:
Co.Module.Class
Part 2
With a slight modification the following transformation produces the complete CSV:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="test-case[contains(#name, '.')]">
<xsl:param name="pDotIndex" select="0"/>
<xsl:variable name="vNextToken"
select="substring-before(substring(#name, $pDotIndex+1), '.')"/>
<xsl:value-of select="concat(substring(',', 2 - (position() > 1)),
substring('.', 2 - ($pDotIndex > 0)), $vNextToken)"/>
<xsl:variable name="vNewDotIndex" select="$pDotIndex+string-length($vNextToken)+1"/>
<xsl:apply-templates
select="self::node()[contains(substring(#name,$vNewDotIndex+1), '.')]">
<xsl:with-param name="pDotIndex" select="$vNewDotIndex"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
When applied on this XML document:
<results>
<test-case name="Co.Module.Class.X"/>
<test-case name="Co2.Module2.Class2.Y"/>
<test-case name="Co3.Module3.Class3.Z"/>
</results>
the wanted, correct (CSV) result is produced:
Co.Module.Class,Co2.Module2.Class2,Co3.Module3.Class3

Convert entity to keyboard character using XSLT

I am in need to convert   entity to normal space (keyboard space) using XSLT 1.0. But I am getting the entity   instead of space.
Sample XML:
<chapter xmlns="http://www.w3.org/1998/Math/MathML">
<math display='block'>
<mrow>
<mtext>x y + y x</mtext>
</mrow>
</math>
</chapter>
XSLT 1.0 tried:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1998/Math/MathML">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mtext">
<xsl:for-each select="contains(.,' ')">
<xsl:text disable-output-escaping="yes"> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Required output:
<?xml version='1.0' encoding='UTF-8' ?>
<chapter xmlns="http://www.w3.org/1998/Math/MathML"><math display="block"><mrow><mtext>x y + y x</mtext></mrow></math></chapter>
Output:
<?xml version='1.0' encoding='UTF-8' ?>
<chapter xmlns="http://www.w3.org/1998/Math/MathML"><math display="block"><mrow><mtext>x y + y x</mtext></mrow></math></chapter>
Much simpler:
<xsl:template match="text()">
<xsl:value-of select="translate(., ' ', ' ')"/>
</xsl:template>
Here is a complete transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="translate(., ' ', ' ')"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<chapter xmlns="http://www.w3.org/1998/Math/MathML">
<math display='block'>
<mrow>
<mtext>x y + y x</mtext>
</mrow>
</math>
</chapter>
the wanted, correct result is produced:
<chapter xmlns="http://www.w3.org/1998/Math/MathML">
<math display="block">
<mrow>
<mtext>x y + y x</mtext>
</mrow>
</math>
</chapter>
Remember:
The best way to replace a single character with another character (or to delete it) is to use the standard XPath function translate().
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1998/Math/MathML">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mtext">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="from"> </xsl:with-param>
<xsl:with-param name="to" select="' '"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="from"/>
<xsl:param name="to"/>
<xsl:choose>
<xsl:when test="contains($text, $from)">
<xsl:variable name="before" select="substring-before($text, $from)"/>
<xsl:variable name="after" select="substring-after($text, $from)"/>
<xsl:variable name="prefix" select="concat($before, $to)"/>
<xsl:copy-of select="$before"/>
<xsl:value-of select="$to" disable-output-escaping="yes"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="$after"/>
<xsl:with-param name="from" select="$from"/>
<xsl:with-param name="to" select="$to"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Need General xslt for XML to JSONX [duplicate]

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>

Trying to create xml from the attribute values

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>