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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new ace5cf67313 CAMEL-22361: camel-groovy-xml - Add data format that uses 
groovy xml that is easy to use and no need for POJOs (#18979)
ace5cf67313 is described below

commit ace5cf673136e2e235dcb0b457a98c4728341027
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Fri Aug 22 15:52:15 2025 +0200

    CAMEL-22361: camel-groovy-xml - Add data format that uses groovy xml that 
is easy to use and no need for POJOs (#18979)
    
    * CAMEL-22361: camel-groovy-xml - Add data format that uses groovy xml that 
is easy to use and no need for POJOs
    
    * CAMEL-22361: camel-groovy-xml - Add data format that uses groovy xml that 
is easy to use and no need for POJOs
---
 bom/camel-bom/pom.xml                              |   5 +
 catalog/camel-allcomponents/pom.xml                |   5 +
 .../apache/camel/catalog/dataformats.properties    |   1 +
 .../camel/catalog/dataformats/groovyXml.json       |  21 ++
 .../org/apache/camel/catalog/models.properties     |   1 +
 .../catalog/models/dataFormatTransformer.json      |   2 +-
 .../apache/camel/catalog/models/dataFormats.json   |   2 +-
 .../org/apache/camel/catalog/models/groovyXml.json |  18 ++
 .../org/apache/camel/catalog/models/marshal.json   |   2 +-
 .../org/apache/camel/catalog/models/unmarshal.json |   2 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  20 ++
 .../apache/camel/catalog/schemas/camel-xml-io.xsd  |  20 ++
 components/camel-groovy-xml/pom.xml                |  84 ++++++++
 .../groovy/xml/GroovyXmlDataFormatConfigurer.java  |  48 +++++
 .../org/apache/camel/groovy/xml/groovyXml.json     |  21 ++
 .../apache/camel/configurer/groovyXml-dataformat   |   2 +
 .../org/apache/camel/dataformat.properties         |   7 +
 .../services/org/apache/camel/dataformat/groovyXml |   2 +
 .../src/main/docs/groovyXml-dataformat.adoc        |  98 ++++++++++
 .../camel/groovy/xml/GroovyXmlDataFormat.java      | 171 ++++++++++++++++
 .../camel/groovy/xml/GroovyXmlDataFormatTest.java  | 216 +++++++++++++++++++++
 .../src/test/resources/log4j2.properties           |  30 +++
 .../apache/camel/model/dataformat/dataFormats.json |   2 +-
 .../apache/camel/model/dataformat/groovyXml.json   |  18 ++
 .../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 |   9 +
 .../org/apache/camel/model/MarshalDefinition.java  |   2 +
 .../apache/camel/model/UnmarshalDefinition.java    |   2 +
 .../model/dataformat/DataFormatsDefinition.java    |   1 +
 .../model/dataformat/GroovyXmlDataFormat.java      |  61 ++++++
 .../DataFormatTransformerDefinition.java           |   2 +
 .../reifier/dataformat/DataFormatReifier.java      |   2 +
 .../dataformat/GroovyXmlDataFormatReifier.java     |  36 ++++
 .../org/apache/camel/main/dataformats.properties   |   1 +
 .../java/org/apache/camel/xml/in/ModelParser.java  |   4 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  12 ++
 .../org/apache/camel/yaml/out/ModelWriter.java     |  12 ++
 .../dataformats/examples/json/groovyXml.json       |   1 +
 docs/components/modules/dataformats/nav.adoc       |   1 +
 .../dataformats/pages/groovyXml-dataformat.adoc    |   1 +
 .../dsl/yaml/deserializers/ModelDeserializers.java |  67 +++++++
 .../deserializers/ModelDeserializersResolver.java  |   2 +
 .../generated/resources/schema/camelYamlDsl.json   |  49 +++++
 parent/pom.xml                                     |   5 +
 49 files changed, 1076 insertions(+), 8 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index e210830c9f4..17926cad0fe 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -917,6 +917,11 @@
         <artifactId>camel-groovy</artifactId>
         <version>4.15.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-groovy-xml</artifactId>
+        <version>4.15.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-grpc</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml 
b/catalog/camel-allcomponents/pom.xml
index a2752f9d1ea..279c7f1d08f 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -786,6 +786,11 @@
             <artifactId>camel-groovy</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-groovy-xml</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-grpc</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 ac36ca06f71..a71e6f2ab78 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
@@ -17,6 +17,7 @@ fhirXml
 flatpack
 fory
 grok
+groovyXml
 gson
 gzipDeflater
 hl7
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyXml.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyXml.json
new file mode 100644
index 00000000000..af52a11b703
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyXml.json
@@ -0,0 +1,21 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "groovyXml",
+    "title": "Groovy XML",
+    "description": "Transform between XML and Java Map via Groovy",
+    "deprecated": false,
+    "firstVersion": "4.15.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.groovy.xml.GroovyXmlDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-groovy-xml",
+    "version": "4.15.0-SNAPSHOT",
+    "modelName": "groovyXml",
+    "modelJavaType": "org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+  },
+  "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" }
+  }
+}
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 64faa3287cf..c100189c7a2 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
@@ -66,6 +66,7 @@ globalOption
 globalOptions
 grok
 groovy
+groovyXml
 gzipDeflater
 head
 header
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 7ea6dd34e25..56997e83aa8 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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "gzipDeflater", 
"hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", 
"mimeMultipart", "parquetAvro", "pgp", "proto [...]
+    "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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro",  [...]
     "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Set a scheme name supported by the transformer. If you specify 
'csv', the transformer will be picked up for all of 'csv' from\/to Java 
transformation. Note that the 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": "Set 
the transformer name under which the transformer gets referenced when 
specifying the input\/output data type on routes. If you specify a transformer 
name that matches a data type scheme like 'csv' the transformer will be picked 
up for all of 'csv:' from\/t [...]
     "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": "Set the 'from' data type name. If you specify 'xml:XYZ', the 
