Design

XML templates

Write an XML file with Carbone tags, and generate e-invoices, payment files and product feeds from JSON data.
COMMUNITY FEATURE Available for:
Carbone Cloud
Carbone On-premise
Embedded Carbone JS
  v2.0+ 

Any XML file can be a template. Write Carbone tags in element text and attribute values, send your JSON data to the API, and get back an XML file with the structure of the template, ready for a bank, a tax platform or a marketplace.

Basic

Write a tag where a value goes, in the text of an element or in an attribute value. In {d.recipient.name}, d is the root of the data and recipient.name is the path to the value. Carbone replaces only the tags: the XML declaration, the namespaces and their prefixes, the comments and the indentation stay as written.

data.jsonDownload
{
  "reference": "SHP-2026-10482",
  "shipDate": "2026-11-12",
  "service": "EXPRESS",
  "shipper": {
    "name": "Acme Corporation",
    "city": "Chicago",
    "country": "US"
  },
  "recipient": {
    "name": "Vandelay & Sons Industries",
    "street": "18 Mill Lane",
    "postalCode": "02108",
    "city": "Boston",
    "country": "US",
    "email": "receiving@vandelay.example"
  },
  "package": {
    "weight": 4.2,
    "contents": "Cordless drills with batteries <100 Wh"
  },
  "instructions": "Use the loading dock & call 10 min before"
}
template.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<ShipmentRequest xmlns="urn:acme:shipping:2.0" version="2.0">
  <Reference>{d.reference}</Reference>
  <ShipDate>{d.shipDate}</ShipDate>
  <Service code="{d.service}"/>
  <Shipper>
    <Name>{d.shipper.name}</Name>
    <City>{d.shipper.city}</City>
    <Country>{d.shipper.country}</Country>
  </Shipper>
  <Recipient>
    <Name>{d.recipient.name}</Name>
    <Street>{d.recipient.street}</Street>
    <City postalCode="{d.recipient.postalCode}">{d.recipient.city}</City>
    <Country>{d.recipient.country}</Country>
    <Email>{d.recipient.email}</Email>
  </Recipient>
  <Package weight="{d.package.weight}" unit="kg">
    <Contents>{d.package.contents}</Contents>
  </Package>
  <Instructions>{d.instructions}</Instructions>
</ShipmentRequest>
report.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<ShipmentRequest xmlns="urn:acme:shipping:2.0" version="2.0">
  <Reference>SHP-2026-10482</Reference>
  <ShipDate>2026-11-12</ShipDate>
  <Service code="EXPRESS"/>
  <Shipper>
    <Name>Acme Corporation</Name>
    <City>Chicago</City>
    <Country>US</Country>
  </Shipper>
  <Recipient>
    <Name>Vandelay &amp; Sons Industries</Name>
    <Street>18 Mill Lane</Street>
    <City postalCode="02108">Boston</City>
    <Country>US</Country>
    <Email>receiving@vandelay.example</Email>
  </Recipient>
  <Package weight="4.2" unit="kg">
    <Contents>Cordless drills with batteries &lt;100 Wh</Contents>
  </Package>
  <Instructions>Use the loading dock &amp; call 10 min before</Instructions>
</ShipmentRequest>

Learn more about tags.

Loops

A loop repeats an element for each item of an array. The template needs two elements:

Carbone repeats the element with its children and attributes. Add a condition to the [i+1] tag to filter the items: noindex=false leaves the cart page out of this sitemap.

data.jsonDownload
{
  "pages": [
    { "url": "https://www.acme.example/", "updatedAt": "2026-11-10T08:15:00Z", "changefreq": "daily", "priority": 1, "noindex": false },
    { "url": "https://www.acme.example/products/cordless-drill", "updatedAt": "2026-11-04T14:30:00Z", "changefreq": "weekly", "priority": 0.8, "noindex": false },
    { "url": "https://www.acme.example/products?category=tools&sort=new", "updatedAt": "2026-11-09T06:00:00Z", "changefreq": "daily", "priority": 0.6, "noindex": false },
    { "url": "https://www.acme.example/cart", "updatedAt": "2026-11-10T09:00:00Z", "changefreq": "always", "priority": 0.1, "noindex": true },
    { "url": "https://www.acme.example/support/warranty", "updatedAt": "2026-09-22T10:00:00Z", "changefreq": "monthly", "priority": 0.5, "noindex": false }
  ]
}
template.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>{d.pages[i].url}</loc>
    <lastmod>{d.pages[i].updatedAt:formatD('YYYY-MM-DD')}</lastmod>
    <changefreq>{d.pages[i].changefreq}</changefreq>
    <priority>{d.pages[i].priority}</priority>
  </url>
  <url>
    <loc>{d.pages[i+1, noindex=false].url}</loc>
  </url>
