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

igarashitm 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 1208229b416c CAMEL-23669: camel-hl7 - Support converting to XML
1208229b416c is described below

commit 1208229b416c9bf63abcdc4553568d84f3308089
Author: Tomohisa Igarashi <[email protected]>
AuthorDate: Tue Jun 2 14:15:40 2026 -0400

    CAMEL-23669: camel-hl7 - Support converting to XML
---
 .../org/apache/camel/catalog/dataformats/hl7.json  |  3 +-
 .../org/apache/camel/catalog/models/hl7.json       |  3 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  | 11 ++++
 .../apache/camel/catalog/schemas/camel-xml-io.xsd  | 11 ++++
 .../camel/component/hl7/HL7ConverterLoader.java    |  8 +++
 .../component/hl7/HL7DataFormatConfigurer.java     |  7 ++
 .../org/apache/camel/component/hl7/hl7.json        |  3 +-
 .../camel-hl7/src/main/docs/hl7-dataformat.adoc    | 56 ++++++++++++++++
 .../apache/camel/component/hl7/HL7Converter.java   | 30 +++++++++
 .../apache/camel/component/hl7/HL7DataFormat.java  | 31 ++++++++-
 .../camel/component/hl7/HL7XmlDataFormatTest.java  | 77 +++++++++++++++++++++-
 .../org/apache/camel/model/dataformat/hl7.json     |  3 +-
 .../camel/model/dataformat/HL7DataFormat.java      | 29 ++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  1 +
 .../org/apache/camel/yaml/out/YamlModelWriter.java |  1 +
 .../dsl/yaml/deserializers/ModelDeserializers.java |  6 ++
 .../resources/schema/camelYamlDsl-canonical.json   |  6 ++
 .../generated/resources/schema/camelYamlDsl.json   |  6 ++
 19 files changed, 284 insertions(+), 9 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/hl7.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/hl7.json
index b0c0a0d6a4d0..af79ab998c68 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/hl7.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/hl7.json
@@ -18,6 +18,7 @@
   "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" },
     "parser": { "index": 1, "kind": "attribute", "displayName": "Parser", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "ca.uhn.hl7v2.parser.Parser", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom HL7 parser" },
-    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." }
+    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." },
+    "targetFormat": { "index": 3, "kind": "attribute", "displayName": "Target 
Format", "group": "common", "required": false, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "XML" ], "deprecated": false, "autowired": false, 
"secret": false, "description": "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an X [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/hl7.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/hl7.json
index 0276a2252125..01c4467712f8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/hl7.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/hl7.json
@@ -15,6 +15,7 @@
   "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" },
     "parser": { "index": 1, "kind": "attribute", "displayName": "Parser", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "ca.uhn.hl7v2.parser.Parser", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom HL7 parser" },
-    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." }
+    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." },
+    "targetFormat": { "index": 3, "kind": "attribute", "displayName": "Target 
Format", "group": "common", "required": false, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "XML" ], "deprecated": false, "autowired": false, 
"secret": false, "description": "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an X [...]
   }
 }
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 3195e51d6614..d8333f69fbd4 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
@@ -8920,6 +8920,17 @@ To use a custom HL7 parser.
             <xs:documentation xml:lang="en">
 <![CDATA[
 Whether to validate the HL7 message Is by default true. Default value: true
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="targetFormat" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+The target format for marshal output and unmarshal result type. By default, 
marshal encodes to HL7 ER7, and unmarshal
+returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an XML DOM
+Document.
 ]]>
             </xs:documentation>
           </xs:annotation>
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 690e7958f3d6..58730483c54e 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
@@ -7583,6 +7583,17 @@ To use a custom HL7 parser.
             <xs:documentation xml:lang="en">
 <![CDATA[
 Whether to validate the HL7 message Is by default true. Default value: true
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="targetFormat" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+The target format for marshal output and unmarshal result type. By default, 
marshal encodes to HL7 ER7, and unmarshal
+returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an XML DOM
+Document.
 ]]>
             </xs:documentation>
           </xs:annotation>
diff --git 
a/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7ConverterLoader.java
 
b/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7ConverterLoader.java
index 32f556b2f362..d0e5152009b8 100644
--- 
a/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7ConverterLoader.java
+++ 
b/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7ConverterLoader.java
@@ -68,6 +68,14 @@ public final class HL7ConverterLoader implements 
TypeConverterLoader, CamelConte
                 }
                 return answer;
             });