transformer will be picked up if source type is 'xml:XYZ'. If you specify just 
'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 
'xml:DEF'." },
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 570e9f25104..6a313d4ba86 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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyXml.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyXml.json
new file mode 100644
index 00000000000..b4752eec3eb
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyXml.json
@@ -0,0 +1,18 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "groovyXml",
+    "title": "Groovy XML",
+    "description": "Transform between XML and Groovy Node (Map structure) 
objects.",
+    "deprecated": false,
+    "firstVersion": "4.15.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.model.dataformat.GroovyXmlDataFormat",
+    "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" }
+  }
+}
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 196af61b1df..c0078ed708f 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
@@ -15,7 +15,7 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the id of this node" },
     "description": { "index": 1, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "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": "Disables this EIP from 
the route." },
-    "dataFormatType": { "index": 3, "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", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "dataFormatType": { "index": 3, "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", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
     "variableSend": { "index": 4, "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. Important: When 
using send variable then the message body is tak [...]
     "variableReceive": { "index": 5, "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. 
Important: When using receive variable th [...]
   }
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 6d0ca05b044..c561196be65 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
@@ -15,7 +15,7 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the id of this node" },
     "description": { "index": 1, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "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": "Disables this EIP from 
the route." },
-    "dataFormatType": { "index": 3, "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", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "dataFormatType": { "index": 3, "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", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
     "variableSend": { "index": 4, "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. Important: When 
using send variable then the message body is tak [...]
     "variableReceive": { "index": 5, "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. 
Important: When using receive variable th [...]
     "allowNullBody": { "index": 6, "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 487fd1fb2c2..7fe2161db41 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
@@ -679,6 +679,15 @@ Unmarshal unstructured data to objects using Logstash 
based Grok patterns.
       <xs:documentation xml:lang="en">
 <![CDATA[
 Evaluates a Groovy script.
+]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="groovyXml" type="tns:groovyXmlDataFormat">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+<![CDATA[
+Transform between XML and Groovy Node (Map structure) objects.
 ]]>
       </xs:documentation>
     </xs:annotation>
@@ -7540,6 +7549,7 @@ messages, or any custom logic needed before the looping 
executes.
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
@@ -8936,6 +8946,13 @@ Whether to capture named expressions only or not (i.e. 
%{IP:ip} but not ${IP}).
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
+  <xs:complexType name="groovyXmlDataFormat">
+    <xs:complexContent>
+      <xs:extension base="tns:dataFormat">
+        <xs:sequence/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
   <xs:complexType name="gzipDeflaterDataFormat">
     <xs:complexContent>
       <xs:extension base="tns:dataFormat">
@@ -14842,6 +14859,7 @@ To type used as a target data type in the 
transformation.
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
@@ -17115,6 +17133,7 @@ Set a reference to a custom Expression to use.
         <xs:element ref="tns:flatpack"/>
         <xs:element ref="tns:fory"/>
         <xs:element ref="tns:grok"/>
+        <xs:element ref="tns:groovyXml"/>
         <xs:element ref="tns:gzipDeflater"/>
         <xs:element ref="tns:hl7"/>
         <xs:element ref="tns:ical"/>
@@ -17965,6 +17984,7 @@ Set the 'to' data type name. If you specify 'json:XYZ', 
the transformer will be
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
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 34816850f3d..44b56d3fe1e 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
@@ -634,6 +634,15 @@ Unmarshal unstructured data to objects using Logstash 
based Grok patterns.
       <xs:documentation xml:lang="en">
 <![CDATA[
 Evaluates a Groovy script.
+]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="groovyXml" type="tns:groovyXmlDataFormat">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+<![CDATA[
+Transform between XML and Groovy Node (Map structure) objects.
 ]]>
       </xs:documentation>
     </xs:annotation>
@@ -6213,6 +6222,7 @@ messages, or any custom logic needed before the looping 
executes.
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
@@ -7609,6 +7619,13 @@ Whether to capture named expressions only or not (i.e. 
%{IP:ip} but not ${IP}).
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
+  <xs:complexType name="groovyXmlDataFormat">
+    <xs:complexContent>
+      <xs:extension base="tns:dataFormat">
+        <xs:sequence/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
   <xs:complexType name="gzipDeflaterDataFormat">
     <xs:complexContent>
       <xs:extension base="tns:dataFormat">
@@ -13536,6 +13553,7 @@ To type used as a target data type in the 
transformation.
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
@@ -15809,6 +15827,7 @@ Set a reference to a custom Expression to use.
         <xs:element ref="tns:flatpack"/>
         <xs:element ref="tns:fory"/>
         <xs:element ref="tns:grok"/>
+        <xs:element ref="tns:groovyXml"/>
         <xs:element ref="tns:gzipDeflater"/>
         <xs:element ref="tns:hl7"/>
         <xs:element ref="tns:ical"/>
@@ -16659,6 +16678,7 @@ Set the 'to' data type name. If you specify 'json:XYZ', 
the transformer will be
             <xs:element ref="tns:flatpack"/>
             <xs:element ref="tns:fory"/>
             <xs:element ref="tns:grok"/>
+            <xs:element ref="tns:groovyXml"/>
             <xs:element ref="tns:gzipDeflater"/>
             <xs:element ref="tns:hl7"/>
             <xs:element ref="tns:ical"/>
diff --git a/components/camel-groovy-xml/pom.xml 
b/components/camel-groovy-xml/pom.xml
new file mode 100644
index 00000000000..7b75fe20f21
--- /dev/null
+++ b/components/camel-groovy-xml/pom.xml
@@ -0,0 +1,84 @@
+<?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/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.15.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-groovy-xml</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: Groovy XML</name>
+    <description>Camel Groovy XML data format</description>
+
+    <properties>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.groovy</groupId>
+            <artifactId>groovy-xml</artifactId>
+            <version>${groovy-version}</version>
+        </dependency>
+
+        <!-- testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jackson</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-main</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>${hamcrest-version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git 
a/components/camel-groovy-xml/src/generated/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatConfigurer.java
 
b/components/camel-groovy-xml/src/generated/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatConfigurer.java
new file mode 100644
index 00000000000..b7e8286cc5c
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/generated/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatConfigurer.java
@@ -0,0 +1,48 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.groovy.xml;
+
+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 GroovyXmlDataFormatConfigurer 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();
+        ALL_OPTIONS = map;
+    }
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Map<String, Object> getAllOptions(Object target) {
+        return ALL_OPTIONS;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git 
a/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
 
b/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
new file mode 100644
index 00000000000..af52a11b703
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
@@ -0,0 +1,21 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "groovyXml",
+    "title": "Groovy XML",
+    "description": "Transform between XML and Java Map via Groovy",
+    "deprecated": false,
+    "firstVersion": "4.15.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.groovy.xml.GroovyXmlDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-groovy-xml",
+    "version": "4.15.0-SNAPSHOT",
+    "modelName": "groovyXml",
+    "modelJavaType": "org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+  },
+  "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" }
+  }
+}
diff --git 
a/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyXml-dataformat
 
b/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyXml-dataformat
new file mode 100644
index 00000000000..b6e0fd3279d
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyXml-dataformat
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.groovy.xml.GroovyXmlDataFormatConfigurer
diff --git 
a/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
 
b/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
new file mode 100644
index 00000000000..346b3429bb3
--- /dev/null
+++ 
b/components/camel-groovy-xml/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=groovyXml
+groupId=org.apache.camel
+artifactId=camel-groovy-xml
+version=4.15.0-SNAPSHOT
+projectName=Camel :: Groovy XML
+projectDescription=Camel Groovy XML data format
diff --git 
a/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyXml
 
b/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyXml
new file mode 100644
index 00000000000..a75d4bb43bf
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyXml
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.groovy.xml.GroovyXmlDataFormat
diff --git 
a/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc 
b/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
new file mode 100644
index 00000000000..9a8a4e878b2
--- /dev/null
+++ b/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
@@ -0,0 +1,98 @@
+= Groovy XML DataFormat
+:doctitle: Groovy XML
+:shortname: groovyXml
+:artifactid: camel-groovy-xml
+:description: Transform between XML and Java Map via Groovy
+:since: 4.15
+:supportlevel: Preview
+:tabs-sync-option:
+//Manually maintained attributes
+:camel-spring-boot-name: groovy-xml
+
+*Since Camel {since}*
+
+The Groovy XML data format is a basic data format to transform XML to Groovy 
Node objects,
+and back to XML. This is convenient when working with XML and using Groovy for 
data manipulation.
+
+This data format is limited in functionality but intended to be easier to use.
+There are none or only a few options to configure.
+
+== Groovy XML Options
+
+// dataformat options: START
+include::partial$dataformat-options.adoc[]
+// dataformat options: END
+
+== Supported Java types
+
+This data format supports marshalling from the following Java type to XML:
+
+- Groovy Node object (`groovy.util.Node`)
+- Jackson Node object (`com.fasterxml.jackson.databind.JsonNode`)
+- Camel JSonObject (`org.apache.camel.util.json.JsonObject`)
+- Java Map object ('java.util.Map')
+
+And unmarshalling from XML to Groovy Node (`groovy.util.Node`) object.
+
+== Examples
+
+For example to transform from XML to Groovy Node:
+
+[source,yaml]
+----
+- route:
+    description: From timer to xml
+    from:
+      uri: timer
+      parameters:
+        repeatCount: "1"
+        timerName: tick
+      steps:
+        - setBody:
+            expression:
+              constant:
+                expression: |-
+                  <library>
+                    <book id="bk101">
+                      <title>No Title</title>
+                      <author>F. Scott Fitzgerald</author>
+                      <year>1925</year>
+                      <genre>Classic</genre>
+                    </book>
+                    <book id="bk102">
+                      <title>1984</title>
+                      <author>George Orwell</author>
+                      <year>1949</year>
+                      <genre>Dystopian</genre>
+                    </book>
+                  </library>
+        - unmarshal:
+            groovyXml:
+              {}
+        - log:
+            message: "${body}"
+----
+
+This will transform the XML into a Groovy Node object which can be manipulated 
using Java and Groovy code.
+
+To convert back to XML you just use the opposite direction with _marshal_.
+
+== Dependencies
+
+To use the data format in your camel routes, you need to add
+a dependency on *camel-groovy-xml* which implements this data format.
+
+If you use maven, you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+----------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-groovy-xml</artifactId>
+  <version>x.x.x</version>
+</dependency>
+----------------------------------------
+
+include::spring-boot:partial$starter.adoc[]
diff --git 
a/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
 
b/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
new file mode 100644
index 00000000000..c5d99b5a851
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
@@ -0,0 +1,171 @@
+/*
+ * 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.groovy.xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import groovy.util.Node;
+import groovy.xml.XmlNodePrinter;
+import groovy.xml.XmlParser;
+import groovy.xml.XmlUtil;
+import groovy.xml.slurpersupport.GPathResult;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatName;
+import org.apache.camel.spi.annotations.Dataformat;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.StringHelper;
+
+@Dataformat("groovyXml")
+public class GroovyXmlDataFormat extends ServiceSupport implements DataFormat, 
DataFormatName {
+
+    int START_TAG = 1;
+    int VALUE = 2;
+    int END_TAG = 3;
+
+    @Override
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) 
throws Exception {
+        if (graph instanceof GPathResult gp) {
+            XmlUtil.serialize(gp, stream);
+        } else if (graph instanceof Node n) {
+            serialize(n, stream);
+        } else if (graph instanceof Map map) {
+            serialize(exchange, map, stream);
+        } else {
+            // optional jackson support
+            if 
(graph.getClass().getName().startsWith("com.fasterxml.jackson.databind")) {
+                var map = 
exchange.getContext().getTypeConverter().convertTo(Map.class, exchange, graph);
+                serialize(exchange, map, stream);
+            } else {
+                byte[] arr = 
exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, 
exchange, graph);
+                stream.write(arr);
+            }
+        }
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws 
Exception {
+        XmlParser parser = new XmlParser();
+        return parser.parse(stream);
+    }
+
+    @Override
+    public String getDataFormatName() {
+        return "groovyXml";
+    }
+
+    private void serialize(Node node, OutputStream os) {
+        PrintWriter pw = new PrintWriter(os);
+        XmlNodePrinter nodePrinter = new XmlNodePrinter(pw);
+        nodePrinter.setPreserveWhitespace(true);
+        nodePrinter.print(node);
+    }
+
+    private void printLines(List<Line> lines, OutputStream os) throws 
Exception {
+        // add missing root end tag
+        lines.add(new Line(lines.get(0).key, null, END_TAG));
+        int level = 0;
+        for (Line line : lines) {
+            int kind = line.kind;
+            if (kind == START_TAG) {
+                String pad = StringHelper.padString(level);
+                os.write(pad.getBytes());
+                os.write("<".getBytes());
+                os.write(line.key.getBytes());
+                os.write(">\n".getBytes());
+                level++;
+            } else if (kind == END_TAG) {
+                level--;
+                String pad = StringHelper.padString(level);
+                os.write(pad.getBytes());
+                os.write("</".getBytes());
+                os.write(line.key.getBytes());
+                os.write(">\n".getBytes());
+            } else {
+                String pad = StringHelper.padString(level);
+                os.write(pad.getBytes());
+                os.write("<".getBytes());
+                os.write(line.key.getBytes());
+                os.write(">".getBytes());
+                os.write(line.value.getBytes());
+                os.write("</".getBytes());
+                os.write(line.key.getBytes());
+                os.write(">\n".getBytes());
+            }
+        }
+    }
+
+    private void serialize(Exchange exchange, Map<String, Object> map, 
OutputStream os) throws Exception {
+        List<Line> lines = new ArrayList<>();
+        doSerialize(exchange.getContext(), map, lines);
+        printLines(lines, os);
+    }
+
+    private void doSerialize(CamelContext context, Map<String, Object> map, 
List<Line> lines) {
+        for (var e : map.entrySet()) {
+            String key = e.getKey();
+
+            // attributes are not yet supported
+            if (key.startsWith("_")) {
+                continue;
+            }
+
+            // root tag
+            if (lines.isEmpty()) {
+                lines.add(new Line(key, null, START_TAG));
+            }
+
+            if (e.getValue() != null) {
+                // nested list or map
+                if (e.getValue() instanceof Map cm) {
+                    doSerialize(context, cm, lines);
+                } else if (e.getValue() instanceof List cl) {
+                    doSerialize(context, cl, key, lines);
+                } else {
+                    String val = 
context.getTypeConverter().convertTo(String.class, e.getValue());
+                    if (val != null) {
+                        val = val.trim();
+                        if (!val.isBlank()) {
+                            lines.add(new Line(key, val, VALUE));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void doSerialize(CamelContext context, List list, String key, 
List<Line> lines) {
+        // list of map or value entries
+        for (var e : list) {
+            lines.add(new Line(key, null, START_TAG));
+            if (e instanceof Map map) {
+                doSerialize(context, map, lines);
+            }
+            lines.add(new Line(key, null, END_TAG));
+        }
+    }
+
+    record Line(String key, String value, int kind) {
+    }
+
+}
diff --git 
a/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
 
b/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
new file mode 100644
index 00000000000..a82685ebee2
--- /dev/null
+++ 
b/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
@@ -0,0 +1,216 @@
+/*
+ * 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.groovy.xml;
+
+import org.w3c.dom.Document;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import groovy.util.Node;
+import groovy.xml.XmlParser;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class GroovyXmlDataFormatTest extends CamelTestSupport {
+
+    private static final String BOOKS
+            = """
+                    <library>
+                      <book id="bk101">
+                        <title>No Title</title>
+                        <author>F. Scott Fitzgerald</author>
+                        <year>1925</year>
+                        <genre>Classic</genre>
+                      </book>
+                      <book id="bk102">
+                        <title>1984</title>
+                        <author>George Orwell</author>
+                        <year>1949</year>
+                        <genre>Dystopian</genre>
+                      </book>
+                    </library>
+                    """;
+
+    private static final String BOOKS_NO_ATTR
+            = """
+                    <library>
+                      <book>
+                        <title>No Title</title>
+                        <author>F. Scott Fitzgerald</author>
+                        <year>1925</year>
+                        <genre>Classic</genre>
+                      </book>
+                      <book>
+                        <title>1984</title>
+                        <author>George Orwell</author>
+                        <year>1949</year>
+                        <genre>Dystopian</genre>
+                      </book>
+                    </library>
+                    """;
+
+    private static final String BOOKS_JSON
+            = """
+                    {
+                        "library": {
+                            "book": [
+                                {
+                                    "title": "No Title",
+                                    "author": "F. Scott Fitzgerald",
+                                    "year": "1925",
+                                    "genre": "Classic",
+                                    "_id": "bk101"
+                                },
+                                {
+                                    "title": "1984",
+                                    "author": "George Orwell",
+                                    "year": "1949",
+                                    "genre": "Dystopian",
+                                    "_id": "bk102"
+                                }
+                            ]
+                        }
+                    }
+                    """;
+
+    @Test
+    public void testUnmarshal() throws Exception {
+        getMockEndpoint("mock:unmarshal").expectedMessageCount(1);
+
+        Object out = template.requestBody("direct:unmarshal", BOOKS);
+        Assertions.assertNotNull(out);
+        Assertions.assertInstanceOf(Node.class, out);
+
+        Node n = (Node) out;
+        Assertions.assertEquals(2, n.children().size());
+        Node c = (Node) n.children().get(0);
+        Assertions.assertEquals("bk101", c.attribute("id"));
+        c = (Node) n.children().get(1);
+        Assertions.assertEquals("bk102", c.attribute("id"));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testMarshal() throws Exception {
+        getMockEndpoint("mock:marshal").expectedMessageCount(1);
+
+        XmlParser parser = new XmlParser();
+        parser.setTrimWhitespace(false);
+        Node n = parser.parseText(BOOKS);
+
+        Object out = template.requestBody("direct:marshal", n);
+        Assertions.assertNotNull(out);
+        Assertions.assertInstanceOf(byte[].class, out);
+
+        String xml = context.getTypeConverter().convertTo(String.class, out);
+        Assertions.assertEquals(BOOKS, xml);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testMarshalDOM() throws Exception {
+        getMockEndpoint("mock:marshal").expectedMessageCount(1);
+
+        Document dom = context.getTypeConverter().convertTo(Document.class, 
BOOKS);
+
+        Object out = template.requestBody("direct:marshal", dom);
+        Assertions.assertNotNull(out);
+        Assertions.assertInstanceOf(byte[].class, out);
+
+        String xml = context.getTypeConverter().convertTo(String.class, out);
+        xml = xml + System.lineSeparator();
+        Assertions.assertEquals(BOOKS, xml);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testMarshalCamelJSon() throws Exception {
+        getMockEndpoint("mock:marshal").expectedMessageCount(1);
+
+        JsonObject root = new JsonObject();
+        JsonArray arr = new JsonArray();
+        JsonObject b1 = new JsonObject();
+        b1.put("title", "No Title");
+        b1.put("author", "F. Scott Fitzgerald");
+        b1.put("year", 1925);
+        b1.put("genre", "Classic");
+
+        JsonObject b2 = new JsonObject();
+        b2.put("title", "1984");
+        b2.put("author", "George Orwell");
+        b2.put("year", 1949);
+        b2.put("genre", "Dystopian");
+
+        arr.add(b1);
+        arr.add(b2);
+        JsonObject books = new JsonObject();
+        books.put("book", arr);
+        root.put("library", books);
+
+        Object out = template.requestBody("direct:marshal", root);
+        Assertions.assertNotNull(out);
+        Assertions.assertInstanceOf(byte[].class, out);
+
+        String xml = context.getTypeConverter().convertTo(String.class, out);
+        Assertions.assertEquals(BOOKS_NO_ATTR, xml);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Test
+    public void testMarshalJacksonJSon() throws Exception {
+        getMockEndpoint("mock:marshal").expectedMessageCount(1);
+
+        ObjectMapper om = new JsonMapper();
+        JsonNode root = om.readTree(BOOKS_JSON);
+
+        Object out = template.requestBody("direct:marshal", root);
+        Assertions.assertNotNull(out);
+        Assertions.assertInstanceOf(byte[].class, out);
+
+        String xml = context.getTypeConverter().convertTo(String.class, out);
+        Assertions.assertEquals(BOOKS_NO_ATTR, xml);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:marshal").streamCache(false)
+                        .marshal().groovyXml()
+                        .to("mock:marshal");
+
+                from("direct:unmarshal")
+                        .unmarshal().groovyXml()
+                        .to("mock:unmarshal");
+            }
+        };
+    }
+}
diff --git a/components/camel-groovy-xml/src/test/resources/log4j2.properties 
b/components/camel-groovy-xml/src/test/resources/log4j2.properties
new file mode 100644
index 00000000000..2679120e692
--- /dev/null
+++ b/components/camel-groovy-xml/src/test/resources/log4j2.properties
@@ -0,0 +1,30 @@
+## ---------------------------------------------------------------------------
+## 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-groovy-xml-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 = [%30.30t] %-30.30c{1} %-5p %m%n
+logger.springframework.name = org.springframework
+logger.springframework.level = WARN
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
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 570e9f25104..6a313d4ba86 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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyXml.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyXml.json
new file mode 100644
index 00000000000..b4752eec3eb
--- /dev/null
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyXml.json
@@ -0,0 +1,18 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "groovyXml",
+    "title": "Groovy XML",
+    "description": "Transform between XML and Groovy Node (Map structure) 
objects.",
+    "deprecated": false,
+    "firstVersion": "4.15.0",
+    "label": "dataformat,transformation,xml",
+    "javaType": "org.apache.camel.model.dataformat.GroovyXmlDataFormat",
+    "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" }
+  }
+}
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 196af61b1df..c0078ed708f 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
@@ -15,7 +15,7 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the id of this node" },
     "description": { "index": 1, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "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": "Disables this EIP from 
the route." },
-    "dataFormatType": { "index": 3, "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", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "dataFormatType": { "index": 3, "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", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
     "variableSend": { "index": 4, "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. Important: When 
using send variable then the message body is tak [...]
     "variableReceive": { "index": 5, "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. 
Important: When using receive variable th [...]
   }
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 7ea6dd34e25..56997e83aa8 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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "gzipDeflater", 
"hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", 
"mimeMultipart", "parquetAvro", "pgp", "proto [...]
+    "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", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro",  [...]
     "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Set a scheme name supported by the transformer. If you specify 
'csv', the transformer will be picked up for all of 'csv' from\/to Java 
transformation. Note that the 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": "Set 
the transformer name under which the transformer gets referenced when 
specifying the input\/output data type on routes. If you specify a transformer 
name that matches a data type scheme like 'csv' the transformer will be picked 
up for all of 'csv:' from\/t [...]
     "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": "Set the 'from' data type name. If you specify 'xml:XYZ', the 
transformer will be picked up if source type is 'xml:XYZ'. If you specify just 
'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 
'xml:DEF'." },
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 6d0ca05b044..c561196be65 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
@@ -15,7 +15,7 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the id of this node" },
     "description": { "index": 1, "kind": "attribute", "displayName": 
"Description", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "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": "Disables this EIP from 
the route." },
-    "dataFormatType": { "index": 3, "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", 
"gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", 
"jsonApi", "lzf", "mimeMultipart", "parquetAvro", "pgp" [...]
+    "dataFormatType": { "index": 3, "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", 
"groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", 
"json", "jsonApi", "lzf", "mimeMultipart", "parque [...]
     "variableSend": { "index": 4, "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. Important: When 
using send variable then the message body is tak [...]
     "variableReceive": { "index": 5, "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. 
Important: When using receive variable th [...]
     "allowNullBody": { "index": 6, "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 71705b90c4d..16dac505f2b 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
@@ -67,6 +67,7 @@ globalOption
 globalOptions
 grok
 groovy
+groovyXml
 gzipDeflater
 head
 header
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 e8bbf2dde79..c4e1b28044e 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
@@ -18,6 +18,7 @@ FhirXmlDataFormat
 FlatpackDataFormat
 ForyDataFormat
 GrokDataFormat
+GroovyXmlDataFormat
 GzipDeflaterDataFormat
 HL7DataFormat
 IcalDataFormat
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 646ef44e1c7..2e70bbd87f2 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
@@ -32,6 +32,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.FlatpackDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -178,6 +179,13 @@ public final class DataFormatBuilderFactory {
         return new GrokDataFormat.Builder();
     }
 
+    /**
+     * Uses the Groovy XML format
+     */
+    public GroovyXmlDataFormat.Builder groovyXml() {
+        return new GroovyXmlDataFormat.Builder();
+    }
+
     /**
      * Uses the GZIP deflater 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 bc446576f81..d88b93f8816 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
@@ -37,6 +37,7 @@ import org.apache.camel.model.dataformat.FhirJsonDataFormat;
 import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -338,6 +339,14 @@ public class DataFormatClause<T extends 
ProcessorDefinition<?>> {
         return dataFormat(grokDataFormat);
     }
 
+    /**
+     * Uses the Groovy XML data format
+     */
+    public T groovyXml() {
+        GroovyXmlDataFormat df = new GroovyXmlDataFormat();
+        return dataFormat(df);
+    }
+
     /**
      * Uses the GZIP deflater 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 808cab8583c..e2e0658d9fb 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
@@ -39,6 +39,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.FlatpackDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -94,6 +95,7 @@ public class MarshalDefinition extends 
NoOutputDefinition<MarshalDefinition> imp
             @XmlElement(name = "flatpack", type = FlatpackDataFormat.class),
             @XmlElement(name = "fory", type = ForyDataFormat.class),
             @XmlElement(name = "grok", type = GrokDataFormat.class),
+            @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class),
             @XmlElement(name = "gzipDeflater", type = 
GzipDeflaterDataFormat.class),
             @XmlElement(name = "hl7", type = HL7DataFormat.class),
             @XmlElement(name = "ical", type = IcalDataFormat.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 f1a8822d4b2..b9659b5360a 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
@@ -39,6 +39,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.FlatpackDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -94,6 +95,7 @@ public class UnmarshalDefinition extends 
NoOutputDefinition<UnmarshalDefinition>
             @XmlElement(name = "flatpack", type = FlatpackDataFormat.class),
             @XmlElement(name = "fory", type = ForyDataFormat.class),
             @XmlElement(name = "grok", type = GrokDataFormat.class),
+            @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class),
             @XmlElement(name = "gzipDeflater", type = 
GzipDeflaterDataFormat.class),
             @XmlElement(name = "hl7", type = HL7DataFormat.class),
             @XmlElement(name = "ical", type = IcalDataFormat.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 35e761a348c..27ef80f90a2 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
@@ -59,6 +59,7 @@ public class DataFormatsDefinition implements 
CopyableDefinition<DataFormatsDefi
             @XmlElement(name = "flatpack", type = FlatpackDataFormat.class),
             @XmlElement(name = "fory", type = ForyDataFormat.class),
             @XmlElement(name = "grok", type = GrokDataFormat.class),
+            @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class),
             @XmlElement(name = "gzipDeflater", type = 
GzipDeflaterDataFormat.class),
             @XmlElement(name = "hl7", type = HL7DataFormat.class),
             @XmlElement(name = "ical", type = IcalDataFormat.class),
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java
new file mode 100644
index 00000000000..a7bd3a117db
--- /dev/null
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java
@@ -0,0 +1,61 @@
+/*
+ * 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.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;
+
+/**
+ * Transform between XML and Groovy Node (Map structure) objects.
+ */
+@Metadata(firstVersion = "4.15.0", label = "dataformat,transformation,xml", 
title = "Groovy XML")
+@XmlRootElement(name = "groovyXml")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class GroovyXmlDataFormat extends DataFormatDefinition {
+
+    public GroovyXmlDataFormat() {
+        super("groovyXml");
+    }
+
+    protected GroovyXmlDataFormat(GroovyXmlDataFormat source) {
+        super(source);
+    }
+
+    private GroovyXmlDataFormat(Builder builder) {
+        this();
+    }
+
+    @Override
+    public GroovyXmlDataFormat copyDefinition() {
+        return new GroovyXmlDataFormat(this);
+    }
+
+    @XmlTransient
+    public static class Builder implements 
DataFormatBuilder<GroovyXmlDataFormat> {
+
+        @Override
+        public GroovyXmlDataFormat end() {
+            return new GroovyXmlDataFormat(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 c4b9508ae0a..efed5e764f2 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
@@ -38,6 +38,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.FlatpackDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -94,6 +95,7 @@ public class DataFormatTransformerDefinition extends 
TransformerDefinition {
             @XmlElement(name = "flatpack", type = FlatpackDataFormat.class),
             @XmlElement(name = "fory", type = ForyDataFormat.class),
             @XmlElement(name = "grok", type = GrokDataFormat.class),
+            @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class),
             @XmlElement(name = "gzipDeflater", type = 
GzipDeflaterDataFormat.class),
             @XmlElement(name = "hl7", type = HL7DataFormat.class),
             @XmlElement(name = "ical", type = IcalDataFormat.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 746fb2efc30..c63742d80e0 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
@@ -170,6 +170,8 @@ public abstract class DataFormatReifier<T extends 
DataFormatDefinition> extends
             return new ForyDataFormatReifier(camelContext, definition);
         } else if (definition instanceof GrokDataFormat) {
             return new GrokDataFormatReifier(camelContext, definition);
+        } else if (definition instanceof GroovyXmlDataFormat) {
+            return new GroovyXmlDataFormatReifier(camelContext, definition);
         } else if (definition instanceof GzipDeflaterDataFormat) {
             return new GzipDataFormatReifier(camelContext, definition);
         } else if (definition instanceof HL7DataFormat) {
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyXmlDataFormatReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyXmlDataFormatReifier.java
new file mode 100644
index 00000000000..9a0c7186ef1
--- /dev/null
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyXmlDataFormatReifier.java
@@ -0,0 +1,36 @@
+/*
+ * 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.GroovyXmlDataFormat;
+
+public class GroovyXmlDataFormatReifier extends 
DataFormatReifier<GroovyXmlDataFormat> {
+
+    public GroovyXmlDataFormatReifier(CamelContext camelContext, 
DataFormatDefinition definition) {
+        super(camelContext, (GroovyXmlDataFormat) definition);
+    }
+
+    @Override
+    protected void prepareDataFormatConfig(Map<String, Object> properties) {
+        // noop
+    }
+
+}
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 ac36ca06f71..a71e6f2ab78 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
@@ -17,6 +17,7 @@ fhirXml
 flatpack
 fory
 grok
+groovyXml
 gson
 gzipDeflater
 hl7
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 8e525098da9..a575ff497ea 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
@@ -1950,6 +1950,9 @@ public class ModelParser extends BaseParser {
                 default: yield identifiedTypeAttributeHandler().accept(def, 
key, val);
             }, noElementHandler(), noValueHandler());
     }
+    protected GroovyXmlDataFormat doParseGroovyXmlDataFormat() throws 
IOException, XmlPullParserException {
+        return doParse(new GroovyXmlDataFormat(), 
identifiedTypeAttributeHandler(), noElementHandler(), noValueHandler());
+    }
     protected GzipDeflaterDataFormat doParseGzipDeflaterDataFormat() throws 
IOException, XmlPullParserException {
         return doParse(new GzipDeflaterDataFormat(), 
identifiedTypeAttributeHandler(), noElementHandler(), noValueHandler());
     }
@@ -2947,6 +2950,7 @@ public class ModelParser extends BaseParser {
             case "flatpack": return doParseFlatpackDataFormat();
             case "fory": return doParseForyDataFormat();
             case "grok": return doParseGrokDataFormat();
+            case "groovyXml": return doParseGroovyXmlDataFormat();
             case "gzipDeflater": return doParseGzipDeflaterDataFormat();
             case "hl7": return doParseHL7DataFormat();
             case "ical": return doParseIcalDataFormat();
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 6d6e3595b4e..6a10dc289b9 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
@@ -490,6 +490,9 @@ public class ModelWriter extends BaseWriter {
     public void writeGrokDataFormat(GrokDataFormat def) throws IOException {
         doWriteGrokDataFormat("grok", def);
     }
+    public void writeGroovyXmlDataFormat(GroovyXmlDataFormat def) throws 
IOException {
+        doWriteGroovyXmlDataFormat("groovyXml", def);
+    }
     public void writeGzipDeflaterDataFormat(GzipDeflaterDataFormat def) throws 
IOException {
         doWriteGzipDeflaterDataFormat("gzipDeflater", def);
     }
@@ -1214,6 +1217,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -1974,6 +1978,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -2535,6 +2540,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -2642,6 +2648,11 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowMultipleMatchesPerLine", 
def.getAllowMultipleMatchesPerLine(), "true");
         endElement(name);
     }
+    protected void doWriteGroovyXmlDataFormat(String name, GroovyXmlDataFormat 
def) throws IOException {
+        startElement(name);
+        doWriteIdentifiedTypeAttributes(def);
+        endElement(name);
+    }
     protected void doWriteGzipDeflaterDataFormat(String name, 
GzipDeflaterDataFormat def) throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
@@ -3668,6 +3679,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index 02f328a673c..16a2c0b665b 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -490,6 +490,9 @@ public class ModelWriter extends BaseWriter {
     public void writeGrokDataFormat(GrokDataFormat def) throws IOException {
         doWriteGrokDataFormat("grok", def);
     }
+    public void writeGroovyXmlDataFormat(GroovyXmlDataFormat def) throws 
IOException {
+        doWriteGroovyXmlDataFormat("groovyXml", def);
+    }
     public void writeGzipDeflaterDataFormat(GzipDeflaterDataFormat def) throws 
IOException {
         doWriteGzipDeflaterDataFormat("gzipDeflater", def);
     }
@@ -1214,6 +1217,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -1974,6 +1978,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -2535,6 +2540,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
@@ -2642,6 +2648,11 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowMultipleMatchesPerLine", 
def.getAllowMultipleMatchesPerLine(), "true");
         endElement(name);
     }
+    protected void doWriteGroovyXmlDataFormat(String name, GroovyXmlDataFormat 
def) throws IOException {
+        startElement(name);
+        doWriteIdentifiedTypeAttributes(def);
+        endElement(name);
+    }
     protected void doWriteGzipDeflaterDataFormat(String name, 
GzipDeflaterDataFormat def) throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
@@ -3668,6 +3679,7 @@ public class ModelWriter extends BaseWriter {
                 case "FlatpackDataFormat" -> 
doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v);
                 case "ForyDataFormat" -> doWriteForyDataFormat("fory", 
(ForyDataFormat) v);
                 case "GrokDataFormat" -> doWriteGrokDataFormat("grok", 
(GrokDataFormat) v);
+                case "GroovyXmlDataFormat" -> 
doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v);
                 case "GzipDeflaterDataFormat" -> 
doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v);
                 case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", 
(HL7DataFormat) v);
                 case "IcalDataFormat" -> doWriteIcalDataFormat("ical", 
(IcalDataFormat) v);
diff --git a/docs/components/modules/dataformats/examples/json/groovyXml.json 
b/docs/components/modules/dataformats/examples/json/groovyXml.json
new file mode 120000
index 00000000000..a9be9ce2af6
--- /dev/null
+++ b/docs/components/modules/dataformats/examples/json/groovyXml.json
@@ -0,0 +1 @@
+../../../../../../components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
\ No newline at end of file
diff --git a/docs/components/modules/dataformats/nav.adoc 
b/docs/components/modules/dataformats/nav.adoc
index e7763d999d9..556396f55d6 100644
--- a/docs/components/modules/dataformats/nav.adoc
+++ b/docs/components/modules/dataformats/nav.adoc
@@ -18,6 +18,7 @@
 ** xref:flatpack-dataformat.adoc[Flatpack]
 ** xref:fory-dataformat.adoc[Fory]
 ** xref:grok-dataformat.adoc[Grok]
+** xref:groovyXml-dataformat.adoc[Groovy XML]
 ** xref:gzipDeflater-dataformat.adoc[GZip Deflater]
 ** xref:hl7-dataformat.adoc[HL7]
 ** xref:ical-dataformat.adoc[iCal]
diff --git 
a/docs/components/modules/dataformats/pages/groovyXml-dataformat.adoc 
b/docs/components/modules/dataformats/pages/groovyXml-dataformat.adoc
new file mode 120000
index 00000000000..42c399c4f92
--- /dev/null
+++ b/docs/components/modules/dataformats/pages/groovyXml-dataformat.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
\ No newline at end of file
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 6cdf9659ca7..15b529e827e 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
@@ -152,6 +152,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat;
 import org.apache.camel.model.dataformat.FlatpackDataFormat;
 import org.apache.camel.model.dataformat.ForyDataFormat;
 import org.apache.camel.model.dataformat.GrokDataFormat;
+import org.apache.camel.model.dataformat.GroovyXmlDataFormat;
 import org.apache.camel.model.dataformat.GzipDeflaterDataFormat;
 import org.apache.camel.model.dataformat.HL7DataFormat;
 import org.apache.camel.model.dataformat.IcalDataFormat;
@@ -3498,6 +3499,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "fory", type = 
"object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "fromType", type = "string", 
description = "Set the 'from' data type name. If you specify 'xml:XYZ', the 
transformer will be picked up if source type is 'xml:XYZ'. If you specify just 
'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 
'xml:DEF'.", displayName = "From Type"),
                     @YamlProperty(name = "grok", type = 
"object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = 
"dataFormatType"),
+                    @YamlProperty(name = "groovyXml", type = 
"object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "gzipDeflater", type = 
"object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "hl7", type = 
"object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "ical", type = 
"object:org.apache.camel.model.dataformat.IcalDataFormat", oneOf = 
"dataFormatType"),
@@ -3626,6 +3628,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "groovyXml": {
+                    org.apache.camel.model.dataformat.GroovyXmlDataFormat val 
= asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "gzipDeflater": {
                     org.apache.camel.model.dataformat.GzipDeflaterDataFormat 
val = asType(node, 
org.apache.camel.model.dataformat.GzipDeflaterDataFormat.class);
                     target.setDataFormatType(val);
@@ -3817,6 +3824,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "flatpack", type = 
"object:org.apache.camel.model.dataformat.FlatpackDataFormat"),
                     @YamlProperty(name = "fory", type = 
"object:org.apache.camel.model.dataformat.ForyDataFormat"),
                     @YamlProperty(name = "grok", type = 
"object:org.apache.camel.model.dataformat.GrokDataFormat"),
+                    @YamlProperty(name = "groovyXml", type = 
"object:org.apache.camel.model.dataformat.GroovyXmlDataFormat"),
                     @YamlProperty(name = "gzipDeflater", type = 
"object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat"),
                     @YamlProperty(name = "hl7", type = 
"object:org.apache.camel.model.dataformat.HL7DataFormat"),
                     @YamlProperty(name = "ical", type = 
"object:org.apache.camel.model.dataformat.IcalDataFormat"),
@@ -4017,6 +4025,16 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormats(existing);
                     break;
                 }
+                case "groovyXml": {
+                    org.apache.camel.model.dataformat.GroovyXmlDataFormat val 
= asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.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 "gzipDeflater": {
                     org.apache.camel.model.dataformat.GzipDeflaterDataFormat 
val = asType(node, 
org.apache.camel.model.dataformat.GzipDeflaterDataFormat.class);
                     
java.util.List<org.apache.camel.model.DataFormatDefinition> existing = 
target.getDataFormats();
@@ -6666,6 +6684,43 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
         }
     }
 
+    @YamlType(
+            nodes = "groovyXml",
+            types = 
org.apache.camel.model.dataformat.GroovyXmlDataFormat.class,
+            order = 
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+            displayName = "Groovy XML",
+            description = "Transform between XML and Groovy Node (Map 
structure) objects.",
+            deprecated = false,
+            properties = @YamlProperty(name = "id", type = "string", 
description = "The id of this node", displayName = "Id")
+    )
+    public static class GroovyXmlDataFormatDeserializer extends 
YamlDeserializerBase<GroovyXmlDataFormat> {
+        public GroovyXmlDataFormatDeserializer() {
+            super(GroovyXmlDataFormat.class);
+        }
+
+        @Override
+        protected GroovyXmlDataFormat newInstance() {
+            return new GroovyXmlDataFormat();
+        }
+
+        @Override
+        protected boolean setProperty(GroovyXmlDataFormat 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;
+                }
+                default: {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     @YamlType(
             nodes = "gzipDeflater",
             types = 
org.apache.camel.model.dataformat.GzipDeflaterDataFormat.class,
@@ -9711,6 +9766,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "flatpack", type = 
"object:org.apache.camel.model.dataformat.FlatpackDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "fory", type = 
"object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "grok", type = 
"object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = 
"dataFormatType"),
+                    @YamlProperty(name = "groovyXml", type = 
"object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "gzipDeflater", type = 
"object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "hl7", type = 
"object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "ical", type = 
"object:org.apache.camel.model.dataformat.IcalDataFormat", oneOf = 
"dataFormatType"),
@@ -9844,6 +9900,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "groovyXml": {
+                    org.apache.camel.model.dataformat.GroovyXmlDataFormat val 
= asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "gzipDeflater": {
                     org.apache.camel.model.dataformat.GzipDeflaterDataFormat 
val = asType(node, 
org.apache.camel.model.dataformat.GzipDeflaterDataFormat.class);
                     target.setDataFormatType(val);
@@ -19889,6 +19950,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "flatpack", type = 
"object:org.apache.camel.model.dataformat.FlatpackDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "fory", type = 
"object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "grok", type = 
"object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = 
"dataFormatType"),
+                    @YamlProperty(name = "groovyXml", type = 
"object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "gzipDeflater", type = 
"object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "hl7", type = 
"object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = 
"dataFormatType"),
                     @YamlProperty(name = "ical", type = 
"object:org.apache.camel.model.dataformat.IcalDataFormat", oneOf = 
"dataFormatType"),
@@ -20027,6 +20089,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setDataFormatType(val);
                     break;
                 }
+                case "groovyXml": {
+                    org.apache.camel.model.dataformat.GroovyXmlDataFormat val 
= asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class);
+                    target.setDataFormatType(val);
+                    break;
+                }
                 case "gzipDeflater": {
                     org.apache.camel.model.dataformat.GzipDeflaterDataFormat 
val = asType(node, 
org.apache.camel.model.dataformat.GzipDeflaterDataFormat.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 30e9ad08aa7..d0dc62d2e8f 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
@@ -151,6 +151,8 @@ public final class ModelDeserializersResolver implements 
YamlDeserializerResolve
             case "org.apache.camel.model.dataformat.GrokDataFormat": return 
new ModelDeserializers.GrokDataFormatDeserializer();
             case "groovy": return new 
ModelDeserializers.GroovyExpressionDeserializer();
             case "org.apache.camel.model.language.GroovyExpression": return 
new ModelDeserializers.GroovyExpressionDeserializer();
+            case "groovyXml": return new 
ModelDeserializers.GroovyXmlDataFormatDeserializer();
+            case "org.apache.camel.model.dataformat.GroovyXmlDataFormat": 
return new ModelDeserializers.GroovyXmlDataFormatDeserializer();
             case "gzipDeflater": return new 
ModelDeserializers.GzipDeflaterDataFormatDeserializer();
             case "org.apache.camel.model.dataformat.GzipDeflaterDataFormat": 
return new ModelDeserializers.GzipDeflaterDataFormatDeserializer();
             case "hl7": return new 
ModelDeserializers.HL7DataFormatDeserializer();
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 17e44b43c17..97486a3490e 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
@@ -2863,6 +2863,8 @@
                 "required" : [ "fory" ]
               }, {
                 "required" : [ "grok" ]
+              }, {
+                "required" : [ "groovyXml" ]
               }, {
                 "required" : [ "gzipDeflater" ]
               }, {
@@ -3041,6 +3043,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "groovyXml" ],
+            "properties" : {
+              "groovyXml" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "gzipDeflater" ],
@@ -3309,6 +3319,7 @@
           "flatpack" : { },
           "fory" : { },
           "grok" : { },
+          "groovyXml" : { },
           "gzipDeflater" : { },
           "hl7" : { },
           "ical" : { },
@@ -7788,6 +7799,7 @@
           "flatpack" : { },
           "fory" : { },
           "grok" : { },
+          "groovyXml" : { },
           "gzipDeflater" : { },
           "hl7" : { },
           "ical" : { },
@@ -7860,6 +7872,8 @@
                 "required" : [ "fory" ]
               }, {
                 "required" : [ "grok" ]
+              }, {
+                "required" : [ "groovyXml" ]
               }, {
                 "required" : [ "gzipDeflater" ]
               }, {
@@ -8038,6 +8052,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "groovyXml" ],
+            "properties" : {
+              "groovyXml" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "gzipDeflater" ],
@@ -10638,6 +10660,9 @@
           "grok" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat"
           },
+          "groovyXml" : {
+            "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+          },
           "gzipDeflater" : {
             "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GzipDeflaterDataFormat"
           },
@@ -11088,6 +11113,19 @@
         },
         "required" : [ "pattern" ]
       },
+      "org.apache.camel.model.dataformat.GroovyXmlDataFormat" : {
+        "title" : "Groovy XML",
+        "description" : "Transform between XML and Groovy Node (Map structure) 
objects.",
+        "type" : "object",
+        "additionalProperties" : false,
+        "properties" : {
+          "id" : {
+            "type" : "string",
+            "title" : "Id",
+            "description" : "The id of this node"
+          }
+        }
+      },
       "org.apache.camel.model.dataformat.GzipDeflaterDataFormat" : {
         "title" : "GZip Deflater",
         "description" : "Compress and decompress messages using 
java.util.zip.GZIPStream.",
@@ -16398,6 +16436,8 @@
                 "required" : [ "fory" ]
               }, {
                 "required" : [ "grok" ]
+              }, {
+                "required" : [ "groovyXml" ]
               }, {
                 "required" : [ "gzipDeflater" ]
               }, {
@@ -16568,6 +16608,14 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat"
               }
             }
+          }, {
+            "type" : "object",
+            "required" : [ "groovyXml" ],
+            "properties" : {
+              "groovyXml" : {
+                "$ref" : 
"#/items/definitions/org.apache.camel.model.dataformat.GroovyXmlDataFormat"
+              }
+            }
           }, {
             "type" : "object",
             "required" : [ "gzipDeflater" ],
@@ -16830,6 +16878,7 @@
           "flatpack" : { },
           "fory" : { },
           "grok" : { },
+          "groovyXml" : { },
           "gzipDeflater" : { },
           "hl7" : { },
           "ical" : { },
diff --git a/parent/pom.xml b/parent/pom.xml
index fc653bec28b..76eb6db9c31 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1437,6 +1437,11 @@
                 <artifactId>camel-groovy</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-groovy-xml</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-grpc</artifactId>

Reply via email to