</urlset>
report.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://www.acme.example/</loc>
    <lastmod>2026-11-10</lastmod>
    <changefreq>daily</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc>https://www.acme.example/products/cordless-drill</loc>
    <lastmod>2026-11-04</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://www.acme.example/products?category=tools&amp;sort=new</loc>
    <lastmod>2026-11-09</lastmod>
    <changefreq>daily</changefreq>
    <priority>0.6</priority>
  </url>
  <url>
    <loc>https://www.acme.example/support/warranty</loc>
    <lastmod>2026-09-22</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  
</urlset>

Learn more about loops, filtering and sorting.

Nested loops

A loop can contain another loop. In this SEPA credit transfer file (pain.001.001.09), {d.batches[i].id} repeats the payment block PmtInf for each execution date, and {d.batches[i].payments[i].name} repeats the transaction CdtTrfTxInf for each payment of the block. The PmtInf element with [i+1] closes the outer loop.

Aggregators fill the control sums: :aggCount counts the transactions and :aggSum adds their amounts, for the whole file in the group header, and for each block inside the loop.

data.jsonDownload
{
  "messageId": "ACME-SCT-20261110-01",
  "createdAt": "2026-11-10T08:30:00Z",
  "debtor": {
    "name": "Acme Corporation",
    "iban": "FR7630006000011234567890189"
  },
  "batches": [
    {
      "id": "BATCH-20261112",
      "executionDate": "2026-11-12",
      "payments": [
        { "invoice": "INV-88412", "amount": 1249.99, "name": "Globex GmbH", "iban": "DE89370400440532013000" },
        { "invoice": "INV-88419", "amount": 860.25, "name": "Initech B.V.", "iban": "NL91ABNA0417164300" }
      ]
    },
    {
      "id": "BATCH-20261115",
      "executionDate": "2026-11-15",
      "payments": [
        { "invoice": "INV-88433", "amount": 3420.17, "name": "Umbrella Logistica S.L.", "iban": "ES9121000418450200051332" }
      ]
    }
  ]
}
template.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>{d.messageId}</MsgId>
      <CreDtTm>{d.createdAt:formatD('YYYY-MM-DDTHH:mm:ssZ')}</CreDtTm>
      <NbOfTxs>{d.batches[].payments[].amount:aggCount}</NbOfTxs>
      <CtrlSum>{d.batches[].payments[].amount:aggSum:round(2)}</CtrlSum>
      <InitgPty><Nm>{d.debtor.name}</Nm></InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>{d.batches[i].id}</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <NbOfTxs>{d.batches[i].payments[].amount:aggCount}</NbOfTxs>
      <CtrlSum>{d.batches[i].payments[].amount:aggSum:round(2)}</CtrlSum>
      <PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf>
      <ReqdExctnDt><Dt>{d.batches[i].executionDate}</Dt></ReqdExctnDt>
      <Dbtr><Nm>{d.debtor.name}</Nm></Dbtr>
      <DbtrAcct><Id><IBAN>{d.debtor.iban}</IBAN></Id></DbtrAcct>
      <DbtrAgt><FinInstnId><Othr><Id>NOTPROVIDED</Id></Othr></FinInstnId></DbtrAgt>
      <CdtTrfTxInf>
        <PmtId><EndToEndId>{d.batches[i].payments[i].invoice}</EndToEndId></PmtId>
        <Amt><InstdAmt Ccy="EUR">{d.batches[i].payments[i].amount}</InstdAmt></Amt>
        <Cdtr><Nm>{d.batches[i].payments[i].name}</Nm></Cdtr>
        <CdtrAcct><Id><IBAN>{d.batches[i].payments[i].iban}</IBAN></Id></CdtrAcct>
      </CdtTrfTxInf>
      <CdtTrfTxInf>
        <PmtId><EndToEndId>{d.batches[i].payments[i+1].invoice}</EndToEndId></PmtId>
      </CdtTrfTxInf>
    </PmtInf>
    <PmtInf>
      <PmtInfId>{d.batches[i+1].id}</PmtInfId>
    </PmtInf>
  </CstmrCdtTrfInitn>
