Noman Khan
Noman Khan

Reputation: 27

Single object not generating array in wso2

I want to transfrom the xml to json while an element "Coll" in the incoming xml will be an array if single object received. Result.Coll needs to be an array object rest will be same.

<Result xmlns="http://ws.apache.org/ns/synapse">
  <ban:DOB xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">22101991</ban:DOB>
  <ban:TDNPFlag xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">N</ban:TDNPFlag>
  <ban:DNPExpryDt xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
  <ban:NibbsBVN xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
  <ban:Fac xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
  <ban:Coll xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">
    <ban:AcctNum>10205781559</ban:AcctNum>
    <ban:Stat>DISC</ban:Stat>
    <ban:ChqbkFlag/>
    <ban:CardFlag/>
  </ban:Coll>
</Result>

Result for above

 {"Result":{"CustNum":"00000002010784868","CustTyp":"01","RelnshpMgr":"0","Title":"1","Name":"Mr Tebogo Sekalaba","Addr1":"Botswana","Addr2":"","Addr3":"","Addr4":"","PstCode":"","HomePhnNum":"","FaxNum":"","CountryOfRes":"BW","BussPhnNum":"","MobileNum":"71961292","Natlty":"BW","NumOfChqbk":"00","NumOfCard":"00","FacltyCnt":"0000","CustLmt":"0.00","TtlBal":"-601.40","CurCode1":"BWP","ResInd":"","UsrName":"NO TELLER NAME","StmtFreq":"H","StmtCyc":"00","StmtDay":"31","GrpCode":"","AvgEodBal":"0.00","FatherName":"","BlackLstInd":"N","EmplInd":"","BlackLstStat":"0","BlackLstComnt":"","CreditRtng":"0","CustStat":"0","IdNum":"652311945","VipStat":"0","AccumCnt1":"0","AccumCnt2":"0","AccumCnt3":"0","AccumCnt4":"0","AccumCnt5":"0","AccumCnt6":"0","AccumCnt7":"0","AccumCnt8":"0","AccumCnt9":"0","AccumCnt10":"0","EmailAdd":"","LagCode":"1","BrchCode":"35","RtnMailInd":"N","HldMail":"","Typ":"","VipTyp":"","name1":"Mr","name2":"","CreateDt":"19092023","MemShpLnth":"124 YEARS  003 MONTHS","CurrAge":"032 YEARS  004 MONTHS","ServLnth":"","RemainServ":"","AvailChnl1":"","AvailChnl2":"","AvailChnl3":"","AvailChnl4":"","AvailChnl5":"","AvailChnl6":"","AvailChnl7":"","AvailChnl8":"","BioEnrollDt":"99999999","BioEnrollTime":"00:00:00","KYCFlag":"H","IdTyp":"0001","DOB":"22101991","TDNPFlag":"N","DNPExpryDt":"","NibbsBVN":"","Fac":"","Coll":{"AcctNum":"10205781559","Stat":"DISC","ChqbkFlag":"","CardFlag":"","AcctFlagTyp":"L","ProdDescptn":"MoMo Instant Loan","CurCode2":"BWP","RelnshpWtAcct":"OWN","Bal":"601.40","OvrdrftAcctLmt":"500.00","AcctTyp":"5000","AcctSubTyp":"0555","ShrtName":"","InstNum":"002","TagStat":"","LonOdAmt":"500.00","ArrAcctAmt":"560.00","Dpd":"2","OdInd":"","HowLong":"0.46","IBAN":"","AcctBrch":"35","CreationDt":"19092023","Acctstat":"40","PurpCod":"27","SignMndt":"","SignDetail":"","SignatoryNum":"0"}}}

Expected output

 {"Result":{"CustNum":"00000002010784868","CustTyp":"01","RelnshpMgr":"0","Title":"1","Name":"Mr Tebogo Sekalaba","Addr1":"Botswana","Addr2":"","Addr3":"","Addr4":"","PstCode":"","HomePhnNum":"","FaxNum":"","CountryOfRes":"BW","BussPhnNum":"","MobileNum":"71961292","Natlty":"BW","NumOfChqbk":"00","NumOfCard":"00","FacltyCnt":"0000","CustLmt":"0.00","TtlBal":"-601.40","CurCode1":"BWP","ResInd":"","UsrName":"NO TELLER NAME","StmtFreq":"H","StmtCyc":"00","StmtDay":"31","GrpCode":"","AvgEodBal":"0.00","FatherName":"","BlackLstInd":"N","EmplInd":"","BlackLstStat":"0","BlackLstComnt":"","CreditRtng":"0","CustStat":"0","IdNum":"652311945","VipStat":"0","AccumCnt1":"0","AccumCnt2":"0","AccumCnt3":"0","AccumCnt4":"0","AccumCnt5":"0","AccumCnt6":"0","AccumCnt7":"0","AccumCnt8":"0","AccumCnt9":"0","AccumCnt10":"0","EmailAdd":"","LagCode":"1","BrchCode":"35","RtnMailInd":"N","HldMail":"","Typ":"","VipTyp":"","name1":"Mr","name2":"","CreateDt":"19092023","MemShpLnth":"124 YEARS  003 MONTHS","CurrAge":"032 YEARS  004 MONTHS","ServLnth":"","RemainServ":"","AvailChnl1":"","AvailChnl2":"","AvailChnl3":"","AvailChnl4":"","AvailChnl5":"","AvailChnl6":"","AvailChnl7":"","AvailChnl8":"","BioEnrollDt":"99999999","BioEnrollTime":"00:00:00","KYCFlag":"H","IdTyp":"0001","DOB":"22101991","TDNPFlag":"N","DNPExpryDt":"","NibbsBVN":"","Fac":"","Coll":[{"AcctNum":"10205781559","Stat":"DISC","ChqbkFlag":"","CardFlag":"","AcctFlagTyp":"L","ProdDescptn":"MoMo Instant Loan","CurCode2":"BWP","RelnshpWtAcct":"OWN","Bal":"601.40","OvrdrftAcctLmt":"500.00","AcctTyp":"5000","AcctSubTyp":"0555","ShrtName":"","InstNum":"002","TagStat":"","LonOdAmt":"500.00","ArrAcctAmt":"560.00","Dpd":"2","OdInd":"","HowLong":"0.46","IBAN":"","AcctBrch":"35","CreationDt":"19092023","Acctstat":"40","PurpCod":"27","SignMndt":"","SignDetail":"","SignatoryNum":"0"}]}}