+        addTypeConverter(registry, ca.uhn.hl7v2.model.Message.class, 
org.w3c.dom.Document.class, false,
+            (type, exchange, value) -> {
+                Object answer = 
org.apache.camel.component.hl7.HL7Converter.toMessage((org.w3c.dom.Document) 
value);
+                if (false && answer == null) {
+                    answer = Void.class;
+                }
+                return answer;
+            });
         addTypeConverter(registry, java.lang.String.class, 
ca.uhn.hl7v2.model.Message.class, false,
             (type, exchange, value) -> {
                 Object answer = 
org.apache.camel.component.hl7.HL7Converter.toString((ca.uhn.hl7v2.model.Message)
 value);
diff --git 
a/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7DataFormatConfigurer.java
 
b/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7DataFormatConfigurer.java
index 0c674bd0c8da..dfeba67564fe 100644
--- 
a/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7DataFormatConfigurer.java
+++ 
b/components/camel-hl7/src/generated/java/org/apache/camel/component/hl7/HL7DataFormatConfigurer.java
@@ -23,6 +23,7 @@ public class HL7DataFormatConfigurer extends 
org.apache.camel.support.component.
     static {
         Map<String, Object> map = new CaseInsensitiveMap();
         map.put("Parser", ca.uhn.hl7v2.parser.Parser.class);
+        map.put("TargetFormat", java.lang.String.class);
         map.put("Validate", boolean.class);
         ALL_OPTIONS = map;
     }
@@ -32,6 +33,8 @@ public class HL7DataFormatConfigurer extends 
org.apache.camel.support.component.
         HL7DataFormat target = (HL7DataFormat) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "parser": target.setParser(property(camelContext, 
ca.uhn.hl7v2.parser.Parser.class, value)); return true;
+        case "targetformat":
+        case "targetFormat": target.setTargetFormat(property(camelContext, 
java.lang.String.class, value)); return true;
         case "validate": target.setValidate(property(camelContext, 
boolean.class, value)); return true;
         default: return false;
         }
@@ -46,6 +49,8 @@ public class HL7DataFormatConfigurer extends 
org.apache.camel.support.component.
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "parser": return ca.uhn.hl7v2.parser.Parser.class;
+        case "targetformat":
+        case "targetFormat": return java.lang.String.class;
         case "validate": return boolean.class;
         default: return null;
         }
@@ -56,6 +61,8 @@ public class HL7DataFormatConfigurer extends 
org.apache.camel.support.component.
         HL7DataFormat target = (HL7DataFormat) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "parser": return target.getParser();
+        case "targetformat":
+        case "targetFormat": return target.getTargetFormat();
         case "validate": return target.isValidate();
         default: return null;
         }
diff --git 
a/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7.json
 
b/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7.json
index b0c0a0d6a4d0..af79ab998c68 100644
--- 
a/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7.json
+++ 
b/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7.json
@@ -18,6 +18,7 @@
   "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" },
     "parser": { "index": 1, "kind": "attribute", "displayName": "Parser", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "ca.uhn.hl7v2.parser.Parser", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom HL7 parser" },
-    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." }
+    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." },
+    "targetFormat": { "index": 3, "kind": "attribute", "displayName": "Target 
Format", "group": "common", "required": false, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "XML" ], "deprecated": false, "autowired": false, 
"secret": false, "description": "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an X [...]
   }
 }