</Document>
report.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>ACME-SCT-20261110-01</MsgId>
      <CreDtTm>2026-11-10T09:30:00+01:00</CreDtTm>
      <NbOfTxs>3</NbOfTxs>
      <CtrlSum>5530.41</CtrlSum>
      <InitgPty><Nm>Acme Corporation</Nm></InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>BATCH-20261112</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <NbOfTxs>2</NbOfTxs>
      <CtrlSum>2110.24</CtrlSum>
      <PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf>
      <ReqdExctnDt><Dt>2026-11-12</Dt></ReqdExctnDt>
      <Dbtr><Nm>Acme Corporation</Nm></Dbtr>
      <DbtrAcct><Id><IBAN>FR7630006000011234567890189</IBAN></Id></DbtrAcct>
      <DbtrAgt><FinInstnId><Othr><Id>NOTPROVIDED</Id></Othr></FinInstnId></DbtrAgt>
      <CdtTrfTxInf>
        <PmtId><EndToEndId>INV-88412</EndToEndId></PmtId>
        <Amt><InstdAmt Ccy="EUR">1249.99</InstdAmt></Amt>
        <Cdtr><Nm>Globex GmbH</Nm></Cdtr>
        <CdtrAcct><Id><IBAN>DE89370400440532013000</IBAN></Id></CdtrAcct>
      </CdtTrfTxInf>
      <CdtTrfTxInf>
        <PmtId><EndToEndId>INV-88419</EndToEndId></PmtId>
        <Amt><InstdAmt Ccy="EUR">860.25</InstdAmt></Amt>
        <Cdtr><Nm>Initech B.V.</Nm></Cdtr>
        <CdtrAcct><Id><IBAN>NL91ABNA0417164300</IBAN></Id></CdtrAcct>
      </CdtTrfTxInf>
      
    </PmtInf>
    <PmtInf>
      <PmtInfId>BATCH-20261115</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <NbOfTxs>1</NbOfTxs>
      <CtrlSum>3420.17</CtrlSum>
      <PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf>
      <ReqdExctnDt><Dt>2026-11-15</Dt></ReqdExctnDt>
      <Dbtr><Nm>Acme Corporation</Nm></Dbtr>
      <DbtrAcct><Id><IBAN>FR7630006000011234567890189</IBAN></Id></DbtrAcct>
      <DbtrAgt><FinInstnId><Othr><Id>NOTPROVIDED</Id></Othr></FinInstnId></DbtrAgt>
      <CdtTrfTxInf>
        <PmtId><EndToEndId>INV-88433</EndToEndId></PmtId>
        <Amt><InstdAmt Ccy="EUR">3420.17</InstdAmt></Amt>
        <Cdtr><Nm>Umbrella Logistica S.L.</Nm></Cdtr>
        <CdtrAcct><Id><IBAN>ES9121000418450200051332</IBAN></Id></CdtrAcct>
      </CdtTrfTxInf>
      
    </PmtInf>
    
  </CstmrCdtTrfInitn>
</Document>

Learn more about aggregators.

Numbers and dates

XML schemas expect machine formats, not the formats of a language. Use these formatters:

Value Tag Result
Date (xs:date) {d.date:formatD('YYYY-MM-DD')} 2026-11-12
Date and time (xs:dateTime) {d.createdAt:formatD('YYYY-MM-DDTHH:mm:ssZ')} 2026-11-10T09:30:00+01:00
Factur-X date (format 102) {d.issueDate:formatD('YYYYMMDD')} 20261110
Decimal (xs:decimal) {d.total:round(2)} 3152.64

See the date and number formatters, and in-template options.

Conditions

Schemas often reject empty elements. Remove an optional element when its value is missing, or print one value or another:

