HI,
What is the best practice to generate XML dynamically ?
The source data is in the database.
Discussion posts and replies are publicly visible
What's the Use Case? What XML format (XSD Schema) does the data need to be structured as? What is going to be consuming this data?
Note: if you can retrieve the data and cast it to Appjan CDT format you can then use fn!toxml()
Stewart Burchell
Thank for your reply. Please find below details :
Use Case : To generate XML dynamically from data in database.
XML Format : Plese refere belw schema
What is going to be consuming data : A variable which will be used to send this on MQ
There is a parent child tags and few levels of casting . We have already tried using toXML() and it would need around 10-15 CDTs.
Can we have another way to creae it?
Below is the sample schema :
<?xml version="1.0" encoding="utf-8"?><BaExchReq xmlns:xc=""> <Envelope> <TransactionRef>##</TransactionRef> <MsgId>##</MsgId> <CreationTime>##</CreationTime> <Requestor>##</Requestor> <Responder>c##</Responder> <Service>##</Service> <RequestType>##</RequestType> </Envelope> <Payload> <AppHdr xmlns=""> <MsgRef>##</MsgRef> <CrDate>##</CrDate> </AppHdr> <Document xmlns="##"> <SbcptOrdrV03> <MsgId> <Id>##</Id> <CreDtTm>##</CreDtTm> </MsgId> <MltplOrdrDtls> <InvstmtAcctDtls> <AcctId> <Prtry> <Id>##</Id> </Prtry> </AcctId> </InvstmtAcctDtls> <IndvOrdrDtls> <OrdrRef>##</OrdrRef> <FinInstrmDtls> <Id> <ISIN>##</ISIN> </Id> </FinInstrmDtls> <GrssAmt Ccy="">##</GrssAmt> <PhysDlvryInd>##</PhysDlvryInd> <ReqdSttlmCcy>##</ReqdSttlmCcy> </IndvOrdrDtls> </MltplOrdrDtls> </SbcptOrdrV03> </Document> </Payload> </BaExchReq>
It won't be elegant but you could assemble the message by providing a template of the message with a set of 'tokens' embedded in it that you want to be substituted with the values from your database. I don't know what the data looks like when you've retrieved it from the database but if you can coerce it into the format that I use in the following example this is how I would approach it:
Here's the XML message as a template with just the first 3 data items set as tags:
<?xml version="1.0" encoding="utf-8"?><BaExchReq xmlns:xc=""> <Envelope> <TransactionRef>###TransactionRef###</TransactionRef> <MsgId>###MsgId###</MsgId> <CreationTime>###CreationTime###</CreationTime> <Requestor>##</Requestor> <Responder>c##</Responder> <Service>##</Service> <RequestType>##</RequestType> </Envelope> <Payload> <AppHdr xmlns=""> <MsgRef>##</MsgRef> <CrDate>##</CrDate> </AppHdr> <Document xmlns="##"> <SbcptOrdrV03> <MsgId> <Id>##</Id> <CreDtTm>##</CreDtTm> </MsgId> <MltplOrdrDtls> <InvstmtAcctDtls> <AcctId> <Prtry> <Id>##</Id> </Prtry> </AcctId> </InvstmtAcctDtls> <IndvOrdrDtls> <OrdrRef>##</OrdrRef> <FinInstrmDtls> <Id> <ISIN>##</ISIN> </Id> </FinInstrmDtls> <GrssAmt Ccy="">##</GrssAmt> <PhysDlvryInd>##</PhysDlvryInd> <ReqdSttlmCcy>##</ReqdSttlmCcy> </IndvOrdrDtls> </MltplOrdrDtls> </SbcptOrdrV03> </Document> </Payload> </BaExchReq>
And here's the code that takes that template a substitutes the tags for the corresponding values:
a!localVariables( local!parameters: { {tag: "###TransactionRef###", value: "ABC123"}, {tag: "###MsgId###", value: "123a4fc4g4aa1204"}, {tag: "###CreationTime###", value: "28-08-2020 09:03"} }, fn!reduce( fn!substitute( _, _ ), ri!xmlTemplate, fn!merge( fn!index(local!parameters,"tag"), fn!index(local!parameters,"value") ) ) )
fn!reduce() is a loop that starts with an initial value - the template - and, for a provided list, runs a function - in this case fn!substitute - on that value and then takes the result and passes that to the next iteration of the provided function.
fn!merge() takes a set of lists and makes a list of those lists - in this case, takes the list of tags and list of values and pairs them up.
The underscore is a way of 'deferring' the actual value to be passed to run-time and maps the inputs to fn!substitute() to the items that follow in fn!reduce() in the order they appear.
I know: it's not intuitive but it is effective.
Note: I am assuming that the example you've provided to me is 'static' - that is, there are not any repeating elements, although the name 'MltplOrdrDtls' does suggest there may be repeating elements within it, which will be a different challenge.