diff --git a/components/camel-hl7/src/main/docs/hl7-dataformat.adoc 
b/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
index 4d35e1fef648..31f1d6fccbe0 100644
--- a/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
+++ b/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
@@ -265,6 +265,62 @@ separators anymore by converting `\n` to `\r`. If you  +
 `Expression` for this purpose.
 
 
+=== Target Format
+
+By default, the HL7 DataFormat works with HAPI `Message` objects and ER7 
(pipe-delimited) encoding.
+The `targetFormat` option can be set to `XML` to change the output format:
+
+* *marshal* encodes the HAPI Message to HL7 XML bytes instead of ER7.
+* *unmarshal* returns an `org.w3c.dom.Document` instead of a HAPI `Message`.
+
+The input format is always auto-detected. Both ER7 and XML inputs are accepted 
by the parser.
+For marshal, the input body can be a HAPI `Message` or an XML `Document` — the 
registered
+TypeConverter handles `Document` to `Message` conversion automatically.
+
+==== EDI to XML conversion
+
+[source,java]
+----
+  HL7DataFormat hl7xml = new HL7DataFormat();
+  hl7xml.setTargetFormat("XML");
+
+  from("direct:hl7in")
+    .unmarshal(hl7xml)
+    .to("direct:xmlout");
+----
+
+In this example, the HL7 EDI input is unmarshalled directly to an XML 
`Document`.
+
+==== XML to Message conversion
+
+[source,java]
+----
+  HL7DataFormat hl7xml = new HL7DataFormat();
+  hl7xml.setTargetFormat("XML");
+
+  from("direct:messageIn")
+    .marshal(hl7xml)
+    .to("direct:xmlout");
+----
+
+Here, a HAPI `Message` is marshalled to HL7 XML bytes.
+
+==== Round-trip EDI to XML to EDI
+
+[source,java]
+----
+  HL7DataFormat hl7xml = new HL7DataFormat();
+  hl7xml.setTargetFormat("XML");
+  HL7DataFormat hl7 = new HL7DataFormat();
+
+  from("direct:hl7in")
+    .unmarshal(hl7xml)
+    .marshal(hl7)
+    .to("direct:hl7out");
+----
+
+The EDI input is converted to an XML Document, then back to EDI.
+
 === Charset
 
 Both `marshal and unmarshal` evaluate the charset
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java
index 80e0683bcdb7..3fc8b6bc80e1 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java
@@ -18,6 +18,9 @@ package org.apache.camel.component.hl7;
 
 import java.io.IOException;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
 import ca.uhn.hl7v2.DefaultHapiContext;
 import ca.uhn.hl7v2.HL7Exception;
 import ca.uhn.hl7v2.HapiContext;
@@ -25,6 +28,7 @@ import ca.uhn.hl7v2.model.Message;
 import ca.uhn.hl7v2.parser.DefaultModelClassFactory;
 import ca.uhn.hl7v2.parser.ParserConfiguration;
 import ca.uhn.hl7v2.parser.UnexpectedSegmentBehaviourEnum;
+import ca.uhn.hl7v2.parser.XMLParser;
 import ca.uhn.hl7v2.validation.impl.ValidationContextFactory;
 import org.apache.camel.Converter;
 import org.apache.camel.Exchange;
@@ -72,4 +76,30 @@ public final class HL7Converter {
         return 
DEFAULT_CONTEXT.getGenericParser().parse(IOConverter.toString(body, exchange));
     }
 
