ISO20022.Suite is a powerful dotnet library an all-in-one solution that combines the robust capabilities of both ISO20022.XSD and ISO20022.Parser. This comprehensive suite streamlines the conversion of XSD to JSON, Validate Message as well as the parsing and generation of ISO 20022 messages, all within a single package. Whether you're working with complex XML schemas or transforming form data into ISO 20022 payment messages, ISO20022.Suite simplifies every step of the integration process, offering a unified and efficient tool for your financial messaging needs.
dotnet add package ISO20022.Suite
Install-Package ISO20022.Suite
ISO20022.Suite library help to parse or extract all the detailed information from the ISO20022 message based on predefined parsing rules.
using System.Data;
using ISO20022.Parser;
public class Program
{
private static async Task Main(string[] args)
{
IParsingService parsingService = new ParsingService(new ParsingJsonRules(@"data\parsing_rules.json"), "Document");
await parsingService.ParseXmlAsync(@"data\pacs.008.xml", (DataSet ds, Guid messageUniqueId, Guid uniquiId) =>
{
//DataSet ds: pacs.008.xml will have multiple messages in a file and this dataset will have the parsed data of the given message. Each message parsed will be callbacked over here for the further process.
// messageUniqueId : As pacs.008 will have multiple message, each message will identified with the given messageUniqueId.
// uniqueId: this id is represent the unique file Id. Meaning each passed file has been represent by the given Id.
Task task = Task.Run(() =>
{
// either we can transform to CSV/Excel or transfered to DB using bulk DB operation
string dateTime = DateTime.Now.ToString("ddmmyyyyHHmmssfff");
foreach(DataTable dt in ds.Tables)
{
ExportDataTableToCsv(dt, @$"export\{messageUniqueId}_{dt.TableName}_{uniquiId}.csv");
}
});
return task;
});
Console.Read();
}
static void ExportDataTableToCsv(DataTable dataTable, string filePath)
{
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
// Create a StreamWriter to write to the CSV file
using (StreamWriter writer = new StreamWriter(filePath))
{
// Write the header row with column names
foreach (DataColumn column in dataTable.Columns)
{
writer.Write(column.ColumnName);
writer.Write(",");
}
writer.WriteLine(); // Move to the next line
// Write the data rows
foreach (DataRow row in dataTable.Rows)
{
foreach (object item in row.ItemArray)
{
writer.Write(item);
writer.Write(",");
}
writer.WriteLine(); // Move to the next line
}
}
}
}
Please follow the Parsing Rules example given in the data directory of the repository. Mapping Rules should follow below model class structure
public class MappingRules
{
public string Namespace { get; set; }
public List Mappings { get; set; }
}
public class MappingTable
{
public string NodeName { get; set; }
public string XPath { get; set; }
public IList Columns { get; set;}
}
public class MappingColumn
{
public int OrderNumber { get; set; }
public string NodeName { get; set; }
public string XPath { get; set; }
public string DataType { get; set; }
public int MinLength { get; set; }
public int MaxLength { get; set; }
public int fractionDigits { get; set; }
public int totalDigits { get; set; }
}
The given example is in json file. Suppose you want to store Parsing rules in Database. Now you need to override the ParsingRules class method DeserializeRules.
public class ParsingDatabaseRules : ParsingRules
{
public override void DeserializeRules()
{
//MapParsingRules is of type IList?
MapParsingRules = GetMyRulesFromDB();
}
}
using ISO20022.XSD;
string xsdFileName = "pacs.008.001.10.xsd";
var fileInfo = new FileInfo(xsdFileName);
if (File.Exists(fileName) && fileInfo.Extension.Equals(".xsd"))
{
XsdToJson xsdLib = new(fileName);
xsdLib.Convert();
File.AppendAllText(fileInfo.FullName.Replace(".xsd", ".json"), xsdLib.SchemaJson);
}
{
"namespace": "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.10",
"schemaElement": {
"id": "Document",
"name": "Document",
"dataType": null,
"minOccurs": "1",
"maxOccurs": null,
"minLength": null,
"maxLength": null,
"pattern": null,
"fractionDigits": null,
"totalDigits": null,
"minInclusive": null,
"maxInclusive": null,
"values": null,
"isCurrency": false,
"xpath": "Document",
"elements":[
...
]
}
}
using ISO20022.Suite;
string targetNamespace = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.10";
string jsonData = File.ReadAllText(@jsonPath);
string xsdContent = File.ReadAllText(@xsdFilePath);
XElement xml = MxMessage.Create(jsonData, targetNamespace) ?? throw new Exception("Conversion failed");
if (MxMessage.ValidateMXMessage(xsdContent, xml.ToString(), out string validationMessage))
{
if (string.IsNullOrEmpty(validationMessage))
{
Console.WriteLine(xml?.ToString());
}
else
{
Console.Error.WriteLine(validationMessage);
}
}
{
"Document": {
"Document_BkToCstmrStmt": {
"Document_BkToCstmrStmt_GrpHdr": {
"Document_BkToCstmrStmt_GrpHdr_MsgId": "235549650",
"Document_BkToCstmrStmt_GrpHdr_CreDtTm": "2023-10-05T14:43:51.979",
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt": {
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt_Nm": "Test Client Ltd.",
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt_Id": {
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt_Id_OrgId": {
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt_Id_OrgId_Othr": [
{
"Document_BkToCstmrStmt_GrpHdr_MsgRcpt_Id_OrgId_Othr_Id": "test001"
}
]
}
}
},
"Document_BkToCstmrStmt_GrpHdr_AddtlInf": "AddTInf"
},
"Document_BkToCstmrStmt_Stmt": [
{
"Document_BkToCstmrStmt_Stmt_Id": "258158850",
"Document_BkToCstmrStmt_Stmt_ElctrncSeqNb": "1",
"Document_BkToCstmrStmt_Stmt_LglSeqNb": "1",
"Document_BkToCstmrStmt_Stmt_CreDtTm": "2023-10-05T14:43:52.098",
"Document_BkToCstmrStmt_Stmt_FrToDt": {
"Document_BkToCstmrStmt_Stmt_FrToDt_FrDtTm": "2023-09-30T20:00:00.000",
"Document_BkToCstmrStmt_Stmt_FrToDt_ToDtTm": "2023-10-01T19:59:59.000"
},
"Document_BkToCstmrStmt_Stmt_Acct": {
"Document_BkToCstmrStmt_Stmt_Acct_Tp": {
"Document_BkToCstmrStmt_Stmt_Acct_Tp_Prtry": "IBDA_DDA"
},
"Document_BkToCstmrStmt_Stmt_Acct_Ccy": "USD",
"Document_BkToCstmrStmt_Stmt_Acct_Nm": "Sample Name 123",
"Document_BkToCstmrStmt_Stmt_Acct_Svcr": {
"Document_BkToCstmrStmt_Stmt_Acct_Svcr_FinInstnId": {
"Document_BkToCstmrStmt_Stmt_Acct_Svcr_FinInstnId_BICFI": "GSCRUS30",
"Document_BkToCstmrStmt_Stmt_Acct_Svcr_FinInstnId_Nm": "Goldman Sachs Bank"
}
}
},
"Document_BkToCstmrStmt_Stmt_Bal": [
{
"Document_BkToCstmrStmt_Stmt_Bal_Tp": {
"Document_BkToCstmrStmt_Stmt_Bal_Tp_CdOrPrtry": {
"Document_BkToCstmrStmt_Stmt_Bal_Tp_CdOrPrtry_Cd": "OPBD"
}
},
"Document_BkToCstmrStmt_Stmt_Bal_Amt": {
"Document_BkToCstmrStmt_Stmt_Bal_Amt_Ccy": "USD",
"Document_BkToCstmrStmt_Stmt_Bal_Amt_Amt": "843686.20"
},
"Document_BkToCstmrStmt_Stmt_Bal_CdtDbtInd": "DBIT",
"Document_BkToCstmrStmt_Stmt_Bal_Dt": {
"Document_BkToCstmrStmt_Stmt_Bal_Dt_DtTm": "2023-09-30T20:00:00.000"
}
},
{
"Document_BkToCstmrStmt_Stmt_Bal_Tp": {
"Document_BkToCstmrStmt_Stmt_Bal_Tp_CdOrPrtry": {
"Document_BkToCstmrStmt_Stmt_Bal_Tp_CdOrPrtry_Cd": "CLAV"
}
},
"Document_BkToCstmrStmt_Stmt_Bal_Amt": {
"Document_BkToCstmrStmt_Stmt_Bal_Amt_Ccy": "USD",
"Document_BkToCstmrStmt_Stmt_Bal_Amt_Amt": "334432401.27"
},
"Document_BkToCstmrStmt_Stmt_Bal_CdtDbtInd": "CRDT",
"Document_BkToCstmrStmt_Stmt_Bal_Dt": {
"Document_BkToCstmrStmt_Stmt_Bal_Dt_DtTm": "2023-10-01T23:59:00.000Z"
}
}
]
}
]
}
}
}
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.10">
<BkToCstmrStmt>
<GrpHdr>
<MsgId>235549650</MsgId>
<CreDtTm>2023-10-05T14:43:51.979</CreDtTm>
<MsgRcpt>
<Nm>Test Client Ltd.</Nm>
<Id>
<OrgId>
<Othr>
<Id>test001</Id>
</Othr>
</OrgId>
</Id>
</MsgRcpt>
<AddtlInf>AddTInf</AddtlInf>
</GrpHdr>
<Stmt>
<Id>258158850</Id>
<ElctrncSeqNb>1</ElctrncSeqNb>
<LglSeqNb>1</LglSeqNb>
<CreDtTm>2023-10-05T14:43:52.098</CreDtTm>
<FrToDt>
<FrDtTm>2023-09-30T20:00:00.000</FrDtTm>
<ToDtTm>2023-10-01T19:59:59.000</ToDtTm>
</FrToDt>
<Acct>
<Tp>
<Prtry>IBDA_DDA</Prtry>
</Tp>
<Ccy>USD</Ccy>
<Nm>Sample Name 123</Nm>
<Svcr>
<FinInstnId>
<BICFI>GSCRUS30</BICFI>
<Nm>Goldman Sachs Bank</Nm>
</FinInstnId>
</Svcr>
</Acct>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>OPBD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="USD">843686.20</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Dt>
<DtTm>2023-09-30T20:00:00.000</DtTm>
</Dt>
</Bal>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>CLAV</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="USD">334432401.27</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<DtTm>2023-10-01T23:59:00.000Z</DtTm>
</Dt>
</Bal>
</Stmt>
</BkToCstmrStmt>
</Document>