I have tried using and javascript to make single object array and respond json but doesnot works.

How do I achieve the expected output?

Upvotes: 1

Views: 76

Answers (3)

Noman Khan
Noman Khan

Reputation: 27

I have used the below code and it works fine.

    <!-- Handling the single object array -->
<jsontransform>
    <property name="synapse.commons.json.output.autoPrimitive" value="false"/>
</jsontransform>
<property name="data" expression="json-eval($.Result)"/>
<payloadFactory media-type="json">
    <format>
                                    {"Result":$1}
                                </format>
    <args>
        <arg expression="$ctx:data"/>
    </args>
</payloadFactory>
<script language="js">
<![CDATA[
    var inputJson = mc.getPayloadJSON();
    var inputJsonString = JSON.stringify(inputJson.Result.Coll)
    
    if (!Array.isArray(inputJson.Result.Coll)) {
        inputJson.Result.Coll = [inputJson.Result.Coll];
    }
    
    mc.setPayloadJSON(inputJson);
]]></script>

Upvotes: 0

ycr
ycr

Reputation: 14604

You can use a custom JSON Schema along with JSON Transform Mediator for this.

First Create a Local Entry with the JSON Schema like below.

<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="JsonSchema" xmlns="http://ws.apache.org/ns/synapse"><![CDATA[
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "Result": {
      "type": "object",
      "properties": {
        "Coll": {
          "type": "array",
          "items": {
            "type": "object"
          }
        }
      }
    }
  }
}
]]></localEntry>

Then in your API/Sequence add the following before responding back.

<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<jsontransform schema="JsonSchema"/>

Upvotes: 0

Shawn
Shawn

Reputation: 3159

you can do it in JavaScript - comments in the code

<script>
    // Wait for the entire HTML document to be fully loaded and parsed
    document.addEventListener('DOMContentLoaded', function() {
        // XML data as a string
        const xmlData = `
        <Result xmlns="http://ws.apache.org/ns/synapse">
          <ban:DOB xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">22101991</ban:DOB>
          <ban:TDNPFlag xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">N</ban:TDNPFlag>
          <ban:DNPExpryDt xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
          <ban:NibbsBVN xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
          <ban:Fac xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema"/>
          <ban:Coll xmlns:ban="http://TCS.BANCS.Adapter/BANCSSchema">
            <ban:AcctNum>10205781559</ban:AcctNum>
            <ban:Stat>DISC</ban:Stat>
            <ban:ChqbkFlag/>
            <ban:CardFlag/>
          </ban:Coll>
        </Result>
        `;

        // Create a new DOMParser instance
        const parser = new DOMParser();
        // Parse the XML string into a DOM Document
        const xmlDoc = parser.parseFromString(xmlData, "text/xml");

        // Initialize the structure of the JSON object
        const resultJson = {
            Result: {}
        };

        // Manually find and process the DOB element from the XML
        const dobElement = xmlDoc.querySelector("DOB");
        if (dobElement) {
            // If the DOB element exists, add its text content to the JSON object
            resultJson.Result.DOB = dobElement.textContent;
        }
        
        // You can add similar processing for other single elements here...

        // Find all 'Coll' elements in the XML to handle them specially
        const collElements = xmlDoc.querySelectorAll("Coll");
        // Initialize the 'Coll' property in the JSON object as an array
        resultJson.Result.Coll = [];
        // Iterate over each 'Coll' element found in the XML
        collElements.forEach((collElement) => {
            // For each 'Coll', create a corresponding object
            const collObj = {};
            // Extract and add the 'AcctNum' and 'Stat' (or other properties) from the XML to the coll object
            collObj.AcctNum = collElement.querySelector("AcctNum")?.textContent || "";
            collObj.Stat = collElement.querySelector("Stat")?.textContent || "";
            // Push the constructed coll object into the 'Coll' array in the JSON object
            resultJson.Result.Coll.push(collObj);
        });

        // Check if the 'Coll' array is empty
        if (resultJson.Result.Coll.length === 0) {
            // If it is, remove the 'Coll' property from the JSON object to avoid having an empty array
            delete resultJson.Result.Coll;
        }

        // Finally, log the constructed JSON object to the console, formatted for readability
        console.log(JSON.stringify(resultJson, null, 2));
    });

Upvotes: 0

Related Questions