+    @Converter
+    public static Message toMessage(Document doc) throws HL7Exception {
+        String version = getVersionFromDocument(doc);
+        return ((XMLParser) DEFAULT_CONTEXT.getXMLParser()).parseDocument(doc, 
version);
+    }
+
+    private static final String HL7_V2_XML_NAMESPACE = "urn:hl7-org:v2xml";
+
+    static String getVersionFromDocument(Document doc) {
+        NodeList nodes = doc.getElementsByTagNameNS(HL7_V2_XML_NAMESPACE, 
"VID.1");
+        if (nodes.getLength() > 0) {
+            String version = nodes.item(0).getTextContent();
+            if (version != null && !version.trim().isEmpty()) {
+                return version.trim();
+            }
+        }
+        nodes = doc.getElementsByTagNameNS(HL7_V2_XML_NAMESPACE, "MSH.12");
+        if (nodes.getLength() > 0) {
+            String version = nodes.item(0).getTextContent();
+            if (version != null && !version.trim().isEmpty()) {
+                return version.trim();
+            }
+        }
+        return null;
+    }
+
 }
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java
index 64f40446838d..27298829a3e1 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java
@@ -64,8 +64,15 @@ import static 
org.apache.camel.component.hl7.HL7Constants.HL7_VERSION_ID;
  * <p/>
  * Uses the <a href="https://hapifhir.github.io/hapi-hl7v2/index.html";>HAPI 
(HL7 API)</a> for HL7 parsing.
  * <p/>
- * Uses the default GenericParser from the HAPI API. This DataFormat 
<b>only</b> supports both the EDI based HL7
- * messages and the XML based messages.
+ * Uses the default GenericParser from the HAPI API. This DataFormat supports 
both the ER7 (pipe-delimited) and XML
+ * based HL7 messages. The input format is auto-detected by the GenericParser.
+ * <p/>
+ * The {@code targetFormat} option controls the output format. When set to 
{@code XML}:
+ * <ul>
+ * <li>marshal encodes the HAPI Message to HL7 XML bytes instead of ER7. The 
input body can be either a HAPI Message or
+ * an XML Document (converted to Message automatically via the registered 
TypeConverter).</li>
+ * <li>unmarshal returns an {@link org.w3c.dom.Document} instead of a HAPI 
Message.</li>
+ * </ul>
  * <p/>
  * The <tt>unmarshal</tt> operation adds these MSH fields as headers on the 
Camel message (key, MSH-field):
  * <ul>
@@ -95,6 +102,7 @@ public class HL7DataFormat extends ServiceSupport implements 
DataFormat, DataFor
     private HapiContext hapiContext;
     private Parser parser;
     private boolean validate = true;
+    private String targetFormat;
 
     static {
         HEADER_MAP.put(HL7_SENDING_APPLICATION, "MSH-3");
@@ -120,7 +128,12 @@ public class HL7DataFormat extends ServiceSupport 
implements DataFormat, DataFor
     public void marshal(Exchange exchange, Object body, OutputStream 
outputStream) throws Exception {
         Message message = ExchangeHelper.convertToMandatoryType(exchange, 
Message.class, body);
         String charsetName = HL7Charset.getCharsetName(message, exchange);
-        String encoded = parser.encode(message);
+        String encoded;
+        if ("XML".equalsIgnoreCase(targetFormat)) {
+            encoded = hapiContext.getXMLParser().encode(message);
+        } else {
+            encoded = parser.encode(message);
+        }
         outputStream.write(encoded.getBytes(charsetName));
     }
 
@@ -138,6 +151,10 @@ public class HL7DataFormat extends ServiceSupport 
implements DataFormat, DataFor
         }
         exchange.getOut().setHeader(HL7_CONTEXT, hapiContext);
         exchange.getOut().setHeader(Exchange.CHARSET_NAME, charsetName);
+
+        if ("XML".equalsIgnoreCase(targetFormat)) {
+            return hapiContext.getXMLParser().encodeDocument(message);
+        }
         return message;
     }
 
@@ -165,6 +182,14 @@ public class HL7DataFormat extends ServiceSupport 
implements DataFormat, DataFor
         this.parser = parser;
     }
 