data.jsonDownload
{
  "store": {
    "name": "Acme Outdoor",
    "url": "https://shop.acme.example",
    "description": "Camping and hiking gear"
  },
  "products": [
    {
      "sku": "TNT-2P-GRN",
      "title": "Ridge 2-Person Tent & Footprint",
      "url": "https://shop.acme.example/p/ridge-tent?color=green&size=2p",
      "image": "https://shop.acme.example/img/ridge-tent-green.jpg",
      "stock": 34,
      "price": 249.99,
      "salePrice": 199.99,
      "brand": "Acme Outdoor",
      "gtin": "00012345678905"
    },
    {
      "sku": "LMP-HD-350",
      "title": "Trail Headlamp 350 lm",
      "url": "https://shop.acme.example/p/trail-headlamp",
      "image": "https://shop.acme.example/img/trail-headlamp.jpg",
      "stock": 0,
      "price": 39.95,
      "salePrice": null,
      "brand": "Acme Outdoor",
      "gtin": ""
    }
  ]
}
template.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
  <channel>
    <title>{d.store.name}</title>
    <link>{d.store.url}</link>
    <description>{d.store.description}</description>
    <item>
      <g:id>{d.products[i].sku}</g:id>
      <title>{d.products[i].title}</title>
      <link>{d.products[i].url}</link>
      <g:image_link>{d.products[i].image}</g:image_link>
      <g:availability>{d.products[i].stock:ifGT(0):show('in_stock'):elseShow('out_of_stock')}</g:availability>
      <g:price>{d.products[i].price} USD</g:price>{d.products[i].salePrice:ifNEM:showBegin}
      <g:sale_price>{d.products[i].salePrice} USD</g:sale_price>{d.products[i].salePrice:showEnd}
      <g:brand>{d.products[i].brand}</g:brand>{d.products[i].gtin:ifNEM:showBegin}
      <g:gtin>{d.products[i].gtin}</g:gtin>{d.products[i].gtin:showEnd}{d.products[i].gtin:ifEM:showBegin}
      <g:identifier_exists>no</g:identifier_exists>{d.products[i].gtin:showEnd}
      <g:condition>new</g:condition>
    </item>
    <item>
      <g:id>{d.products[i+1].sku}</g:id>
    </item>
  </channel>
</rss>
report.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
  <channel>
    <title>Acme Outdoor</title>
    <link>https://shop.acme.example</link>
    <description>Camping and hiking gear</description>
    <item>
      <g:id>TNT-2P-GRN</g:id>
      <title>Ridge 2-Person Tent &amp; Footprint</title>
      <link>https://shop.acme.example/p/ridge-tent?color=green&amp;size=2p</link>
      <g:image_link>https://shop.acme.example/img/ridge-tent-green.jpg</g:image_link>
      <g:availability>in_stock</g:availability>
      <g:price>249.99 USD</g:price>
      <g:sale_price>199.99 USD</g:sale_price>
      <g:brand>Acme Outdoor</g:brand>
      <g:gtin>00012345678905</g:gtin>
      <g:condition>new</g:condition>
    </item>
    <item>
      <g:id>LMP-HD-350</g:id>
      <title>Trail Headlamp 350 lm</title>
      <link>https://shop.acme.example/p/trail-headlamp</link>
      <g:image_link>https://shop.acme.example/img/trail-headlamp.jpg</g:image_link>
      <g:availability>out_of_stock</g:availability>
      <g:price>39.95 USD</g:price>
      <g:brand>Acme Outdoor</g:brand>
      <g:identifier_exists>no</g:identifier_exists>
      <g:condition>new</g:condition>
    </item>
    
  </channel>
</rss>

Write the begin tag at the end of the line above the block, and the end tag at the end of the last line of the block: the removed block leaves no empty line. :hideBegin and :hideEnd work the same way.

To remove an attribute, write the block inside the start tag: <Contact{d.email:ifNEM:showBegin} email="{d.email}"{d.email:showEnd}>. The template is no longer well-formed XML, but the report is. Learn more about conditional blocks and inline conditions.

Totals

Math formatters and aggregators compute the amounts from the data. This Factur-X invoice uses the MINIMUM profile, which has no invoice lines: {d.lines[].qty:mul(.price):aggSum} computes the net total from the lines of the JSON data, and :set stores it in c.net. The tax and the totals below read c.net.

