ISO20022.Suite is a powerful .NET library and an all-in-one solution that combines the robust capabilities of both ISO20022.XSD and ISO20022.Parser. This comprehensive suite streamlines XSD-to-JSON conversion, message validation, 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, providing 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": {
"CstmrCdtTrfInitn": {
"GrpHdr": {
"MsgId": "123456",
"CreDtTm": "2025-03-27T10:00:00",
"NbOfTxs": "1",
"CtrlSum": "1000",
"InitgPty": {
"Nm": "Sender Company",
"CtryOfRes": "US"
}
},
"PmtInf": [
{
"PmtInfId": "PAY001",
"PmtMtd": "TRF",
"BtchBookg": "false",
"Dbtr": {
"Nm": "John Doe"
},
"DbtrAcct": {
"Nm": "DE89370400440532013000"
},
"DbtrAgt": {
"FinInstnId": {
"BICFI": "DEUTDEFFXXX"
}
},
"CdtTrfTxInf": [
{
"PmtId": {
"EndToEndId": "TX123"
},
"Amt": {
"InstdAmt": {
"Ccy": "USD",
"Amt": "1000"
}
},
"CdtrAgt": {
"FinInstnId": {
"BICFI": "BNPAFRPPXXX"
}
},
"Cdtr": {
"Nm": "Jane Smith"
},
"CdtrAcct": {
"Id": {
"IBAN": "FR7630006000011234567890189"
}
}
}
]
}
]
}
}
}
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.12">
<CstmrCdtTrfInitn>
<GrpHdr>
123456</MsgId>
<CreDtTm>2025-03-27T10:00:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>1000</CtrlSum>
<InitgPty>
<Nm>Sender Company</Nm>
<CtryOfRes>US</CtryOfRes>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>PAY001</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>false</BtchBookg>
<Dbtr>
<Nm>John Doe</Nm>
</Dbtr>
<DbtrAcct>
<Nm>DE89370400440532013000</Nm>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BICFI>DEUTDEFFXXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>TX123</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="USD">1000</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BICFI>BNPAFRPPXXX</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Jane Smith</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>FR7630006000011234567890189</IBAN>
</Id>
</CdtrAcct>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>