+    public String getTargetFormat() {
+        return targetFormat;
+    }
+
+    public void setTargetFormat(String targetFormat) {
+        this.targetFormat = targetFormat;
+    }
+
     @Override
     protected void doStart() throws Exception {
         if (hapiContext == null) {
diff --git 
a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7XmlDataFormatTest.java
 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7XmlDataFormatTest.java
index 37f7f4e1d22b..5b639b768a8d 100644
--- 
a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7XmlDataFormatTest.java
+++ 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7XmlDataFormatTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.hl7;
 
+import org.w3c.dom.Document;
+
 import ca.uhn.hl7v2.DefaultHapiContext;
 import ca.uhn.hl7v2.HapiContext;
 import ca.uhn.hl7v2.model.Message;
@@ -28,8 +30,7 @@ import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit6.CamelTestSupport;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 
 public class HL7XmlDataFormatTest extends CamelTestSupport {
 
@@ -62,6 +63,67 @@ public class HL7XmlDataFormatTest extends CamelTestSupport {
         assertEquals("O01", new Terser(received).get("MSH-9-2"));
     }
 
+    @Test
+    public void testUnmarshalXmlFormat() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:unmarshalXml");
+        mock.expectedMessageCount(1);
+
+        String body = createHL7AsString();
+        template.sendBody("direct:unmarshalXml", body);
+
+        MockEndpoint.assertIsSatisfied(context);
+        Object rawBody = mock.getReceivedExchanges().get(0).getIn().getBody();
+        assertNotNull(rawBody);
+        assertInstanceOf(Document.class, rawBody);
+        Document doc = (Document) rawBody;
+        assertEquals("ORM_O01", doc.getDocumentElement().getLocalName());
+    }
+
+    @Test
+    public void testMarshalXmlFromDocument() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshalFromDoc");
+        mock.expectedMessageCount(1);
+
+        String body = createHL7AsString();
+        Message msg = hl7.getParser().parse(body);
+        String xml = hl7.getParser().encode(msg, "XML");
+        template.sendBody("direct:marshalFromDoc", xml);
+
+        MockEndpoint.assertIsSatisfied(context);
+        String edi = 
mock.getReceivedExchanges().get(0).getIn().getBody(String.class);
+        assertTrue(edi.contains("MSH|^~\\&|"));
+        assertTrue(edi.contains("ORM^O01"));
+    }
+
+    @Test
+    public void testMarshalXmlOutput() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshalXmlOutput");
+        mock.expectedMessageCount(1);
+
+        String body = createHL7AsString();
+        Message msg = hl7.getParser().parse(body);
+        template.sendBody("direct:marshalXmlOutput", msg);
+
+        MockEndpoint.assertIsSatisfied(context);
+        String xml = 
mock.getReceivedExchanges().get(0).getIn().getBody(String.class);
+        assertTrue(xml.contains("<ORM_O01"));
+        assertTrue(xml.contains("urn:hl7-org:v2xml"));
+    }
+
+    @Test
+    public void testRoundTripEdiToXmlToEdi() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:roundtrip");
+        mock.expectedMessageCount(1);
+
+        String body = createHL7AsString();
+        template.sendBody("direct:roundtrip", body);
+
+        MockEndpoint.assertIsSatisfied(context);
+        String edi = 
mock.getReceivedExchanges().get(0).getIn().getBody(String.class);
+        assertTrue(edi.contains("MSH|^~\\&|"));
+        assertTrue(edi.contains("ORM^O01"));
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         HapiContext hapiContext = new DefaultHapiContext();
@@ -70,10 +132,21 @@ public class HL7XmlDataFormatTest extends CamelTestSupport 
{
         hl7 = new HL7DataFormat();
         hl7.setParser(p);
 
+        final HL7DataFormat hl7Xml = new HL7DataFormat();
+        hl7Xml.setTargetFormat("XML");
+        hl7Xml.setValidate(false);
+
+        final HL7DataFormat hl7Default = new HL7DataFormat();
+        hl7Default.setValidate(false);
+
         return new RouteBuilder() {
             public void configure() {
                 
from("direct:unmarshalOk").unmarshal().hl7(false).to("mock:unmarshal");
                 
from("direct:unmarshalOkXml").unmarshal(hl7).to("mock:unmarshal");
+                
from("direct:unmarshalXml").unmarshal(hl7Xml).to("mock:unmarshalXml");
+                
from("direct:marshalFromDoc").marshal(hl7Default).to("mock:marshalFromDoc");
+                
from("direct:marshalXmlOutput").marshal(hl7Xml).to("mock:marshalXmlOutput");
+                
from("direct:roundtrip").unmarshal(hl7Xml).marshal(hl7Default).to("mock:roundtrip");
             }
         };
     }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/hl7.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/hl7.json
