0

I am using Java 1.8, Saxon-HE version 9.9.1-4 version and xslt3.0 to tranform the JSON to XML.

Input JSON

{
    "analystId": "Test",
    "jobId": "",
    "profileData": {
        "allAuthorCoverage": false,
        "assetClasses": [
            {
                "code": "Test1"
            }
        ]
        
    }   
}

XSLT3.0

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" /> 
  <xsl:strip-space elements="*"/>
  <xsl:param name="jsonText"/>

  <xsl:template match="@*|node()"> 
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template> 

  <xsl:template name="init">
    <xsl:apply-templates select="json-to-xml($jsonText)"/> 
  </xsl:template>
  
 <xsl:template match="*[@key]" >
  <xsl:element name="{@key}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

Output XML Generated

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <analystId xmlns="">Test</analystId>
   <jobId xmlns=""/>
   <profileData xmlns="">
      <allAuthorCoverage>false</allAuthorCoverage>
      <assetClasses>
         <map xmlns="http://www.w3.org/2005/xpath-functions">
            <code xmlns="">Test1</code>
         </map>
      </assetClasses>
   </profileData>
</map>

Output XML Expected

<?xml version="1.0" encoding="UTF-8"?>
<analystId>Test</analystId>
<jobId />
<profileData>
    <allAuthorCoverage>false</allAuthorCoverage>
    <assetClasses>
        <code>Test1</code>
    </assetClasses>
</profileData>

We can still see <map> element and xmlns attribute in the generated output and my requirement is to remove the same.

How can I remove the Map element from the generated output and xmlns attribute as well?

Also in case I expand my JSON structure with new attributes these map element and xmlns attribute should not be added back again.

7
  • You will need to edit your question and show us the XML you want to output. Commented Aug 23, 2019 at 14:12
  • For a start, if you don't want to copy nodes from the input I would simply remove the xsl:template match="@* | node()" from the code that you have shown. Commented Aug 23, 2019 at 14:25
  • [~Martin] Apologies for not adding the expected output. I have added the expected output for the reference Commented Aug 23, 2019 at 15:13
  • Then I think my answer covers that, you simply have put a template with the identity transformation in your code you should rather omit. Commented Aug 23, 2019 at 15:16
  • 1
    @JineshParikh Thank you for sharing this topic, I'm working on a similar code, could you please share with me a java code snippet, on how are you passing the jsonText parameter to the XSL stylesheet ? or any code sample that will help on understanding the conversion flow. thank you. Commented Jun 28, 2021 at 3:10

1 Answer 1

1

If you don't use the identity template you have used and instead omit it only your template to transform elements with a key attribute into elements of the name of the key value and any text nodes will create output:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all">

    <xsl:param name="jsonText" as="xs:string"><![CDATA[{
    "analystId": "Test",
    "jobId": "",
    "profileData": {
        "allAuthorCoverage": false,
        "assetClasses": [
            {
                "code": "Test1"
            }
        ]

    }   
}]]></xsl:param>

    <xsl:output indent="yes" /> 
    <xsl:strip-space elements="*"/>

    <xsl:template name="xsl:initial-template">
        <xsl:apply-templates select="json-to-xml($jsonText)"/> 
    </xsl:template>

    <xsl:template match="*[@key]" >
        <xsl:element name="{@key}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for the answer. It worked . I have one more simple question. If I take the json-to-xml($jsonText) in a variable in xslt. How can I access the individual elements from that variable which has the whole XML.
You are working with XSLT 3 where the selection language to access nodes in general or of course also elements in an XML document (it does not matter whether it is created from JSON) is XPath 3 so you select elements with any XPath 3 expression you need. The format of the XML is described in w3.org/TR/xslt-30/#json-to-xml-mapping, for your sample JSON you can see it by outputting <xsl:sequence select="json-to-xml($jsonText)"/>.
The elements are in the namespace http://www.w3.org/2005/xpath-functions so declare with e.g. xmlns:fn="http://www.w3.org/2005/xpath-functions" and select e.g. //fn:map[@key = 'profileData'].
Thanks for Help @Martin honnen I have few other questions but let me try to resolve it and if not I will raise it over here

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.