Search code examples
xsltxslt-1.0xslt-2.0jsonx

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?


Solution

  • 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.