1

i have a front end page that send a request to an data service deployed to wso2 console for doing an update in a table. The problem is that i need to convert the json array from the front end to an xml format for build the payload factory for the request. The json is :

{"cdcList":
["UpdateCdc":
    {
 "idCdc":1,
     "order":1,
     "cdcName":"test 1",
    },
 "UpdateCdc":
    {
     "idCdc":2,
 "order":2,
     "cdcName":"test 2",
     "idParent":1
    },
  "UpdateCdc":
    {
     "idCdc":3,
     "order":1,
     "cdcName":"test 3",
     "idParent":1
     }
]

}

and the desired result in xml that i would like that it will be is :

<cdcList>
          <UpdateCdc>
        <idCdc>1</idCdc>
        <order>1</order>
            <cdcName>test 1</cdcName>
          </UpdateCdc>
          <UpdateCdc>
            <idCdc>2</idCdc>
            <order>2</order>
            <cdcName>test 2</cdcName>
            <idParent>1</idParent>
          </UpdateCdc>
          <UpdateCdc>
            <idCdc>3</idCdc>
            <order>3</order>
            <cdcName>test 3</cdcName>
            <idParent>1</idParent>
          </UpdateCdc>
</cdcList>

Thank you.

3
  • XSLT is for XML transforms, not json. What programming language, as there are plenty of libraries to convert json to xml Commented Jun 25, 2018 at 14:22
  • 1
    XSLT 3.0 has a "json-to-xml" function. See stackoverflow.com/questions/47590058/… Commented Jun 25, 2018 at 14:32
  • I don't think the input you have shown is even JSON, jsonlint.com says "Error: Parse error on line 2" , "Expecting 'EOF', '}', ',', ']', got ':'" for the colon in ...cList": ["UpdateCdc": { after the UpdateCdc. Commented Jun 25, 2018 at 16:57

2 Answers 2

2

To do client-side processing in XSLT with support for JSON parsing you will need an XSLT 3.0 processor, which in practice means Saxon-JS. (Disclaimer: that's my company's product.)

Unfortunately the input you supplied isn't valid JSON, but let's assume it is actually like this:

[
    {
        "idCdc": 1,
        "order": 1,
        "cdcName": "test 1"
    },
    {
        "idCdc": 2,
        "order": 2,
        "cdcName": "test 2",
        "idParent": 1
    },
    {
        "idCdc": 3,
        "order": 1,
        "cdcName": "test 3",
        "idParent": 1
    }
]

Then you can convert it to your desired XML format using the following XSLT 3.0 code:

<xsl:variable name="json-array" select="json-doc('input.json')"/>
<cdcList>
  <xsl:for-each select="$json-array?*">
    <updateCdc>
      <xsl:for-each select="map:keys(.)">
         <xsl:element name="{.}">
           <xsl:value-of select="map:get(.)"/>
         </xsl:element>
      </xsl:for-each>
    </updateCdc>
  </xsl:for-each>
</cdcList>
Sign up to request clarification or add additional context in comments.

Comments

2

While Michael Kay's answer gives you XML (see it online at https://xsltfiddle.liberty-development.net/bFDb2Cf/) I think it has one shortcoming, the order of the keys of an XPath 3.1 map is not defined so with map:keys you might get any order for the child elements (e.g. in the linked example it is idParent, idCdc, cdcName, order) while you probably want to define the order for the child elements based on the order in the JSON. That can be achieved using the json-to-xml function already mentioned by Tim in a comment:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="xs math map array fn"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:param name="json-input" as="xs:string">[
    {
        "idCdc": 1,
        "order": 1,
        "cdcName": "test 1"
    },
    {
        "idCdc": 2,
        "order": 2,
        "cdcName": "test 2",
        "idParent": 1
    },
    {
        "idCdc": 3,
        "order": 1,
        "cdcName": "test 3",
        "idParent": 1
    }
]</xsl:param>

  <xsl:variable name="json-array" select="parse-json($json-input)"/>

  <xsl:variable name="json-xml" select="json-to-xml($json-input)"/>

  <xsl:template match="/">
    <cdcList>
        <xsl:apply-templates select="$json-xml/*"/>
    </cdcList>
  </xsl:template>

  <xsl:template match="fn:map">
      <updateCdc>
          <xsl:apply-templates/>
      </updateCdc>
  </xsl:template>

  <xsl:template match="fn:map/fn:*">
      <xsl:element name="{@key}">
          <xsl:value-of select="."/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFDb2Cf/2 has that example, in https://xsltfiddle.liberty-development.net/bFDb2Cf/1 I also output the result of the json-to-xml call so that you can see how the JSON input is mapped to XML:

<array xmlns="http://www.w3.org/2005/xpath-functions">
   <map>
      <number key="idCdc">1</number>
      <number key="order">1</number>
      <string key="cdcName">test 1</string>
   </map>
   <map>
      <number key="idCdc">2</number>
      <number key="order">2</number>
      <string key="cdcName">test 2</string>
      <number key="idParent">1</number>
   </map>
   <map>
      <number key="idCdc">3</number>
      <number key="order">1</number>
      <string key="cdcName">test 3</string>
      <number key="idParent">1</number>
   </map>
</array>

Comments

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.