NuGet - Scriban (XML Template + Data = XML)

Scriban takes a template, and a block of data, and merges it together with code.

Sample code

1
2
3
4
var template = Template.Parse(GetTemplate());
var result = await template.RenderAsync(templateModel);

await File.WriteAllTextAsync(outputFilePath, result, Encoding.UTF8);

Here is sample data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var templateModel = new XmlTemplateModel
{
Header = new HeaderInfo
{
InterfaceTypeId = parametersData["InterfaceTypeId"],
BusinessPartnerId = parametersData["BusinessPartnerId"],
SchemaVersion = parametersData["SchemaVersion"],
CurrentDateTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss")
},
Employees = employees,
EmployersCalPersId = employees.First().EmployersCalPERSId,
ReportPeriodBeginDate = employees.First().ReportPeriodBeginDate,
ReportPeriodEndDate = employees.First().ReportPeriodEndDate,
TestReport = employees.First().TestReport,
ReportType = employees.First().ReportType
};

Here is the template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
        private static string GetTemplate()
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<cuns:HeaderInfo xmlns:cuns="http://calpers.ca.gov/PSR/CommonUtilitiesV1">
<cuns:InterfaceTypeId>{{ header.interface_type_id }}</cuns:InterfaceTypeId>
<cuns:BusinessPartnerId>{{ header.business_partner_id }}</cuns:BusinessPartnerId>
<cuns:SchemaVersion>{{ header.schema_version }}</cuns:SchemaVersion>
<cuns:DateTime>{{ header.current_date_time }}</cuns:DateTime>
</cuns:HeaderInfo>
</soap:Header>
<soap:Body>
<n1:RetirementAndPayrollTransactions
xmlns:cuns="http://calpers.ca.gov/PSR/CommonUtilitiesV1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rhtns="http://calpers.ca.gov/PSR/RetirementHealthTransactionsV1"
xsi:schemaLocation="http://calpers.ca.gov/PSR/PayrollRetirementV1 PayrollRetirementV1.xsd"
xmlns:n1="http://calpers.ca.gov/PSR/PayrollRetirementV1">
<n1:EmployerPayrollReport>
<n1:Employer>
<n1:EmployersCalPERSId>{{ employers_cal_pers_id }}</n1:EmployersCalPERSId>
<n1:Report>
<n1:ReportPeriodBeginDate>{{ report_period_begin_date | date.to_string '%Y-%m-%d' }}</n1:ReportPeriodBeginDate>
<n1:ReportPeriodEndDate>{{ report_period_end_date | date.to_string '%Y-%m-%d' }}</n1:ReportPeriodEndDate>
<n1:ProgramType>SP2</n1:ProgramType>
<n1:TestReport>{{ test_report | string.downcase }}</n1:TestReport>
<n1:ReportType>{{ report_type }}</n1:ReportType>
<n1:ReportCounter>
<n1:RecordType>SIP</n1:RecordType>
<n1:RecordTypeCount>{{ employees.size }}</n1:RecordTypeCount>
<n1:RecordTypeTotal>{{ employees.size }}</n1:RecordTypeTotal>
</n1:ReportCounter>
{{~ for employee in employees ~}}
<n1:Participant>
<n1:ParticipantInfo>
<n1:ParticipantsCalPERSId>{{ employee.participants_cal_pers_id }}</n1:ParticipantsCalPERSId>
<n1:FirstName>{{ employee.first_name }}</n1:FirstName>
<n1:LastName>{{ employee.last_name }}</n1:LastName>
</n1:ParticipantInfo>
<n1:ParticipantRecordDetails>
<n1:EarnedPeriodDetails>
<n1:RecordPeriodBeginDate>{{ employee.record_period_begin_date | date.to_string '%Y-%m-%d' }}</n1:RecordPeriodBeginDate>
<n1:RecordPeriodEndDate>{{ employee.record_period_end_date | date.to_string '%Y-%m-%d' }}</n1:RecordPeriodEndDate>
</n1:EarnedPeriodDetails>
<n1:SupplementalIncomePlan>
<n1:PlanId>{{ employee.plan_id }}</n1:PlanId>
<n1:TaxedMemberPaidContributionOrDeduction>{{ employee.taxed_member_paid_contribution_or_deduction }}</n1:TaxedMemberPaidContributionOrDeduction>
<n1:TaxDeferredMemberPaidContributionOrDeduction>{{ employee.tax_deferred_member_paid_contribution_or_deduction }}</n1:TaxDeferredMemberPaidContributionOrDeduction>
</n1:SupplementalIncomePlan>
</n1:ParticipantRecordDetails>
</n1:Participant>
{{~ end ~}}
</n1:Report>
</n1:Employer>
</n1:EmployerPayrollReport>
</n1:RetirementAndPayrollTransactions>
</soap:Body>
</soap:Envelope>";
}
  • Notice
  • Header.InterfaceTypeId – on the template it’s That is all lowercase, capital lets have an underscore prefix.
  • Loops
    1
    2
    3
    {{~ for employee in employees ~}}
    Is used to looup through objects
    {{~ end ~}}

References