This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch feature/CAMEL-23690-camel-ubl
in repository https://gitbox.apache.org/repos/asf/camel.git

commit fb9e139fa798bad7125deba26130a1718bdc32ba
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Aug 12 12:34:03 2026 +0200

    CAMEL-23690: Add camel-ubl data format for UBL 2.1 document marshalling
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 bom/camel-bom/pom.xml                              |   5 +
 catalog/camel-allcomponents/pom.xml                |   5 +
 .../apache/camel/catalog/dataformats.properties    |   1 +
 .../org/apache/camel/catalog/dataformats/ubl.json  |  22 +++
 .../org/apache/camel/catalog/docs.properties       |   1 +
 .../apache/camel/catalog/docs/ubl-dataformat.adoc  | 193 +++++++++++++++++++++
 .../org/apache/camel/catalog/models.properties     |   1 +
 .../catalog/models/dataFormatTransformer.json      |   2 +-
 .../apache/camel/catalog/models/dataFormats.json   |   2 +-
 .../org/apache/camel/catalog/models/marshal.json   |   2 +-
 .../org/apache/camel/catalog/models/ubl.json       |  19 ++
 .../org/apache/camel/catalog/models/unmarshal.json |   2 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  25 +++
 .../apache/camel/catalog/schemas/camel-xml-io.xsd  |  29 ++++
 components/camel-ubl/pom.xml                       |  69 ++++++++
 .../component/ubl/UblDataFormatConfigurer.java     |  63 +++++++
 .../org/apache/camel/component/ubl/ubl.json        |  22 +++
 .../org/apache/camel/configurer/ubl-dataformat     |   2 +
 .../org/apache/camel/dataformat.properties         |   7 +
 .../services/org/apache/camel/dataformat/ubl       |   2 +
 .../camel-ubl/src/main/docs/ubl-dataformat.adoc    | 193 +++++++++++++++++++++
 .../apache/camel/component/ubl/UblDataFormat.java  | 141 +++++++++++++++
 .../camel/component/ubl/UblDataFormatTest.java     | 164 +++++++++++++++++
 .../camel-ubl/src/test/resources/log4j2.properties |  29 ++++
 components/pom.xml                                 |   1 +
 .../apache/camel/model/dataformat/dataFormats.json |   2 +-
 .../org/apache/camel/model/dataformat/ubl.json     |  19 ++
 .../META-INF/org/apache/camel/model/marshal.json   |   2 +-
 .../model/transformer/dataFormatTransformer.json   |   2 +-
 .../META-INF/org/apache/camel/model/unmarshal.json |   2 +-
 .../services/org/apache/camel/model.properties     |   1 +
 .../org/apache/camel/model/dataformat/jaxb.index   |   1 +
 .../camel/builder/DataFormatBuilderFactory.java    |   8 +
 .../org/apache/camel/builder/DataFormatClause.java |  19 ++
 .../org/apache/camel/model/MarshalDefinition.java  |   2 +
 .../apache/camel/model/UnmarshalDefinition.java    |   2 +
 .../model/dataformat/DataFormatsDefinition.java    |   1 +
 .../camel/model/dataformat/UblDataFormat.java      |  99 +++++++++++
 .../DataFormatTransformerDefinition.java           |   2 +
 .../reifier/dataformat/DataFormatReifier.java      |   2 +
 .../reifier/dataformat/UblDataFormatReifier.java   |  35 ++++
 .../apache/camel/java/out/JavaDslModelWriter.java  |  15 ++
 .../org/apache/camel/main/dataformats.properties   |   1 +
 .../java/org/apache/camel/xml/in/ModelParser.java  |   7 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  13 ++
 .../org/apache/camel/yaml/out/YamlModelWriter.java |  13 ++
 .../dsl/yaml/deserializers/ModelDeserializers.java |  75 ++++++++
 .../deserializers/ModelDeserializersResolver.java  |   2 +
 .../resources/schema/camelYamlDsl-canonical.json   |  33 +++-
 .../resources/schema/camelYamlDsl-model.json       |  42 +++++
 .../generated/resources/schema/camelYamlDsl.json   |  53 ++++++
 parent/pom.xml                                     |   6 +
 52 files changed, 1452 insertions(+), 9 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index c1597480fa6b..d2419f9f74ae 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -2472,6 +2472,11 @@
         <artifactId>camel-twitter</artifactId>
         <version>4.23.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-ubl</artifactId>
+        <version>4.23.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-undertow</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml 
b/catalog/camel-allcomponents/pom.xml
index 30389d69ee56..fab4a83b9ab1 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -2227,6 +2227,11 @@
             <artifactId>camel-twitter</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-ubl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-undertow</artifactId>
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties
index 1b8b6f52b65b..f1c8964b31f5 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties
@@ -46,6 +46,7 @@ swiftMx
 syslog
 tarFile
 thrift
+ubl
 univocityCsv
 univocityFixed
 univocityTsv
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/ubl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/ubl.json
new file mode 100644
index 000000000000..d2b1c533fa79
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/ubl.json
@@ -0,0 +1,22 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "ubl",
+    "title": "UBL",
+    "description": "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+    "deprecated": false,
+    "firstVersion": "4.23.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.component.ubl.UblDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ubl",
+    "version": "4.23.0-SNAPSHOT",
+    "modelName": "ubl",
+    "modelJavaType": "org.apache.camel.model.dataformat.UblDataFormat"
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node" },
+    "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty 
Print", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable pretty printing 
(formatted) output of the XML" }
+  }
+}
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
index 8d546b6b2a1e..03163011cb01 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs.properties
@@ -657,6 +657,7 @@ twilio-component
 twitter-directmessage-component
 twitter-search-component
 twitter-timeline-component
+ubl-dataformat
 undertow-component
 undertow-spring-security
 univocityCsv-dataformat
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ubl-dataformat.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ubl-dataformat.adoc
new file mode 100644
index 000000000000..4b7e84d73b74
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ubl-dataformat.adoc
@@ -0,0 +1,193 @@
+= UBL DataFormat
+:doctitle: UBL
+:shortname: ubl
+:artifactid: camel-ubl
+:description: Marshal and unmarshal UBL 2.1 (Universal Business Language) 
documents.
+:since: 4.23
+:supportlevel: Preview
+:tabs-sync-option:
+
+*Since Camel {since}*
+
+The UBL data format is used for marshalling and unmarshalling
+https://docs.oasis-open.org/ubl/UBL-2.1.html[UBL 2.1 (Universal Business 
Language)] documents.
+
+UBL 2.1 is an OASIS standard that defines XML business document types such as 
invoices,
+credit notes, orders, despatch advice, and more. It is the document format 
used by the
+https://peppol.org/[Peppol e-invoicing network] and is increasingly mandated 
across the EU
+(ViDA directive), and other countries.
+
+The data format uses the https://github.com/phax/ph-ubl[ph-ubl] library by 
Philip Helger
+as the underlying JAXB binding layer. It supports all 65 UBL 2.1 document 
types and
+auto-detects the document type from the Java class name (when marshalling) or 
from the
+XML root element (when unmarshalling).
+
+== UBL Options
+
+// dataformat options: START
+include::partial$dataformat-options.adoc[]
+// dataformat options: END
+
+== Supported Document Types
+
+The data format supports all 65 UBL 2.1 document types, including:
+
+* Invoice, CreditNote, DebitNote
+* Order, OrderResponse, OrderCancellation, OrderChange
+* DespatchAdvice, ReceiptAdvice
+* Quotation, RequestForQuotation
+* Catalogue, CatalogueRequest
+* ApplicationResponse
+* Waybill, BillOfLading, FreightInvoice
+* Statement, RemittanceAdvice, Reminder
+* and many more
+
+== Usage
+
+=== Marshalling (Java object to XML)
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:marshal")
+    .marshal().ubl()
+    .to("file:output");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:marshal"/>
+  <marshal>
+    <ubl/>
+  </marshal>
+  <to uri="file:output"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:marshal
+    steps:
+      - marshal:
+          ubl: {}
+      - to:
+          uri: file:output
+----
+====
+
+=== Unmarshalling (XML to Java object)
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:invoices")
+    .unmarshal().ubl()
+    .process(exchange -> {
+        InvoiceType invoice = exchange.getIn().getBody(InvoiceType.class);
+        String id = invoice.getIDValue();
+    });
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="file:invoices"/>
+  <unmarshal>
+    <ubl/>
+  </unmarshal>
+  <to uri="direct:process"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:invoices
+    steps:
+      - unmarshal:
+          ubl: {}
+      - to:
+          uri: direct:process
+----
+====
+
+=== With pretty printing
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+UblDataFormat ubl = new UblDataFormat();
+ubl.setPrettyPrint(true);
+
+from("direct:marshal")
+    .marshal(ubl)
+    .to("file:output");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:marshal"/>
+  <marshal>
+    <ubl prettyPrint="true"/>
+  </marshal>
+  <to uri="file:output"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:marshal
+    steps:
+      - marshal:
+          ubl:
+            prettyPrint: true
+      - to:
+          uri: file:output
+----
+====
+
+== Dependencies
+
+To use UBL in your Camel routes, you need to add the dependency on *camel-ubl*
+which implements this data format.
+
+If you use Maven, you could add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release.
+
+[source,xml]
+----------------------------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-ubl</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----------------------------------------------------------
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index e4ba73788d8e..a4ae1a15e2d6 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -214,6 +214,7 @@ transacted
 transform
 transformDataType
 transformers