data.jsonDownload
{
  "number": "FA-2026-0417",
  "issueDate": "2026-11-10",
  "currency": "EUR",
  "vatRate": 20,
  "prepaid": 500,
  "seller": {
    "name": "Acme Corporation SAS",
    "siren": "999999998",
    "country": "FR",
    "vatId": "FR11999999998"
  },
  "buyer": {
    "name": "Globex SARL"
  },
  "lines": [
    { "name": "Cordless drill 18 V", "qty": 12, "price": 129.99 },
    { "name": "Battery pack 5 Ah", "qty": 24, "price": 64.49 },
    { "name": "Delivery", "qty": 1, "price": 45 }
  ]
}
template.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:factur-x.eu:1p0:minimum</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>{d.number}</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">{d.issueDate:formatD('YYYYMMDD')}</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>{d.seller.name}</ram:Name>
        <ram:SpecifiedLegalOrganization><ram:ID schemeID="0002">{d.seller.siren}</ram:ID></ram:SpecifiedLegalOrganization>
        <ram:PostalTradeAddress><ram:CountryID>{d.seller.country}</ram:CountryID></ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration><ram:ID schemeID="VA">{d.seller.vatId}</ram:ID></ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>{d.buyer.name}</ram:Name>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery/>
    <ram:ApplicableHeaderTradeSettlement>{d.lines[].qty:mul(.price):aggSum:round(2):set(c.net)}
      <ram:InvoiceCurrencyCode>{d.currency}</ram:InvoiceCurrencyCode>{c.net:mul(d.vatRate):div(100):round(2):set(c.vat)}
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:TaxBasisTotalAmount>{c.net}</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="{d.currency}">{c.vat}</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>{c.net:add(c.vat):round(2)}</ram:GrandTotalAmount>
        <ram:DuePayableAmount>{c.net:add(c.vat):sub(d.prepaid):round(2)}</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
report.xmlDownload
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:factur-x.eu:1p0:minimum</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>FA-2026-0417</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20261110</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Acme Corporation SAS</ram:Name>
        <ram:SpecifiedLegalOrganization><ram:ID schemeID="0002">999999998</ram:ID></ram:SpecifiedLegalOrganization>
        <ram:PostalTradeAddress><ram:CountryID>FR</ram:CountryID></ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration><ram:ID schemeID="VA">FR11999999998</ram:ID></ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>Globex SARL</ram:Name>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery/>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:TaxBasisTotalAmount>3152.64</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">630.53</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>3783.17</ram:GrandTotalAmount>
        <ram:DuePayableAmount>3283.17</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

A :set tag prints nothing. Write it at the end of a line, above the tags that read its value. Learn more about math formatters and :set.

The BASIC, EN 16931 and EXTENDED profiles add the invoice lines: repeat ram:IncludedSupplyChainTradeLineItem with a loop. To embed the XML in the PDF invoice, use :attachFile, as in the Factur-X invoice example.

Best practices

Automate an XML file

To generate an XML file from an XML template with the Carbone API:

  1. Prepare two files: an XML template with Carbone tags, like {d.name}, and the JSON data to populate it. You can use the files of the Nested loops example.
  2. Generate the XML in one of three ways:
    • Use an official Carbone integration, like N8N, Make, Zapier, Airtable or Bubble.
    • Use a Carbone SDK: Node.js, Go, Python, Java, JavaScript or PHP.
    • Send a POST /render/template HTTP request to the Carbone API, like this curl command:
curl --location --request POST 'https://api.carbone.io/render/template?download=true' \
  --header 'carbone-version: 5' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer API_TOKEN' \
  --data-raw "{
    \"data\": $(cat nested-data.json),
    \"template\": \"$(base64 -i nested-template.xml)\",
    \"timezone\": \"Europe/Paris\"
  }" \
  --output report.xml
💡 Linux users: replace base64 -i nested-template.xml with base64 -w 0 nested-template.xml

Key parameters

Parameter Description
template Your XML template, encoded as a Base64 string.
data JSON data used to populate the template.
timezone Time zone of the dates and times printed by :formatD, like "UTC". "Europe/Paris" by default. See time zones.
lang Optional: language of the translations and of :formatN and :formatC.
convertTo Omit it: an XML template generates an XML file.
?download=true Query parameter to download the document as a stream.
Authorization Header required for the Carbone Cloud API. Get your API key here.

For more details, refer to the Carbone API Documentation.