index 0276a2252125..01c4467712f8 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/hl7.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/hl7.json
@@ -15,6 +15,7 @@
   "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" },
     "parser": { "index": 1, "kind": "attribute", "displayName": "Parser", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "ca.uhn.hl7v2.parser.Parser", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom HL7 parser" },
-    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." }
+    "validate": { "index": 2, "kind": "attribute", "displayName": "Validate", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to validate the HL7 message Is by 
default true." },
+    "targetFormat": { "index": 3, "kind": "attribute", "displayName": "Target 
Format", "group": "common", "required": false, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "XML" ], "deprecated": false, "autowired": false, 
"secret": false, "description": "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an X [...]
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/HL7DataFormat.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/HL7DataFormat.java
index 968024157c90..26e6d020221b 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/HL7DataFormat.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/HL7DataFormat.java
@@ -40,6 +40,9 @@ public class HL7DataFormat extends DataFormatDefinition {
     @XmlAttribute
     @Metadata(defaultValue = "true", javaType = "java.lang.Boolean")
     private String validate;
+    @XmlAttribute
+    @Metadata(enums = "XML")
+    private String targetFormat;
 
     public HL7DataFormat() {
         super("hl7");
@@ -49,12 +52,14 @@ public class HL7DataFormat extends DataFormatDefinition {
         super(source);
         this.parser = source.parser;
         this.validate = source.validate;
+        this.targetFormat = source.targetFormat;
     }
 
     private HL7DataFormat(Builder builder) {
         this();
         this.parser = builder.parser;
         this.validate = builder.validate;
+        this.targetFormat = builder.targetFormat;
     }
 
     @Override
@@ -86,6 +91,19 @@ public class HL7DataFormat extends DataFormatDefinition {
         this.parser = parser;
     }
 
+    public String getTargetFormat() {
+        return targetFormat;
+    }
+
+    /**
+     * The target format for marshal output and unmarshal result type. By 
default, marshal encodes to HL7 ER7, and
+     * unmarshal returns a HAPI Message object. If this is set to XML, marshal 
encodes to HL7 XML, and unmarshal returns
+     * an XML DOM Document.
+     */
+    public void setTargetFormat(String targetFormat) {
+        this.targetFormat = targetFormat;
+    }
+
     /**
      * {@code Builder} is a specific builder for {@link HL7DataFormat}.
      */
@@ -94,6 +112,7 @@ public class HL7DataFormat extends DataFormatDefinition {
 
         private String parser;
         private String validate;
+        private String targetFormat;
 
         /**
          * Whether to validate the HL7 message
@@ -123,6 +142,16 @@ public class HL7DataFormat extends DataFormatDefinition {
             return this;
         }
 
+        /**
+         * The target format for marshal output and unmarshal result type. By 
default, marshal encodes to HL7 ER7, and
+         * unmarshal returns a HAPI Message object. If this is set to XML, 
marshal encodes to HL7 XML, and unmarshal
+         * returns an XML DOM Document.
+         */
+        public Builder targetFormat(String targetFormat) {
+            this.targetFormat = targetFormat;
+            return this;
+        }
+
         @Override
         public HL7DataFormat end() {
             return new HL7DataFormat(this);
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 e213cac7540a..d4f1127a263f 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
@@ -1794,6 +1794,7 @@ public class ModelParser extends BaseParser {
     protected HL7DataFormat doParseHL7DataFormat() throws IOException, 
XmlPullParserException {
         return doParse(new HL7DataFormat(), (def, key, val) -> switch (key) {
                 case "parser": def.setParser(val); yield true;
+                case "targetFormat": def.setTargetFormat(val); yield true;
                 case "validate": def.setValidate(val); yield true;
                 default: yield identifiedTypeAttributeHandler().accept(def, 
key, val);
             }, noElementHandler(), noValueHandler());
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 a51814d0dd56..5e81fda70cc7 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
@@ -2399,6 +2399,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("parser", def.getParser(), null);
         doWriteAttribute("validate", def.getValidate(), "true");
+        doWriteAttribute("targetFormat", def.getTargetFormat(), null);
         endElement(name);
     }
     protected void doWriteIcalDataFormat(String name, IcalDataFormat def) 
throws IOException {
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
index b9ddb7fa5e4c..d48d8ce2b3b5 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
@@ -2397,6 +2397,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
         doWriteIdentifiedTypeAttributes(jo, def);
         doWriteAttribute(jo, "parser", def.getParser(), null);
         doWriteAttribute(jo, "validate", def.getValidate(), "true");
+        doWriteAttribute(jo, "targetFormat", def.getTargetFormat(), null);
         return jo;
     }
     protected JsonObject doWriteIcalDataFormat(IcalDataFormat def) {
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 45bf777d70f5..71bd1d240aca 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
@@ -6419,6 +6419,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
             properties = {
                     @YamlProperty(name = "id", type = "string", description = 
"The id of this node", displayName = "Id"),
                     @YamlProperty(name = "parser", type = "string", 
description = "To use a custom HL7 parser", displayName = "Parser"),
+                    @YamlProperty(name = "targetFormat", type = "enum:XML", 
description = "The target format for marshal output and unmarshal result type. 
By default, marshal encodes to HL7 ER7, and unmarshal returns a HAPI Message 
object. If this is set to XML, marshal encodes to HL7 XML, and unmarshal 
returns an XML DOM Document.", displayName = "Target Format"),
                     @YamlProperty(name = "validate", type = "boolean", 
defaultValue = "true", description = "Whether to validate the HL7 message Is by 
default true.", displayName = "Validate")
             }
     )
@@ -6447,6 +6448,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setParser(val);
                     break;
                 }
+                case "targetFormat": {
+                    String val = asText(node);
+                    target.setTargetFormat(val);
+                    break;
+                }
                 case "validate": {
                     String val = asText(node);
                     target.setValidate(val);
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
index 8438e7a74b37..19b822bdf87d 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
@@ -7248,6 +7248,12 @@
             "title" : "Parser",
             "description" : "To use a custom HL7 parser"
           },
+          "targetFormat" : {
+            "type" : "string",
+            "title" : "Target Format",
+            "description" : "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an XML DOM Document.",
+            "enum" : [ "XML" ]
+          },
           "validate" : {
             "type" : "boolean",
             "title" : "Validate",
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 9baa494c457e..9c2228a0d070 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
@@ -10784,6 +10784,12 @@
             "title" : "Parser",
             "description" : "To use a custom HL7 parser"
           },
+          "targetFormat" : {
+            "type" : "string",
+            "title" : "Target Format",
+            "description" : "The target format for marshal output and 
unmarshal result type. By default, marshal encodes to HL7 ER7, and unmarshal 
returns a HAPI Message object. If this is set to XML, marshal encodes to HL7 
XML, and unmarshal returns an XML DOM Document.",
+            "enum" : [ "XML" ]
+          },
           "validate" : {
             "type" : "boolean",
             "title" : "Validate",


Reply via email to