+ubl
 univocityCsv
 univocityFixed
 univocityHeader
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json
index 8bb901e0ff29..b642502e9991 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json
@@ -12,7 +12,7 @@
     "output": false
   },
   "properties": {
-    "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Scheme name supported by the transformer. If specified, the 
transformer will be picked up for all from\/to transformation of this scheme. 
Scheme matching is performed only when no exactly matched transformer exists." 
},
     "name": { "index": 2, "kind": "attribute", "displayName": "Name", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Name 
under which the transformer gets referenced when specifying input\/output data 
type on routes. If the name matches a data type scheme, the transformer will be 
picked up as a fallback." },
     "fromType": { "index": 3, "kind": "attribute", "displayName": "From Type", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The source (from) data type name. If you specify 'xml:XYZ', the 
transformer is picked up when source type matches. If you specify just 'xml', 
it matches all xml source types." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json
index d3c163c836f7..d3266940b5a1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json
@@ -12,6 +12,6 @@
     "output": false
   },
   "properties": {
-    "dataFormats": { "index": 0, "kind": "element", "displayName": "Data 
Formats", "group": "common", "required": true, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ 
"asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", 
"csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...]
+    "dataFormats": { "index": 0, "kind": "element", "displayName": "Data 
Formats", "group": "common", "required": true, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ 
"asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", 
"csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json
index c1e7ae1190ef..6ef786007f20 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json
@@ -17,7 +17,7 @@
     "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
note for this node" },
     "description": { "index": 2, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The description for this node" },
     "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to disable this 
EIP from the route during build time. Once an EIP has been disabled then it 
cannot be enabled later at runtime." },
-    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "variableSend": { "index": 5, "kind": "attribute", "displayName": 
"Variable Send", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable as the source for the 
message body to send. This makes it handy to use variables for user data and to 
easily control what data to use for sending and receiving." },
     "variableReceive": { "index": 6, "kind": "attribute", "displayName": 
"Variable Receive", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable to store the received 
message body (only body, not headers). This makes it handy to use variables for 
user data and to easily control what data to use for sending and receiving." }
   }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/ubl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/ubl.json
new file mode 100644
index 000000000000..12439bb29e16
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/ubl.json
@@ -0,0 +1,19 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "ubl",
+    "title": "UBL",
+    "description": "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+    "deprecated": false,
+    "firstVersion": "4.23.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.model.dataformat.UblDataFormat",
+    "abstract": false,
+    "input": false,
+    "output": false
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node" },
+    "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty 
Print", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable pretty printing 
(formatted) output of the XML" }
+  }
+}
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json
index 1d5029f557e3..a178566ec814 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json
@@ -17,7 +17,7 @@
     "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
note for this node" },
     "description": { "index": 2, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The description for this node" },
     "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to disable this 
EIP from the route during build time. Once an EIP has been disabled then it 
cannot be enabled later at runtime." },
-    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "variableSend": { "index": 5, "kind": "attribute", "displayName": 
"Variable Send", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable as the source for the 
message body to send. This makes it handy to use variables for user data and to 
easily control what data to use for sending and receiving." },
     "variableReceive": { "index": 6, "kind": "attribute", "displayName": 
"Variable Receive", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable to store the received 
message body (only body, not headers). This makes it handy to use variables for 
user data and to easily control what data to use for sending and receiving." },
     "allowNullBody": { "index": 7, "kind": "attribute", "displayName": "Allow 
Null Body", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Indicates whether null is allowed as value of a body to unmarshall." }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 1cd46566e4b4..c9b462748301 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -2193,6 +2193,15 @@ transformers
       <xs:documentation xml:lang="en">
 <![CDATA[
 Container for defining data type transformer definitions
+]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="ubl" type="tns:ublDataFormat">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+<![CDATA[
+Marshal and unmarshal UBL 2.1 (Universal Business Language) documents.
 ]]>
       </xs:documentation>
     </xs:annotation>
@@ -15897,6 +15906,22 @@ An example value of this response header.
       </xs:choice>
     </xs:sequence>
   </xs:complexType>
+  <xs:complexType name="ublDataFormat">
+    <xs:complexContent>
+      <xs:extension base="tns:dataFormat">
+        <xs:sequence/>
+        <xs:attribute name="prettyPrint" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+Whether to enable pretty printing (formatted) output of the XML. Default 
value: false
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
   <xs:complexType name="cSimpleExpression">
     <xs:simpleContent>
       <xs:extension base="tns:typedExpressionDefinition">
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
index 3f8d4c70e701..1a4ccf14fe36 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
@@ -2004,6 +2004,15 @@ transformers
       <xs:documentation xml:lang="en">
 <![CDATA[
 Container for defining data type transformer definitions
+]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="ubl" type="tns:ublDataFormat">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+<![CDATA[
+Marshal and unmarshal UBL 2.1 (Universal Business Language) documents.
 ]]>
       </xs:documentation>
     </xs:annotation>
@@ -6212,6 +6221,7 @@ custom logic needed before the looping executes.
             <xs:element ref="tns:swiftMx"/>
             <xs:element ref="tns:syslog"/>
             <xs:element ref="tns:tarFile"/>
+            <xs:element ref="tns:ubl"/>
             <xs:element ref="tns:thrift"/>
             <xs:element ref="tns:univocityCsv"/>
             <xs:element ref="tns:univocityFixed"/>
@@ -9106,6 +9116,22 @@ Whether to preserve path elements when the file name 
contains path elements in t
 <![CDATA[
 The maximum decompressed size of a tar file (in bytes). An IOException is 
thrown if the decompressed size exceeds this
 amount. Set to -1 to disable. Default value: 1073741824
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="ublDataFormat">
+    <xs:complexContent>
+      <xs:extension base="tns:dataFormat">
+        <xs:sequence/>
+        <xs:attribute name="prettyPrint" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+Whether to enable pretty printing (formatted) output of the XML. Default 
value: false
 ]]>
             </xs:documentation>
           </xs:annotation>
@@ -13601,6 +13627,7 @@ into.
             <xs:element ref="tns:swiftMx"/>
             <xs:element ref="tns:syslog"/>
             <xs:element ref="tns:tarFile"/>
+            <xs:element ref="tns:ubl"/>
             <xs:element ref="tns:thrift"/>
             <xs:element ref="tns:univocityCsv"/>
             <xs:element ref="tns:univocityFixed"/>
@@ -15029,6 +15056,7 @@ An example value of this response header.
         <xs:element ref="tns:swiftMx"/>
         <xs:element ref="tns:syslog"/>
         <xs:element ref="tns:tarFile"/>
+        <xs:element ref="tns:ubl"/>
         <xs:element ref="tns:thrift"/>
         <xs:element ref="tns:univocityCsv"/>
         <xs:element ref="tns:univocityFixed"/>
@@ -15912,6 +15940,7 @@ matches. If you specify just 'json', it matches all 
json destination types.
             <xs:element ref="tns:swiftMx"/>
             <xs:element ref="tns:syslog"/>
             <xs:element ref="tns:tarFile"/>
+            <xs:element ref="tns:ubl"/>
             <xs:element ref="tns:thrift"/>
             <xs:element ref="tns:univocityCsv"/>
             <xs:element ref="tns:univocityFixed"/>
diff --git a/components/camel-ubl/pom.xml b/components/camel-ubl/pom.xml
new file mode 100644
index 000000000000..0963a6248455
--- /dev/null
+++ b/components/camel-ubl/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.23.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-ubl</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: UBL</name>
+    <description>Camel UBL 2.1 (Universal Business Language) data 
format</description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.helger.ubl</groupId>
+            <artifactId>ph-ubl21</artifactId>
+            <version>${ph-ubl-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-runtime</artifactId>
+        </dependency>
+
+        <!-- testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
diff --git 
a/components/camel-ubl/src/generated/java/org/apache/camel/component/ubl/UblDataFormatConfigurer.java
 
b/components/camel-ubl/src/generated/java/org/apache/camel/component/ubl/UblDataFormatConfigurer.java
new file mode 100644
index 000000000000..b0215facc924
--- /dev/null
+++ 
b/components/camel-ubl/src/generated/java/org/apache/camel/component/ubl/UblDataFormatConfigurer.java
@@ -0,0 +1,63 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.ubl;
+
+import javax.annotation.processing.Generated;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.PackageDataFormatMojo")
+@SuppressWarnings("unchecked")
+public class UblDataFormatConfigurer extends 
org.apache.camel.support.component.PropertyConfigurerSupport implements 
GeneratedPropertyConfigurer, ExtendedPropertyConfigurerGetter {
+
+    private static final Map<String, Object> ALL_OPTIONS;
+    static {
+        Map<String, Object> map = new CaseInsensitiveMap();
+        map.put("PrettyPrint", boolean.class);
+        ALL_OPTIONS = map;
+    }
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
+        UblDataFormat target = (UblDataFormat) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "prettyprint":
+        case "prettyPrint": target.setPrettyPrint(property(camelContext, 
boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Map<String, Object> getAllOptions(Object target) {
+        return ALL_OPTIONS;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "prettyprint":
+        case "prettyPrint": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        UblDataFormat target = (UblDataFormat) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "prettyprint":
+        case "prettyPrint": return target.isPrettyPrint();
+        default: return null;
+        }
+    }
+}
+
diff --git 
a/components/camel-ubl/src/generated/resources/META-INF/org/apache/camel/component/ubl/ubl.json
 
b/components/camel-ubl/src/generated/resources/META-INF/org/apache/camel/component/ubl/ubl.json
new file mode 100644
index 000000000000..d2b1c533fa79
--- /dev/null
+++ 
b/components/camel-ubl/src/generated/resources/META-INF/org/apache/camel/component/ubl/ubl.json
@@ -0,0 +1,22 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "ubl",
+    "title": "UBL",
+    "description": "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+    "deprecated": false,
+    "firstVersion": "4.23.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.component.ubl.UblDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ubl",
+    "version": "4.23.0-SNAPSHOT",
+    "modelName": "ubl",
+    "modelJavaType": "org.apache.camel.model.dataformat.UblDataFormat"
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node" },
+    "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty 
Print", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable pretty printing 
(formatted) output of the XML" }
+  }
+}
diff --git 
a/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/configurer/ubl-dataformat
 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/configurer/ubl-dataformat
new file mode 100644
index 000000000000..cd681bf5d751
--- /dev/null
+++ 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/configurer/ubl-dataformat
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.ubl.UblDataFormatConfigurer
diff --git 
a/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
new file mode 100644
index 000000000000..01a5cbbb87e2
--- /dev/null
+++ 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+dataFormats=ubl
+groupId=org.apache.camel
+artifactId=camel-ubl
+version=4.23.0-SNAPSHOT
+projectName=Camel :: UBL
+projectDescription=Camel UBL 2.1 (Universal Business Language) data format
diff --git 
a/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat/ubl
 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat/ubl
new file mode 100644
index 000000000000..6c825f31bce7
--- /dev/null
+++ 
b/components/camel-ubl/src/generated/resources/META-INF/services/org/apache/camel/dataformat/ubl
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.ubl.UblDataFormat
diff --git a/components/camel-ubl/src/main/docs/ubl-dataformat.adoc 
b/components/camel-ubl/src/main/docs/ubl-dataformat.adoc
new file mode 100644
index 000000000000..4b7e84d73b74
--- /dev/null
+++ b/components/camel-ubl/src/main/docs/ubl-dataformat.adoc
@@ -0,0 +1,193 @@
+= UBL DataFormat
+:doctitle: UBL
+:shortname: ubl
+:artifactid: camel-ubl
+:description: Marshal and unmarshal UBL 2.1 (Universal Business Language) 
documents.
+:since: 4.23
+:supportlevel: Preview
+:tabs-sync-option:
+
+*Since Camel {since}*
+
+The UBL data format is used for marshalling and unmarshalling
+https://docs.oasis-open.org/ubl/UBL-2.1.html[UBL 2.1 (Universal Business 
Language)] documents.
+
+UBL 2.1 is an OASIS standard that defines XML business document types such as 
invoices,
+credit notes, orders, despatch advice, and more. It is the document format 
used by the
+https://peppol.org/[Peppol e-invoicing network] and is increasingly mandated 
across the EU
+(ViDA directive), and other countries.
+
+The data format uses the https://github.com/phax/ph-ubl[ph-ubl] library by 
Philip Helger
+as the underlying JAXB binding layer. It supports all 65 UBL 2.1 document 
types and
+auto-detects the document type from the Java class name (when marshalling) or 
from the
+XML root element (when unmarshalling).
+
+== UBL Options
+
+// dataformat options: START
+include::partial$dataformat-options.adoc[]
+// dataformat options: END
+
+== Supported Document Types
+
+The data format supports all 65 UBL 2.1 document types, including:
+
+* Invoice, CreditNote, DebitNote
+* Order, OrderResponse, OrderCancellation, OrderChange
+* DespatchAdvice, ReceiptAdvice
+* Quotation, RequestForQuotation
+* Catalogue, CatalogueRequest
+* ApplicationResponse
+* Waybill, BillOfLading, FreightInvoice
+* Statement, RemittanceAdvice, Reminder
+* and many more
+
+== Usage
+
+=== Marshalling (Java object to XML)
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:marshal")
+    .marshal().ubl()
+    .to("file:output");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:marshal"/>
+  <marshal>
+    <ubl/>
+  </marshal>
+  <to uri="file:output"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:marshal
+    steps:
+      - marshal:
+          ubl: {}
+      - to:
+          uri: file:output
+----
+====
+
+=== Unmarshalling (XML to Java object)
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("file:invoices")
+    .unmarshal().ubl()
+    .process(exchange -> {
+        InvoiceType invoice = exchange.getIn().getBody(InvoiceType.class);
+        String id = invoice.getIDValue();
+    });
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="file:invoices"/>
+  <unmarshal>
+    <ubl/>
+  </unmarshal>
+  <to uri="direct:process"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:invoices
+    steps:
+      - unmarshal:
+          ubl: {}
+      - to:
+          uri: direct:process
+----
+====
+
+=== With pretty printing
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+UblDataFormat ubl = new UblDataFormat();
+ubl.setPrettyPrint(true);
+
+from("direct:marshal")
+    .marshal(ubl)
+    .to("file:output");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="direct:marshal"/>
+  <marshal>
+    <ubl prettyPrint="true"/>
+  </marshal>
+  <to uri="file:output"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:marshal
+    steps:
+      - marshal:
+          ubl:
+            prettyPrint: true
+      - to:
+          uri: file:output
+----
+====
+
+== Dependencies
+
+To use UBL in your Camel routes, you need to add the dependency on *camel-ubl*
+which implements this data format.
+
+If you use Maven, you could add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release.
+
+[source,xml]
+----------------------------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-ubl</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----------------------------------------------------------
diff --git 
a/components/camel-ubl/src/main/java/org/apache/camel/component/ubl/UblDataFormat.java
 
b/components/camel-ubl/src/main/java/org/apache/camel/component/ubl/UblDataFormat.java
new file mode 100644
index 000000000000..c77c34c42df6
--- /dev/null
+++ 
b/components/camel-ubl/src/main/java/org/apache/camel/component/ubl/UblDataFormat.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.ubl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+
+import com.helger.jaxb.GenericJAXBMarshaller;
+import com.helger.ubl21.UBL21Marshaller;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.CamelExchangeException;
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatName;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Dataformat;
+import org.apache.camel.support.service.ServiceSupport;
+
+/**
+ * Marshal and unmarshal UBL 2.1 (Universal Business Language) documents using 
the
+ * <a href="https://github.com/phax/ph-ubl";>ph-ubl</a> library.
+ */
+@Dataformat("ubl")
+@Metadata(firstVersion = "4.23.0", title = "UBL")
+public class UblDataFormat extends ServiceSupport implements DataFormat, 
DataFormatName, CamelContextAware {
+
+    private CamelContext camelContext;
+    private boolean prettyPrint;
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public String getDataFormatName() {
+        return "ubl";
+    }
+
+    @Override
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) 
throws Exception {
+        String className = graph.getClass().getSimpleName();
+        if (!className.endsWith("Type")) {
+            throw new CamelExchangeException(
+                    "Unsupported UBL document type: " + 
graph.getClass().getName()
+                                             + ". Expected a UBL 2.1 JAXB type 
(e.g. InvoiceType, CreditNoteType)",
+                    exchange);
+        }
+        String docName = className.substring(0, className.length() - 4);
+        String methodName = Character.toLowerCase(docName.charAt(0)) + 
docName.substring(1);
+
+        GenericJAXBMarshaller marshaller = lookupMarshaller(methodName, 
exchange);
+        marshaller.setFormattedOutput(prettyPrint);
+        marshaller.setUseSchema(false);
+        byte[] bytes = marshaller.getAsBytes(graph);
+        if (bytes == null) {
+            throw new CamelExchangeException("Failed to marshal UBL document 
of type " + className, exchange);
+        }
+        stream.write(bytes);
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws 
Exception {
+        byte[] data = stream.readAllBytes();
+
+        String localName = peekRootElement(data, exchange);
+        String methodName = Character.toLowerCase(localName.charAt(0)) + 
localName.substring(1);
+
+        GenericJAXBMarshaller<?> marshaller = lookupMarshaller(methodName, 
exchange);
+        marshaller.setUseSchema(false);
+        Object result = marshaller.read(new ByteArrayInputStream(data));
+        if (result == null) {
+            throw new CamelExchangeException("Failed to unmarshal UBL document 
with root element: " + localName, exchange);
+        }
+        return result;
+    }
+
+    private GenericJAXBMarshaller<?> lookupMarshaller(String methodName, 
Exchange exchange) throws Exception {
+        try {
+            Method method = UBL21Marshaller.class.getMethod(methodName);
+            return (GenericJAXBMarshaller<?>) method.invoke(null);
+        } catch (NoSuchMethodException e) {
+            throw new CamelExchangeException(
+                    "No UBL 2.1 marshaller found for: " + methodName
+                                             + ". Ensure the document type is 
a valid UBL 2.1 type.",
+                    exchange);
+        }
+    }
+
+    private static String peekRootElement(byte[] data, Exchange exchange) 
throws Exception {
+        XMLInputFactory factory = XMLInputFactory.newInstance();
+        factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, 
false);
+        factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+        XMLStreamReader reader = factory.createXMLStreamReader(new 
ByteArrayInputStream(data));
+        try {
+            while (reader.hasNext()) {
+                if (reader.next() == XMLStreamConstants.START_ELEMENT) {
+                    return reader.getLocalName();
+                }
+            }
+            throw new CamelExchangeException("No root element found in UBL 
document", exchange);
+        } finally {
+            reader.close();
+        }
+    }
+
+    public boolean isPrettyPrint() {
+        return prettyPrint;
+    }
+
+    public void setPrettyPrint(boolean prettyPrint) {
+        this.prettyPrint = prettyPrint;
+    }
+}
diff --git 
a/components/camel-ubl/src/test/java/org/apache/camel/component/ubl/UblDataFormatTest.java
 
b/components/camel-ubl/src/test/java/org/apache/camel/component/ubl/UblDataFormatTest.java
new file mode 100644
index 000000000000..148ba4fb44ef
--- /dev/null
+++ 
b/components/camel-ubl/src/test/java/org/apache/camel/component/ubl/UblDataFormatTest.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.ubl;
+
+import 
oasis.names.specification.ubl.schema.xsd.commonbasiccomponents_21.IDType;
+import 
oasis.names.specification.ubl.schema.xsd.commonbasiccomponents_21.InvoiceTypeCodeType;
+import oasis.names.specification.ubl.schema.xsd.creditnote_21.CreditNoteType;
+import oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType;
+import oasis.names.specification.ubl.schema.xsd.order_21.OrderType;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class UblDataFormatTest extends CamelTestSupport {
+
+    @Test
+    void testMarshalAndUnmarshalInvoice() throws Exception {
+        InvoiceType invoice = createTestInvoice();
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(InvoiceType.class);
+
+        String xml = template.requestBody("direct:marshal", invoice, 
String.class);
+        assertThat(xml).contains("<Invoice");
+        assertThat(xml).contains("INV-001");
+
+        template.sendBody("direct:unmarshal", xml);
+        mock.assertIsSatisfied();
+
+        InvoiceType result = 
mock.getExchanges().get(0).getIn().getBody(InvoiceType.class);
+        assertThat(result.getIDValue()).isEqualTo("INV-001");
+        assertThat(result.getInvoiceTypeCodeValue()).isEqualTo("380");
+    }
+
+    @Test
+    void testMarshalAndUnmarshalCreditNote() throws Exception {
+        CreditNoteType creditNote = new CreditNoteType();
+        IDType id = new IDType();
+        id.setValue("CN-001");
+        creditNote.setID(id);
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(CreditNoteType.class);
+
+        String xml = template.requestBody("direct:marshal", creditNote, 
String.class);
+        assertThat(xml).contains("<CreditNote");
+        assertThat(xml).contains("CN-001");
+
+        template.sendBody("direct:unmarshal", xml);
+        mock.assertIsSatisfied();
+
+        CreditNoteType result = 
mock.getExchanges().get(0).getIn().getBody(CreditNoteType.class);
+        assertThat(result.getIDValue()).isEqualTo("CN-001");
+    }
+
+    @Test
+    void testMarshalAndUnmarshalOrder() throws Exception {
+        OrderType order = new OrderType();
+        IDType id = new IDType();
+        id.setValue("ORD-001");
+        order.setID(id);
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(OrderType.class);
+
+        String xml = template.requestBody("direct:marshal", order, 
String.class);
+        assertThat(xml).contains("<Order");
+        assertThat(xml).contains("ORD-001");
+
+        template.sendBody("direct:unmarshal", xml);
+        mock.assertIsSatisfied();
+
+        OrderType result = 
mock.getExchanges().get(0).getIn().getBody(OrderType.class);
+        assertThat(result.getIDValue()).isEqualTo("ORD-001");
+    }
+
+    @Test
+    void testUnmarshalFromXml() throws Exception {
+        String xml = """
+                <?xml version="1.0" encoding="UTF-8"?>
+                <Invoice 
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
+                         
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
+                    <cbc:ID>TEST-999</cbc:ID>
+                    <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
+                </Invoice>
+                """;
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(InvoiceType.class);
+
+        template.sendBody("direct:unmarshal", xml);
+        mock.assertIsSatisfied();
+
+        InvoiceType result = 
mock.getExchanges().get(0).getIn().getBody(InvoiceType.class);
+        assertThat(result.getIDValue()).isEqualTo("TEST-999");
+    }
+
+    @Test
+    void testMarshalWithPrettyPrint() throws Exception {
+        InvoiceType invoice = createTestInvoice();
+
+        String xml = template.requestBody("direct:marshalPretty", invoice, 
String.class);
+        assertThat(xml).contains("<Invoice");
+        assertThat(xml).contains("INV-001");
+        assertThat(xml).contains("\n");
+    }
+
+    @Test
+    void testMarshalUnsupportedType() {
+        assertThatThrownBy(() -> template.requestBody("direct:marshal", "not a 
UBL type", String.class))
+                .isInstanceOf(CamelExecutionException.class)
+                .rootCause()
+                .hasMessageContaining("Unsupported UBL document type");
+    }
+
+    private InvoiceType createTestInvoice() {
+        InvoiceType invoice = new InvoiceType();
+
+        IDType id = new IDType();
+        id.setValue("INV-001");
+        invoice.setID(id);
+
+        InvoiceTypeCodeType typeCode = new InvoiceTypeCodeType();
+        typeCode.setValue("380");
+        invoice.setInvoiceTypeCode(typeCode);
+
+        return invoice;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:marshal").marshal().ubl();
+                from("direct:marshalPretty").marshal().ubl(true);
+                from("direct:unmarshal").unmarshal().ubl().to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-ubl/src/test/resources/log4j2.properties 
b/components/camel-ubl/src/test/resources/log4j2.properties
new file mode 100644
index 000000000000..267fecc0a574
--- /dev/null
+++ b/components/camel-ubl/src/test/resources/log4j2.properties
@@ -0,0 +1,29 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-ubl-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components/pom.xml b/components/pom.xml
index c96b5dc82b31..e5c3970408dc 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -332,6 +332,7 @@
         <module>camel-tika</module>
         <module>camel-twilio</module>
         <module>camel-twitter</module>
+        <module>camel-ubl</module>
         <module>camel-univocity-parsers</module>
         <module>camel-velocity</module>
         <module>camel-vertx</module>
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json
index d3c163c836f7..d3266940b5a1 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json
@@ -12,6 +12,6 @@
     "output": false
   },
   "properties": {
-    "dataFormats": { "index": 0, "kind": "element", "displayName": "Data 
Formats", "group": "common", "required": true, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ 
"asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", 
"csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...]
+    "dataFormats": { "index": 0, "kind": "element", "displayName": "Data 
Formats", "group": "common", "required": true, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ 
"asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", 
"csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...]
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/ubl.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/ubl.json
new file mode 100644
index 000000000000..12439bb29e16
--- /dev/null
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/ubl.json
@@ -0,0 +1,19 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "ubl",
+    "title": "UBL",
+    "description": "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+    "deprecated": false,
+    "firstVersion": "4.23.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.model.dataformat.UblDataFormat",
+    "abstract": false,
+    "input": false,
+    "output": false
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node" },
+    "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty 
Print", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable pretty printing 
(formatted) output of the XML" }
+  }
+}
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json
index c1e7ae1190ef..6ef786007f20 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json
@@ -17,7 +17,7 @@
     "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
note for this node" },
     "description": { "index": 2, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The description for this node" },
     "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to disable this 
EIP from the route during build time. Once an EIP has been disabled then it 
cannot be enabled later at runtime." },
-    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "variableSend": { "index": 5, "kind": "attribute", "displayName": 
"Variable Send", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable as the source for the 
message body to send. This makes it handy to use variables for user data and to 
easily control what data to use for sending and receiving." },
     "variableReceive": { "index": 6, "kind": "attribute", "displayName": 
"Variable Receive", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable to store the received 
message body (only body, not headers). This makes it handy to use variables for 
user data and to easily control what data to use for sending and receiving." }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json
index 8bb901e0ff29..b642502e9991 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json
@@ -12,7 +12,7 @@
     "output": false
   },
   "properties": {
-    "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Scheme name supported by the transformer. If specified, the 
transformer will be picked up for all from\/to transformation of this scheme. 
Scheme matching is performed only when no exactly matched transformer exists." 
},
     "name": { "index": 2, "kind": "attribute", "displayName": "Name", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Name 
under which the transformer gets referenced when specifying input\/output data 
type on routes. If the name matches a data type scheme, the transformer will be 
picked up as a fallback." },
     "fromType": { "index": 3, "kind": "attribute", "displayName": "From Type", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The source (from) data type name. If you specify 'xml:XYZ', the 
transformer is picked up when source type matches. If you specify just 'xml', 
it matches all xml source types." },
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json
index 1d5029f557e3..a178566ec814 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json
@@ -17,7 +17,7 @@
     "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
note for this node" },
     "description": { "index": 2, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The description for this node" },
     "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to disable this 
EIP from the route during build time. Once an EIP has been disabled then it 
cannot be enabled later at runtime." },
-    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
+    "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data 
Format Type", "group": "common", "required": true, "type": "object", 
"javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", 
"avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", 
"custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", 
"jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...]
     "variableSend": { "index": 5, "kind": "attribute", "displayName": 
"Variable Send", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable as the source for the 
message body to send. This makes it handy to use variables for user data and to 
easily control what data to use for sending and receiving." },
     "variableReceive": { "index": 6, "kind": "attribute", "displayName": 
"Variable Receive", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a variable to store the received 
message body (only body, not headers). This makes it handy to use variables for 
user data and to easily control what data to use for sending and receiving." },
     "allowNullBody": { "index": 7, "kind": "attribute", "displayName": "Allow 
Null Body", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Indicates whether null is allowed as value of a body to unmarshall." }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
 
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index b03ebb5e461b..e230d8d32d78 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -215,6 +215,7 @@ transacted
 transform
 transformDataType
 transformers
+ubl
 univocityCsv
 univocityFixed
 univocityHeader
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index
index 70e177bf1ccb..ac4a0d5e2669 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index
@@ -45,6 +45,7 @@ SwiftMxDataFormat
 SyslogDataFormat
 TarFileDataFormat
 ThriftDataFormat
+UblDataFormat
 UniVocityCsvDataFormat
 UniVocityFixedDataFormat
 UniVocityHeader
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java
index 86944ac799d3..f67d83dcafd9 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java
@@ -57,6 +57,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
 import org.apache.camel.model.dataformat.UniVocityTsvDataFormat;
@@ -350,6 +351,13 @@ public final class DataFormatBuilderFactory {
         return new TarFileDataFormat.Builder();
     }
 
+    /**
+     * Uses the UBL (Universal Business Language) 2.1 data format
+     */
+    public UblDataFormat.Builder ubl() {
+        return new UblDataFormat.Builder();
+    }
+
     /**
      * Uses the Thrift data format
      */
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
index c3ca1584515e..0caa1b9584df 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.XMLSecurityDataFormat;
 import org.apache.camel.model.dataformat.YAMLDataFormat;
 import org.apache.camel.model.dataformat.YAMLLibrary;
@@ -1094,6 +1095,24 @@ public class DataFormatClause<T extends 
ProcessorDefinition<?>> {
         return dataFormat(new ThriftDataFormat(instanceClassName, 
contentTypeFormat));
     }
 
+    /**
+     * Uses the UBL (Universal Business Language) 2.1 data format
+     */
+    public T ubl() {
+        return dataFormat(new UblDataFormat());
+    }
+
+    /**
+     * Uses the UBL (Universal Business Language) 2.1 data format
+     *
+     * @param prettyPrint turn pretty printing on or off
+     */
+    public T ubl(boolean prettyPrint) {
+        UblDataFormat ublDataFormat = new UblDataFormat();
+        ublDataFormat.setPrettyPrint(Boolean.toString(prettyPrint));
+        return dataFormat(ublDataFormat);
+    }
+
     /**
      * Uses the YAML data format
      *
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java
index 564cdef59f92..3ea99f9db77b 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
 import org.apache.camel.model.dataformat.UniVocityTsvDataFormat;
@@ -124,6 +125,7 @@ public class MarshalDefinition extends 
NoOutputDefinition<MarshalDefinition> imp
             @XmlElement(name = "swiftMx", type = SwiftMxDataFormat.class),
             @XmlElement(name = "syslog", type = SyslogDataFormat.class),
             @XmlElement(name = "tarFile", type = TarFileDataFormat.class),
+            @XmlElement(name = "ubl", type = UblDataFormat.class),
             @XmlElement(name = "thrift", type = ThriftDataFormat.class),
             @XmlElement(name = "univocityCsv", type = 
UniVocityCsvDataFormat.class),
             @XmlElement(name = "univocityFixed", type = 
UniVocityFixedDataFormat.class),
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
index af21f4f5c5e4..5b1f378df019 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
 import org.apache.camel.model.dataformat.UniVocityTsvDataFormat;
@@ -124,6 +125,7 @@ public class UnmarshalDefinition extends 
NoOutputDefinition<UnmarshalDefinition>
             @XmlElement(name = "swiftMx", type = SwiftMxDataFormat.class),
             @XmlElement(name = "syslog", type = SyslogDataFormat.class),
             @XmlElement(name = "tarFile", type = TarFileDataFormat.class),
+            @XmlElement(name = "ubl", type = UblDataFormat.class),
             @XmlElement(name = "thrift", type = ThriftDataFormat.class),
             @XmlElement(name = "univocityCsv", type = 
UniVocityCsvDataFormat.class),
             @XmlElement(name = "univocityFixed", type = 
UniVocityFixedDataFormat.class),
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
index ba1f05f849e1..0b9a7c5ea834 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
@@ -85,6 +85,7 @@ public class DataFormatsDefinition implements 
CopyableDefinition<DataFormatsDefi
             @XmlElement(name = "swiftMx", type = SwiftMxDataFormat.class),
             @XmlElement(name = "syslog", type = SyslogDataFormat.class),
             @XmlElement(name = "tarFile", type = TarFileDataFormat.class),
+            @XmlElement(name = "ubl", type = UblDataFormat.class),
             @XmlElement(name = "thrift", type = ThriftDataFormat.class),
             @XmlElement(name = "univocityCsv", type = 
UniVocityCsvDataFormat.class),
             @XmlElement(name = "univocityFixed", type = 
UniVocityFixedDataFormat.class),
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/UblDataFormat.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/UblDataFormat.java
new file mode 100644
index 000000000000..f4528248ae2c
--- /dev/null
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/UblDataFormat.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.model.dataformat;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlRootElement;
+import jakarta.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.builder.DataFormatBuilder;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Marshal and unmarshal UBL 2.1 (Universal Business Language) documents.
+ */
+@Metadata(firstVersion = "4.23.0", label = "dataformat,transformation,xml", 
title = "UBL",
+          description = "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.")
+@XmlRootElement(name = "ubl")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class UblDataFormat extends DataFormatDefinition {
+
+    @XmlAttribute
+    @Metadata(description = "Whether to enable pretty printing (formatted) 
output of the XML", defaultValue = "false",
+              javaType = "java.lang.Boolean")
+    private String prettyPrint;
+
+    public UblDataFormat() {
+        super("ubl");
+    }
+
+    public UblDataFormat(UblDataFormat source) {
+        super(source);
+        this.prettyPrint = source.prettyPrint;
+    }
+
+    private UblDataFormat(Builder builder) {
+        this();
+        this.prettyPrint = builder.prettyPrint;
+    }
+
+    @Override
+    public UblDataFormat copyDefinition() {
+        return new UblDataFormat(this);
+    }
+
+    public String getPrettyPrint() {
+        return prettyPrint;
+    }
+
+    public void setPrettyPrint(String prettyPrint) {
+        this.prettyPrint = prettyPrint;
+    }
+
+    /**
+     * {@code Builder} is a specific builder for {@link UblDataFormat}.
+     */
+    @XmlTransient
+    public static class Builder implements DataFormatBuilder<UblDataFormat> {
+
+        private String prettyPrint;
+
+        /**
+         * Whether to enable pretty printing (formatted) output of the XML.
+         */
+        public Builder prettyPrint(String prettyPrint) {
+            this.prettyPrint = prettyPrint;
+            return this;
+        }
+
+        /**
+         * Whether to enable pretty printing (formatted) output of the XML.
+         */
+        public Builder prettyPrint(boolean prettyPrint) {
+            this.prettyPrint = Boolean.toString(prettyPrint);
+            return this;
+        }
+
+        @Override
+        public UblDataFormat end() {
+            return new UblDataFormat(this);
+        }
+    }
+}
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
index cd1013765daf..57e5f67ae6d4 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
 import org.apache.camel.model.dataformat.UniVocityTsvDataFormat;
@@ -125,6 +126,7 @@ public class DataFormatTransformerDefinition extends 
TransformerDefinition {
             @XmlElement(name = "swiftMx", type = SwiftMxDataFormat.class),
             @XmlElement(name = "syslog", type = SyslogDataFormat.class),
             @XmlElement(name = "tarFile", type = TarFileDataFormat.class),
+            @XmlElement(name = "ubl", type = UblDataFormat.class),
             @XmlElement(name = "thrift", type = ThriftDataFormat.class),
             @XmlElement(name = "univocityCsv", type = 
UniVocityCsvDataFormat.class),
             @XmlElement(name = "univocityFixed", type = 
UniVocityFixedDataFormat.class),
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java
index 84a6ca6f191e..c47fe3cdc82f 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java
@@ -214,6 +214,8 @@ public abstract class DataFormatReifier<T extends 
DataFormatDefinition> extends
             return new SwiftMxDataFormatReifier(camelContext, definition);
         } else if (definition instanceof TarFileDataFormat) {
             return new TarFileDataFormatReifier(camelContext, definition);
+        } else if (definition instanceof UblDataFormat) {
+            return new UblDataFormatReifier(camelContext, definition);
         } else if (definition instanceof ThriftDataFormat) {
             return new ThriftDataFormatReifier(camelContext, definition);
         } else if (definition instanceof UniVocityCsvDataFormat) {
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/UblDataFormatReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/UblDataFormatReifier.java
new file mode 100644
index 000000000000..b508f4967442
--- /dev/null
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/UblDataFormatReifier.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.reifier.dataformat;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.model.dataformat.UblDataFormat;
+
+public class UblDataFormatReifier extends DataFormatReifier<UblDataFormat> {
+
+    public UblDataFormatReifier(CamelContext camelContext, 
DataFormatDefinition definition) {
+        super(camelContext, (UblDataFormat) definition);
+    }
+
+    @Override
+    protected void prepareDataFormatConfig(Map<String, Object> properties) {
+        properties.put("prettyPrint", definition.getPrettyPrint());
+    }
+}
diff --git 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
index e2721cac9660..dd67911afc84 100644
--- 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
+++ 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
@@ -1111,6 +1111,13 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
         doWriteThriftDataFormat(sb, def);
         return sb.toString();
     }
+    public String writeUblDataFormat(UblDataFormat def) {
+        resetState();
+        StringBuilder sb = new StringBuilder();
+        beginStep(sb, "ubl", def);
+        doWriteUblDataFormat(sb, def);
+        return sb.toString();
+    }
     public String writeUniVocityCsvDataFormat(UniVocityCsvDataFormat def) {
         resetState();
         StringBuilder sb = new StringBuilder();
@@ -2081,6 +2088,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(sb, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(sb, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(sb, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(sb, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(sb, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(sb, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(sb, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
@@ -2704,6 +2712,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(sb, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(sb, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(sb, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(sb, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(sb, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(sb, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(sb, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
@@ -2982,6 +2991,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
                     case "SwiftMxDataFormat" -> doWriteChildElement(sb, 
"swiftMx", (SwiftMxDataFormat) item, this::doWriteSwiftMxDataFormat);
                     case "SyslogDataFormat" -> doWriteChildElement(sb, 
"syslog", (SyslogDataFormat) item, this::doWriteSyslogDataFormat);
                     case "TarFileDataFormat" -> doWriteChildElement(sb, 
"tarFile", (TarFileDataFormat) item, this::doWriteTarFileDataFormat);
+                    case "UblDataFormat" -> doWriteChildElement(sb, "ubl", 
(UblDataFormat) item, this::doWriteUblDataFormat);
                     case "ThriftDataFormat" -> doWriteChildElement(sb, 
"thrift", (ThriftDataFormat) item, this::doWriteThriftDataFormat);
                     case "UniVocityCsvDataFormat" -> doWriteChildElement(sb, 
"univocityCsv", (UniVocityCsvDataFormat) item, 
this::doWriteUniVocityCsvDataFormat);
                     case "UniVocityFixedDataFormat" -> doWriteChildElement(sb, 
"univocityFixed", (UniVocityFixedDataFormat) item, 
this::doWriteUniVocityFixedDataFormat);
@@ -3279,6 +3289,10 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
         doWriteAttribute(sb, "contentTypeFormat", def.getContentTypeFormat(), 
"binary");
         doWriteAttribute(sb, "contentTypeHeader", def.getContentTypeHeader(), 
"true");
     }
+    protected void doWriteUblDataFormat(StringBuilder sb, UblDataFormat def) {
+        doWriteIdentifiedTypeAttributes(sb, def);
+        doWriteAttribute(sb, "prettyPrint", def.getPrettyPrint(), "false");
+    }
     protected void doWriteUniVocityAbstractDataFormatAttributes(StringBuilder 
sb, UniVocityAbstractDataFormat def) {
         doWriteIdentifiedTypeAttributes(sb, def);
         doWriteAttribute(sb, "headerExtractionEnabled", 
def.getHeaderExtractionEnabled(), null);
@@ -3932,6 +3946,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(sb, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(sb, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(sb, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(sb, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(sb, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(sb, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(sb, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
diff --git 
a/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties
 
b/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties
index 1b8b6f52b65b..f1c8964b31f5 100644
--- 
a/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties
+++ 
b/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties
@@ -46,6 +46,7 @@ swiftMx
 syslog
 tarFile
 thrift
+ubl
 univocityCsv
 univocityFixed
 univocityTsv
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 44745bdfdcdd..bca806445151 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -2065,6 +2065,12 @@ public class ModelParser extends BaseParser {
                 default: yield identifiedTypeAttributeHandler().accept(def, 
key, val);
             }, noElementHandler(), noValueHandler());
     }
+    protected UblDataFormat doParseUblDataFormat() throws IOException, 
XmlPullParserException {
+        return doParse(new UblDataFormat(), (def, key, val) -> switch (key) {
+                case "prettyPrint": def.setPrettyPrint(val); yield true;
+                default: yield identifiedTypeAttributeHandler().accept(def, 
key, val);
+            }, noElementHandler(), noValueHandler());
+    }
     protected UniVocityCsvDataFormat doParseUniVocityCsvDataFormat() throws 
IOException, XmlPullParserException {
         return doParse(new UniVocityCsvDataFormat(), (def, key, val) -> switch 
(key) {
                 case "delimiter": def.setDelimiter(val); yield true;
@@ -2868,6 +2874,7 @@ public class ModelParser extends BaseParser {
             case "syslog": return doParseSyslogDataFormat();
             case "tarFile": return doParseTarFileDataFormat();
             case "thrift": return doParseThriftDataFormat();
+            case "ubl": return doParseUblDataFormat();
             case "univocityCsv": return doParseUniVocityCsvDataFormat();
             case "univocityFixed": return doParseUniVocityFixedDataFormat();
             case "univocityTsv": return doParseUniVocityTsvDataFormat();
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index d848dc156bf0..3f664175a3f2 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -512,6 +512,9 @@ public class ModelWriter extends BaseWriter {
     public void writeThriftDataFormat(ThriftDataFormat def) throws IOException 
{
         doWriteThriftDataFormat("thrift", def);
     }
+    public void writeUblDataFormat(UblDataFormat def) throws IOException {
+        doWriteUblDataFormat("ubl", def);
+    }
     public void writeUniVocityCsvDataFormat(UniVocityCsvDataFormat def) throws 
IOException {
         doWriteUniVocityCsvDataFormat("univocityCsv", def);
     }
@@ -1212,6 +1215,7 @@ public class ModelWriter extends BaseWriter {
                 case "SwiftMxDataFormat" -> 
doWriteSwiftMxDataFormat("swiftMx", (SwiftMxDataFormat) v);
                 case "SyslogDataFormat" -> doWriteSyslogDataFormat("syslog", 
(SyslogDataFormat) v);
                 case "TarFileDataFormat" -> 
doWriteTarFileDataFormat("tarFile", (TarFileDataFormat) v);
+                case "UblDataFormat" -> doWriteUblDataFormat("ubl", 
(UblDataFormat) v);
                 case "ThriftDataFormat" -> doWriteThriftDataFormat("thrift", 
(ThriftDataFormat) v);
                 case "UniVocityCsvDataFormat" -> 
doWriteUniVocityCsvDataFormat("univocityCsv", (UniVocityCsvDataFormat) v);
                 case "UniVocityFixedDataFormat" -> 
doWriteUniVocityFixedDataFormat("univocityFixed", (UniVocityFixedDataFormat) v);
@@ -1989,6 +1993,7 @@ public class ModelWriter extends BaseWriter {
                 case "SwiftMxDataFormat" -> 
doWriteSwiftMxDataFormat("swiftMx", (SwiftMxDataFormat) v);
                 case "SyslogDataFormat" -> doWriteSyslogDataFormat("syslog", 
(SyslogDataFormat) v);
                 case "TarFileDataFormat" -> 
doWriteTarFileDataFormat("tarFile", (TarFileDataFormat) v);
+                case "UblDataFormat" -> doWriteUblDataFormat("ubl", 
(UblDataFormat) v);
                 case "ThriftDataFormat" -> doWriteThriftDataFormat("thrift", 
(ThriftDataFormat) v);
                 case "UniVocityCsvDataFormat" -> 
doWriteUniVocityCsvDataFormat("univocityCsv", (UniVocityCsvDataFormat) v);
                 case "UniVocityFixedDataFormat" -> 
doWriteUniVocityFixedDataFormat("univocityFixed", (UniVocityFixedDataFormat) v);
@@ -2318,6 +2323,7 @@ public class ModelWriter extends BaseWriter {
                 case "SwiftMxDataFormat" -> 
doWriteSwiftMxDataFormat("swiftMx", (SwiftMxDataFormat) v);
                 case "SyslogDataFormat" -> doWriteSyslogDataFormat("syslog", 
(SyslogDataFormat) v);
                 case "TarFileDataFormat" -> 
doWriteTarFileDataFormat("tarFile", (TarFileDataFormat) v);
+                case "UblDataFormat" -> doWriteUblDataFormat("ubl", 
(UblDataFormat) v);
                 case "ThriftDataFormat" -> doWriteThriftDataFormat("thrift", 
(ThriftDataFormat) v);
                 case "UniVocityCsvDataFormat" -> 
doWriteUniVocityCsvDataFormat("univocityCsv", (UniVocityCsvDataFormat) v);
                 case "UniVocityFixedDataFormat" -> 
doWriteUniVocityFixedDataFormat("univocityFixed", (UniVocityFixedDataFormat) v);
@@ -2679,6 +2685,12 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("contentTypeHeader", def.getContentTypeHeader(), 
"true");
         endElement(name);
     }
+    protected void doWriteUblDataFormat(String name, UblDataFormat def) throws 
IOException {
+        startElement(name);
+        doWriteIdentifiedTypeAttributes(def);
+        doWriteAttribute("prettyPrint", def.getPrettyPrint(), "false");
+        endElement(name);
+    }
     protected void 
doWriteUniVocityAbstractDataFormatAttributes(UniVocityAbstractDataFormat def) 
throws IOException {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("headerExtractionEnabled", 
def.getHeaderExtractionEnabled(), null);
@@ -3503,6 +3515,7 @@ public class ModelWriter extends BaseWriter {
                 case "SwiftMxDataFormat" -> 
doWriteSwiftMxDataFormat("swiftMx", (SwiftMxDataFormat) v);
                 case "SyslogDataFormat" -> doWriteSyslogDataFormat("syslog", 
(SyslogDataFormat) v);
                 case "TarFileDataFormat" -> 
doWriteTarFileDataFormat("tarFile", (TarFileDataFormat) v);
+                case "UblDataFormat" -> doWriteUblDataFormat("ubl", 
(UblDataFormat) v);
                 case "ThriftDataFormat" -> doWriteThriftDataFormat("thrift", 
(ThriftDataFormat) v);
                 case "UniVocityCsvDataFormat" -> 
doWriteUniVocityCsvDataFormat("univocityCsv", (UniVocityCsvDataFormat) v);
                 case "UniVocityFixedDataFormat" -> 
doWriteUniVocityFixedDataFormat("univocityFixed", (UniVocityFixedDataFormat) v);
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
index 2837cbeea4d2..88bb222f4b4e 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
@@ -505,6 +505,9 @@ public class YamlModelWriter extends YamlModelWriterSupport 
{
     public JsonObject writeThriftDataFormat(ThriftDataFormat def) {
         return wrapNode("thrift", doWriteThriftDataFormat(def));
     }
+    public JsonObject writeUblDataFormat(UblDataFormat def) {
+        return wrapNode("ubl", doWriteUblDataFormat(def));
+    }
     public JsonObject writeUniVocityCsvDataFormat(UniVocityCsvDataFormat def) {
         return wrapNode("univocityCsv", doWriteUniVocityCsvDataFormat(def));
     }
@@ -1207,6 +1210,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(jo, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(jo, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(jo, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(jo, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(jo, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(jo, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(jo, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
@@ -1985,6 +1989,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(jo, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(jo, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(jo, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(jo, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(jo, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(jo, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(jo, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
@@ -2315,6 +2320,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
                     case "SwiftMxDataFormat" -> doWriteChildElement(jo, 
"swiftMx", (SwiftMxDataFormat) item, this::doWriteSwiftMxDataFormat);
                     case "SyslogDataFormat" -> doWriteChildElement(jo, 
"syslog", (SyslogDataFormat) item, this::doWriteSyslogDataFormat);
                     case "TarFileDataFormat" -> doWriteChildElement(jo, 
"tarFile", (TarFileDataFormat) item, this::doWriteTarFileDataFormat);
+                    case "UblDataFormat" -> doWriteChildElement(jo, "ubl", 
(UblDataFormat) item, this::doWriteUblDataFormat);
                     case "ThriftDataFormat" -> doWriteChildElement(jo, 
"thrift", (ThriftDataFormat) item, this::doWriteThriftDataFormat);
                     case "UniVocityCsvDataFormat" -> doWriteChildElement(jo, 
"univocityCsv", (UniVocityCsvDataFormat) item, 
this::doWriteUniVocityCsvDataFormat);
                     case "UniVocityFixedDataFormat" -> doWriteChildElement(jo, 
"univocityFixed", (UniVocityFixedDataFormat) item, 
this::doWriteUniVocityFixedDataFormat);
@@ -2677,6 +2683,12 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
         doWriteAttribute(jo, "contentTypeHeader", def.getContentTypeHeader(), 
"true");
         return jo;
     }
+    protected JsonObject doWriteUblDataFormat(UblDataFormat def) {
+        JsonObject jo = new JsonObject();
+        doWriteIdentifiedTypeAttributes(jo, def);
+        doWriteAttribute(jo, "prettyPrint", def.getPrettyPrint(), "false");
+        return jo;
+    }
     protected void doWriteUniVocityAbstractDataFormatAttributes(JsonObject jo, 
UniVocityAbstractDataFormat def) {
         doWriteIdentifiedTypeAttributes(jo, def);
         doWriteAttribute(jo, "headerExtractionEnabled", 
def.getHeaderExtractionEnabled(), null);
@@ -3503,6 +3515,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
                 case "SwiftMxDataFormat" -> doWriteChildElement(jo, "swiftMx", 
(SwiftMxDataFormat) def.getDataFormatType(), this::doWriteSwiftMxDataFormat);
                 case "SyslogDataFormat" -> doWriteChildElement(jo, "syslog", 
(SyslogDataFormat) def.getDataFormatType(), this::doWriteSyslogDataFormat);
                 case "TarFileDataFormat" -> doWriteChildElement(jo, "tarFile", 
(TarFileDataFormat) def.getDataFormatType(), this::doWriteTarFileDataFormat);
+                case "UblDataFormat" -> doWriteChildElement(jo, "ubl", 
(UblDataFormat) def.getDataFormatType(), this::doWriteUblDataFormat);
                 case "ThriftDataFormat" -> doWriteChildElement(jo, "thrift", 
(ThriftDataFormat) def.getDataFormatType(), this::doWriteThriftDataFormat);
                 case "UniVocityCsvDataFormat" -> doWriteChildElement(jo, 
"univocityCsv", (UniVocityCsvDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityCsvDataFormat);
                 case "UniVocityFixedDataFormat" -> doWriteChildElement(jo, 
"univocityFixed", (UniVocityFixedDataFormat) def.getDataFormatType(), 
this::doWriteUniVocityFixedDataFormat);
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 6a183fc53af1..04cfce6617d6 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -160,6 +160,7 @@ import org.apache.camel.model.dataformat.SwiftMxDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
+import org.apache.camel.model.dataformat.UblDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
 import org.apache.camel.model.dataformat.UniVocityHeader;
@@ -3204,6 +3205,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "tarFile", type = 
"object:org.apache.camel.model.dataformat.TarFileDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "thrift", type = 
"object:org.apache.camel.model.dataformat.ThriftDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "toType", type = "string", 
description = "The destination (to) data type name. If you specify 'json:XYZ', 
the transformer is picked up when destination type matches. If you specify just 
'json', it matches all json destination types.", displayName = "To Type"),
+                    @YamlProperty(name = "ubl", type = 
"object:org.apache.camel.model.dataformat.UblDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityCsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityCsvDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityFixed", type = 
"object:org.apache.camel.model.dataformat.UniVocityFixedDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityTsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityTsvDataFormat", oneOf = 
"dataFormatType"),
@@ -3433,6 +3435,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "ubl": {
+                    org.apache.camel.model.dataformat.UblDataFormat val = 
asType(node, org.apache.camel.model.dataformat.UblDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "thrift": {
                     org.apache.camel.model.dataformat.ThriftDataFormat val = 
asType(node, org.apache.camel.model.dataformat.ThriftDataFormat.class);
                     target.setDataFormatType(val);
@@ -3550,6 +3557,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "syslog", type = 
"object:org.apache.camel.model.dataformat.SyslogDataFormat"),
                     @YamlProperty(name = "tarFile", type = 
"object:org.apache.camel.model.dataformat.TarFileDataFormat"),
                     @YamlProperty(name = "thrift", type = 
"object:org.apache.camel.model.dataformat.ThriftDataFormat"),
+                    @YamlProperty(name = "ubl", type = 
"object:org.apache.camel.model.dataformat.UblDataFormat"),
                     @YamlProperty(name = "univocityCsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityCsvDataFormat"),
                     @YamlProperty(name = "univocityFixed", type = 
"object:org.apache.camel.model.dataformat.UniVocityFixedDataFormat"),
                     @YamlProperty(name = "univocityTsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityTsvDataFormat"),
@@ -3979,6 +3987,16 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormats(existing);
                     break;
                 }
+                case "ubl": {
+                    org.apache.camel.model.dataformat.UblDataFormat val = 
asType(node, org.apache.camel.model.dataformat.UblDataFormat.class);
+                    
java.util.List<org.apache.camel.model.DataFormatDefinition> existing = 
target.getDataFormats();
+                    if (existing == null) {
+                        existing = new java.util.ArrayList<>();
+                    }
+                    existing.add(val);
+                    target.setDataFormats(existing);
+                    break;
+                }
                 case "thrift": {
                     org.apache.camel.model.dataformat.ThriftDataFormat val = 
asType(node, org.apache.camel.model.dataformat.ThriftDataFormat.class);
                     
java.util.List<org.apache.camel.model.DataFormatDefinition> existing = 
target.getDataFormats();
@@ -9468,6 +9486,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "syslog", type = 
"object:org.apache.camel.model.dataformat.SyslogDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "tarFile", type = 
"object:org.apache.camel.model.dataformat.TarFileDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "thrift", type = 
"object:org.apache.camel.model.dataformat.ThriftDataFormat", oneOf = 
"dataFormatType"),
+                    @YamlProperty(name = "ubl", type = 
"object:org.apache.camel.model.dataformat.UblDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityCsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityCsvDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityFixed", type = 
"object:org.apache.camel.model.dataformat.UniVocityFixedDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "univocityTsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityTsvDataFormat", oneOf = 
"dataFormatType"),
@@ -9699,6 +9718,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "ubl": {
+                    org.apache.camel.model.dataformat.UblDataFormat val = 
asType(node, org.apache.camel.model.dataformat.UblDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "thrift": {
                     org.apache.camel.model.dataformat.ThriftDataFormat val = 
asType(node, org.apache.camel.model.dataformat.ThriftDataFormat.class);
                     target.setDataFormatType(val);
@@ -19215,6 +19239,51 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
         }
     }
 
+    @YamlType(
+            nodes = "ubl",
+            types = org.apache.camel.model.dataformat.UblDataFormat.class,
+            order = 
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+            displayName = "UBL",
+            description = "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+            deprecated = false,
+            properties = {
+                    @YamlProperty(name = "id", type = "string", description = 
"The id of this node", displayName = "Id"),
+                    @YamlProperty(name = "prettyPrint", type = "boolean", 
defaultValue = "false", description = "Whether to enable pretty printing 
(formatted) output of the XML", displayName = "Pretty Print")
+            }
+    )
+    public static class UblDataFormatDeserializer extends 
YamlDeserializerBase<UblDataFormat> {
+        public UblDataFormatDeserializer() {
+            super(UblDataFormat.class);
+        }
+
+        @Override
+        protected UblDataFormat newInstance() {
+            return new UblDataFormat();
+        }
+
+        @Override
+        protected boolean setProperty(UblDataFormat target, String 
propertyKey, String propertyName,
+                Node node) {
+            propertyKey = 
org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey);
+            switch(propertyKey) {
+                case "id": {
+                    String val = asText(node);
+                    target.setId(val);
+                    break;
+                }
+                case "prettyPrint": {
+                    String val = asText(node);
+                    target.setPrettyPrint(val);
+                    break;
+                }
+                default: {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     @YamlType(
             nodes = "univocityCsv",
             types = 
org.apache.camel.model.dataformat.UniVocityCsvDataFormat.class,
@@ -19731,6 +19800,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "syslog", type = 
"object:org.apache.camel.model.dataformat.SyslogDataFormat", required = true, 
oneOf = "dataFormatType"),
                     @YamlProperty(name = "tarFile", type = 
"object:org.apache.camel.model.dataformat.TarFileDataFormat", required = true, 
oneOf = "dataFormatType"),
                     @YamlProperty(name = "thrift", type = 
"object:org.apache.camel.model.dataformat.ThriftDataFormat", required = true, 
oneOf = "dataFormatType"),
+                    @YamlProperty(name = "ubl", type = 
"object:org.apache.camel.model.dataformat.UblDataFormat", required = true, 
oneOf = "dataFormatType"),
                     @YamlProperty(name = "univocityCsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityCsvDataFormat", required = 
true, oneOf = "dataFormatType"),
                     @YamlProperty(name = "univocityFixed", type = 
"object:org.apache.camel.model.dataformat.UniVocityFixedDataFormat", required = 
true, oneOf = "dataFormatType"),
                     @YamlProperty(name = "univocityTsv", type = 
"object:org.apache.camel.model.dataformat.UniVocityTsvDataFormat", required = 
true, oneOf = "dataFormatType"),
@@ -19967,6 +20037,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "ubl": {
+                    org.apache.camel.model.dataformat.UblDataFormat val = 
asType(node, org.apache.camel.model.dataformat.UblDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "thrift": {
                     org.apache.camel.model.dataformat.ThriftDataFormat val = 
asType(node, org.apache.camel.model.dataformat.ThriftDataFormat.class);
                     target.setDataFormatType(val);
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index 8c0c15933b80..1378eacddbf1 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -438,6 +438,8 @@ public final class ModelDeserializersResolver implements 
YamlDeserializerResolve
             case "org.apache.camel.model.transformer.TransformersDefinition": 
return new ModelDeserializers.TransformersDefinitionDeserializer();
             case "doTry": return new 
ModelDeserializers.TryDefinitionDeserializer();
             case "org.apache.camel.model.TryDefinition": return new 
ModelDeserializers.TryDefinitionDeserializer();
+            case "ubl": return new 
ModelDeserializers.UblDataFormatDeserializer();
+            case "org.apache.camel.model.dataformat.UblDataFormat": return new 
ModelDeserializers.UblDataFormatDeserializer();
             case "univocityCsv": return new 
ModelDeserializers.UniVocityCsvDataFormatDeserializer();
             case "org.apache.camel.model.dataformat.UniVocityCsvDataFormat": 
return new ModelDeserializers.UniVocityCsvDataFormatDeserializer();
             case "univocityFixed": return new 
ModelDeserializers.UniVocityFixedDataFormatDeserializer();
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
index 13dbe0c2b152..9497a31bd86e 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
@@ -2238,6 +2238,9 @@
           "thrift" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
           },
+          "ubl" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+          },
           "univocityCsv" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UniVocityCsvDataFormat"
           },
@@ -5718,6 +5721,9 @@
           "thrift" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
           },
+          "ubl" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+          },
           "univocityCsv" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UniVocityCsvDataFormat"
           },
@@ -5750,7 +5756,7 @@
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ZipFileDataFormat"
           }
         },
-        "required" : [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", 
"cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", 
"fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", 
"iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", 
"ocsf", "parquetAvro", "pgp", "pqc", "protobuf", "rss", "smooks", "soap", 
"swiftMt", "swiftMx", "syslog", "tarFile", "thrift", "univocityCsv", 
"univocityFixed", "univocityTsv", "xmlSecu [...]
+        "required" : [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", 
"cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", 
"fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", 
"iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", 
"ocsf", "parquetAvro", "pgp", "pqc", "protobuf", "rss", "smooks", "soap", 
"swiftMt", "swiftMx", "syslog", "tarFile", "thrift", "ubl", "univocityCsv", 
"univocityFixed", "univocityTsv", " [...]
       },
       "org.apache.camel.model.ValidateDefinition" : {
         "title" : "Validate",
@@ -6941,6 +6947,9 @@
           "thrift" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
           },
+          "ubl" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+          },
           "univocityCsv" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UniVocityCsvDataFormat"
           },
@@ -8499,6 +8508,25 @@
           }
         }
       },
+      "org.apache.camel.model.dataformat.UblDataFormat" : {
+        "title" : "UBL",
+        "description" : "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+        "type" : "object",
+        "additionalProperties" : false,
+        "properties" : {
+          "id" : {
+            "type" : "string",
+            "title" : "Id",
+            "description" : "The id of this node"
+          },
+          "prettyPrint" : {
+            "type" : "boolean",
+            "title" : "Pretty Print",
+            "description" : "Whether to enable pretty printing (formatted) 
output of the XML",
+            "default" : false
+          }
+        }
+      },
       "org.apache.camel.model.dataformat.UniVocityCsvDataFormat" : {
         "title" : "uniVocity CSV",
         "description" : "Marshal and unmarshal Java objects from and to CSV 
(Comma Separated Values) using UniVocity Parsers",
@@ -12959,6 +12987,9 @@
             "title" : "To Type",
             "description" : "The destination (to) data type name. If you 
specify 'json:XYZ', the transformer is picked up when destination type matches. 
If you specify just 'json', it matches all json destination types."
           },
+          "ubl" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+          },
           "univocityCsv" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UniVocityCsvDataFormat"
           },
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
index 2c7cb827c3cf..e9f9bf9c6d61 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
@@ -3789,6 +3789,10 @@
         "name" : "thrift",
         "type" : "object",
         "ref" : "thrift"
+      }, {
+        "name" : "ubl",
+        "type" : "object",
+        "ref" : "ubl"
       }, {
         "name" : "univocityCsv",
         "type" : "object",
@@ -9312,6 +9316,11 @@
         "type" : "object",
         "ref" : "thrift",
         "required" : true
+      }, {
+        "name" : "ubl",
+        "type" : "object",
+        "ref" : "ubl",
+        "required" : true
       }, {
         "name" : "univocityCsv",
         "type" : "object",
@@ -11038,6 +11047,10 @@
         "name" : "thrift",
         "type" : "object",
         "ref" : "thrift"
+      }, {
+        "name" : "ubl",
+        "type" : "object",
+        "ref" : "ubl"
       }, {
         "name" : "univocityCsv",
         "type" : "object",
@@ -13362,6 +13375,31 @@
         "group" : "common"
       } ]
     },
+    "ubl" : {
+      "title" : "UBL",
+      "description" : "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+      "label" : "dataformat,transformation,xml",
+      "children" : [ {
+        "name" : "id",
+        "type" : "string",
+        "description" : "The id of this node",
+        "title" : "Id",
+        "displayName" : "Id",
+        "kind" : "attribute",
+        "index" : 0,
+        "group" : "common"
+      }, {
+        "name" : "prettyPrint",
+        "type" : "boolean",
+        "description" : "Whether to enable pretty printing (formatted) output 
of the XML",
+        "title" : "Pretty Print",
+        "default" : "false",
+        "displayName" : "Pretty Print",
+        "kind" : "attribute",
+        "index" : 1,
+        "group" : "common"
+      } ]
+    },
     "uniVocityCsv" : {
       "title" : "uniVocity CSV",
       "description" : "Marshal and unmarshal Java objects from and to CSV 
(Comma Separated Values) using UniVocity Parsers",
@@ -19553,6 +19591,10 @@
         "name" : "thrift",
         "type" : "object",
         "ref" : "thrift"
+      }, {
+        "name" : "ubl",
+        "type" : "object",
+        "ref" : "ubl"
       }, {
         "name" : "univocityCsv",
         "type" : "object",
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index 76a9d85c2cd9..c44b19b51ca2 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -3194,6 +3194,8 @@
                 "required" : [ "tarFile" ]
               }, {
                 "required" : [ "thrift" ]
+              }, {
+                "required" : [ "ubl" ]
               }, {
                 "required" : [ "univocityCsv" ]
               }, {
@@ -3530,6 +3532,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "ubl" ],
+            "properties" : {
+              "ubl" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "univocityCsv" ],
@@ -3661,6 +3671,7 @@
           "syslog" : { },
           "tarFile" : { },
           "thrift" : { },
+          "ubl" : { },
           "univocityCsv" : { },
           "univocityFixed" : { },
           "univocityTsv" : { },
@@ -8643,6 +8654,7 @@
           "syslog" : { },
           "tarFile" : { },
           "thrift" : { },
+          "ubl" : { },
           "univocityCsv" : { },
           "univocityFixed" : { },
           "univocityTsv" : { },
@@ -8980,6 +8992,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "ubl" ],
+            "properties" : {
+              "ubl" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "univocityCsv" ],
@@ -10444,6 +10464,9 @@
           "thrift" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
           },
+          "ubl" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+          },
           "univocityCsv" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UniVocityCsvDataFormat"
           },
@@ -12026,6 +12049,25 @@
           }
         } ]
       },
+      "org.apache.camel.model.dataformat.UblDataFormat" : {
+        "title" : "UBL",
+        "description" : "Marshal and unmarshal UBL 2.1 (Universal Business 
Language) documents.",
+        "type" : "object",
+        "additionalProperties" : false,
+        "properties" : {
+          "id" : {
+            "type" : "string",
+            "title" : "Id",
+            "description" : "The id of this node"
+          },
+          "prettyPrint" : {
+            "type" : "boolean",
+            "title" : "Pretty Print",
+            "description" : "Whether to enable pretty printing (formatted) 
output of the XML",
+            "default" : false
+          }
+        }
+      },
       "org.apache.camel.model.dataformat.UniVocityCsvDataFormat" : {
         "title" : "uniVocity CSV",
         "description" : "Marshal and unmarshal Java objects from and to CSV 
(Comma Separated Values) using UniVocity Parsers",
@@ -16711,6 +16753,8 @@
                 "required" : [ "tarFile" ]
               }, {
                 "required" : [ "thrift" ]
+              }, {
+                "required" : [ "ubl" ]
               }, {
                 "required" : [ "univocityCsv" ]
               }, {
@@ -17047,6 +17091,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.ThriftDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "ubl" ],
+            "properties" : {
+              "ubl" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.UblDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "univocityCsv" ],
@@ -17167,6 +17219,7 @@
           "syslog" : { },
           "tarFile" : { },
           "thrift" : { },
+          "ubl" : { },
           "univocityCsv" : { },
           "univocityFixed" : { },
           "univocityTsv" : { },
diff --git a/parent/pom.xml b/parent/pom.xml
index 22d8abb30bd5..de9f851b5951 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -169,6 +169,7 @@
         <ftpserver-version>1.2.1</ftpserver-version>
         <freemarker-version>2.3.34</freemarker-version>
         <fory-version>1.6.0</fory-version>
+        <ph-ubl-version>10.2.0</ph-ubl-version>
         <j8583-version>3.0.1</j8583-version>
         <jakarta-jms-api-version>3.1.0</jakarta-jms-api-version>
         
<jakarta-persistence-api-version>3.2.0</jakarta-persistence-api-version>
@@ -2882,6 +2883,11 @@
                 <artifactId>camel-twitter</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-ubl</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-undertow</artifactId>

Reply via email to