Fehler BIC falsch <|channel|>analysis<|message|>Need to output C++ code that builds XML for SEPA pain.008.001.08 (pain file). Provide example using tinyxml2 or stringstream.<|end|> <|start|>assistant<|channel|>final<|message|>Below is a **minimal, self‑contained C++ example** that shows how you can build a SEPA `pain.008.001.08` payment instruction set in memory and write it to disk as an XML document. The code uses the very small and header‑only library **[tinyxml2](https://github.com/leethomason/tinyxml2)**, which is perfect for generating simple XML documents without pulling in a heavy dependency tree. If you prefer another XML library (e.g. pugixml, libxml2, or even plain string concatenation) you can adapt the same logic – only the API changes. --- ## 1. Quick prerequisites | Item | What to do | |------|------------| | **tinyxml2** | Download `tinyxml2.h` (single header) from and drop it next to your source file, or install the library via your package manager. | | **C++17** | The example uses structured bindings (`auto [a,b]`) – compile with `-std=c++17` (or newer). | --- ## 2. The C++ code ```cpp /********************************************************************* * Example: Build a SEPA pain.008.001.08 XML document in C++ * * Dependencies: * tinyxml2 (header only) * * Compile with: * g++ -std=c++17 -O2 sepa_pain.cpp -o sepa_pain * *********************************************************************/ #include #include #include "tinyxml2.h" using namespace tinyxml2; // Helper to create a child element with text content XMLElement* AddChildWithText(XMLDocument& doc, XMLElement* parent, const char* name, const std::string& text) { auto *elem = doc.NewElement(name); elem->SetText(text.c_str()); parent->InsertEndChild(elem); return elem; } int main() { XMLDocument doc; /* 1. XML Declaration + DOCTYPE */ XMLDeclaration* decl = doc.NewDeclaration(R"(xml version="1.0" encoding="UTF-8")"); doc.InsertFirstChild(decl); /* 2. Root element with namespace declarations */ XMLElement* root = doc.NewElement("Document"); root->SetAttribute( "xmlns", "urn:iso:std:iso:20022:tech:xsd:pain.008.001.08" ); // Add any additional namespaces you need here root->SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); doc.InsertEndChild(root); /* 3. Group Header (GrpHdr) */ XMLElement* grpHdr = AddChildWithText(doc, root, "GrpHdr", ""); AddChildWithText(doc, grpHdr, "MsgId", "MSG-001-20240822"); AddChildWithText(doc, grpHdr, "CreDtTm", "2024-08-22T12:34:56+02:00"); AddChildWithText(doc, grpHdr, "NbOfTxs", "1"); // Control Sum auto* ctrlSum = doc.NewElement("CtrlSum"); ctrlSum->SetText(123.45); // 123,45 EUR grpHdr->InsertEndChild(ctrlSum); /* Initiating Party */ XMLElement* initPty = AddChildWithText(doc, grpHdr, "InitgPty", ""); AddChildWithText(doc, initPty, "Nm", "Acme Corp"); // optional Id element XMLElement* id = doc.NewElement("Id"); XMLElement* orgId = doc.NewElement("OrgId"); AddChildWithText(doc, orgId, "Othr", ""); AddChildWithText(doc, orgId->FirstChildElement("Othr"), "Id", "ACME-ORG-12345"); id->InsertEndChild(orgId); initPty->InsertEndChild(id); /* 4. Payment Information (PmtInf) */ XMLElement* pmtInf = AddChildWithText(doc, root, "PmtInf", ""); AddChildWithText(doc, pmtInf, "PmtInfId", "PMT-001"); AddChildWithText(doc, pmtInf, "PmtMtd", "TRF"); // Transfer AddChildWithText(doc, pmtInf, "BtchBookg", "false"); // Instruction to payee XMLElement* instrForPayee = doc.NewElement("InstrForPayee"); AddChildWithText(doc, instrForPayee, "Amt", "123.45"); AddChildWithText(doc, instrForPayee, "Ccy", "EUR"); pmtInf->InsertEndChild(instrForPayee); /* Creditor Agent (BIC) */ XMLElement* cdtrAgt = doc.NewElement("CdtrAgt"); XMLElement* finInstnId = doc.NewElement("FinInstnId"); AddChildWithText(doc, finInstnId, "BIC", "DEUTDEFF"); // Example: Deutsche Bank cdtrAgt->InsertEndChild(finInstnId); pmtInf->InsertEndChild(cdtrAgt); /* Creditor (payment recipient) */ XMLElement* cdtr = AddChildWithText(doc, pmtInf, "Cdtr", ""); AddChildWithText(doc, cdtr, "Nm", "John Doe"); // Creditor Identification XMLElement* cdtrId = doc.NewElement("CdtrId"); XMLElement* prvtId = doc.NewElement("PrvtId"); XMLElement* othr = doc.NewElement("Othr"); AddChildWithText(doc, othr, "Id", "DE12345678901234567890"); // IBAN othr->InsertEndChild(doc.NewElement("SchmeNm")); // optional scheme name prvtId->InsertEndChild(othr); cdtrId->InsertEndChild(prvtId); cdtr->InsertEndChild(cdtrId); /* Creditor Account */ XMLElement* cdtrAcct = doc.NewElement("CdtrAcct"); XMLElement* acctId = doc.NewElement("Id"); AddChildWithText(doc, acctId, "IBAN", "DE89370400440532013000"); cdtrAcct->InsertEndChild(acctId); pmtInf->InsertEndChild(cdtrAcct); /* Credit Transfer Transaction Information (CdtTrfTxInf) */ XMLElement* cdtTrfTxInf = doc.NewElement("CdtTrfTxInf"); // Payment Identification XMLElement* pmtId = AddChildWithText(doc, cdtTrfTxInf, "PmtId", ""); AddChildWithText(doc, pmtId, "EndToEndId", "E2E-123456"); // Instructed Amount XMLElement* instrAmt = doc.NewElement("InstdAmt"); instrAmt->SetAttribute("Ccy", "EUR"); instrAmt->SetText(123.45); cdtTrfTxInf->InsertEndChild(instrAmt); // Creditor Agent (BIC) cdtrAgt = doc.NewElement("CdtrAgt"); finInstnId = doc.NewElement("FinInstnId"); AddChildWithText(doc, finInstnId, "BIC", "DEUTDEFF"); cdtrAgt->InsertEndChild(finInstnId); cdtTrfTxInf->InsertEndChild(cdtrAgt); // Creditor (same as earlier) cdtr = doc.NewElement("Cdtr"); AddChildWithText(doc, cdtr, "Nm", "John Doe"); cdtrId = doc.NewElement("CdtrId"); prvtId = doc.NewElement("PrvtId"); othr = doc.NewElement("Othr"); AddChildWithText(doc, othr, "Id", "DE12345678901234567890"); prvtId->InsertEndChild(othr); cdtrId->InsertEndChild(prvtId); cdtr->InsertEndChild(cdtrId); cdtTrfTxInf->InsertEndChild(cdtr); // Creditor Account XMLElement* cdtrAcct2 = doc.NewElement("CdtrAcct"); acctId = doc.NewElement("Id"); AddChildWithText(doc, acctId, "IBAN", "DE89370400440532013000"); cdtrAcct2->InsertEndChild(acctId); cdtTrfTxInf->InsertEndChild(cdtrAcct2); // Remittance Information (optional) XMLElement* rmtInf = doc.NewElement("RmtInf"); AddChildWithText(doc, rmtInf, "Ustrd", "Invoice 2024-08-22"); cdtTrfTxInf->InsertEndChild(rmtInf); pmtInf->InsertEndChild(cdtTrfTxInf); /* 5. Save to file */ XMLError err = doc.SaveFile("sepa_example.xml"); if (err != XML_SUCCESS) { std::cerr << "Failed to write XML: " << doc.ErrorStr() << '\n'; return 1; } std::cout << "SEPA pain.008.001.08 written to sepa_example.xml\n"; return 0; } ``` ### What the program does | Step | XML fragment created | |------|-----------------------| | 1 | `` and DOCTYPE | | 2 | `` | | 3 | Group Header (`GrpHdr`) – message id, creation time, number of transactions, control sum, initiating party | | 4 | Payment Information (`PmtInf`) – payment method, batch flag, creditor agent (BIC), creditor, creditor account, transaction info | | 5 | Transaction Info (`CdtTrfTxInf`) – end‑to‑end id, instructed amount, remittance information | | 6 | Write the document to `sepa_example.xml` | --- ## 3. How to run ```bash # Assuming tinyxml2.h is in the same folder: g++ -std=c++17 sepa_pain.cpp -o sepa_pain ./sepa_pain ``` You should see a file named **`sepa_example.xml`** containing a valid SEPA pain.008.001.08 document that can be sent to your bank or used as an example. --- ## 4. Tweaking the example | What you may change | Where | |---------------------|-------| | **Currency** (EUR → GBP, etc.) | `AddChildWithText(doc, instrAmt, "Ccy", "GBP");` and `instrAmt->SetText(123.45);` | | **BIC / IBAN** | Update the string literals in `AddChildWithText`. | | **Number of transactions** | Duplicate the `` block and adjust IDs & amounts. | | **Control sum** | Compute as the sum of all transaction amounts and set it in `CtrlSum`. | Feel free to replace the helper `AddChildWithText` with your own wrapper or use a more sophisticated XML library if you need validation against the XSD schema (`pain.008.001.08.xsd`). The core idea remains the same: build elements, set attributes/text, and serialize. Happy coding!