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 6b7b11af441 Fix XSD to not have duplicate entry (#16865)
6b7b11af441 is described below
commit 6b7b11af4415e4e4ffeeec29c2e4120065adbddc
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jan 20 16:51:31 2025 +0100
Fix XSD to not have duplicate entry (#16865)
* CAMEL-21632: camel-spring-xml - Fix XSD to not include duplicate ##other
entry that is caused by the parser support for importing legacy spring or
blueprint xml files for migration and tooling purposes. Added XSD validation
test to validate the generated XSD onwards. Thanks to Tobias Kleinschmidt for
validation example
---
.../apache/camel/catalog/schemas/camel-spring.xsd | 1 -
components/camel-spring-xml/pom.xml | 6 +++
.../camel/spring/CamelSpringXSDValidateTest.java | 41 ++++++++++++++++++
.../spi/annotations/ExternalSchemaElement.java | 23 ++++++++---
.../apache/camel/model/app/BeansDefinition.java | 48 +++++++---------------
.../java/org/apache/camel/xml/in/ModelParser.java | 12 +++---
.../java/org/apache/camel/xml/out/ModelWriter.java | 5 +--
.../org/apache/camel/xml/in/ModelParserTest.java | 19 +++++----
.../org/apache/camel/yaml/out/ModelWriter.java | 5 +--
.../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 30 ++++++--------
.../org/apache/camel/dsl/xml/io/springBeans.xml | 29 ++++++++++---
.../src/main/resources/velocity/model-parser.vm | 8 ++++
.../spi/annotations/ExternalSchemaElement.java | 23 ++++++++---
13 files changed, 161 insertions(+), 89 deletions(-)
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 7b650d74165..5962f3bd6ba 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
@@ -14831,7 +14831,6 @@ List of bean.
</xs:annotation>
</xs:element>
<xs:any maxOccurs="unbounded" minOccurs="0" namespace="##other"
processContents="skip"/>
- <xs:any maxOccurs="unbounded" minOccurs="0" namespace="##other"
processContents="skip"/>
<xs:element minOccurs="0" name="dataFormats">
<xs:complexType>
<xs:sequence>
diff --git a/components/camel-spring-xml/pom.xml
b/components/camel-spring-xml/pom.xml
index 4a0cb38d130..d3df2783140 100644
--- a/components/camel-spring-xml/pom.xml
+++ b/components/camel-spring-xml/pom.xml
@@ -84,6 +84,12 @@
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.springframework.ws</groupId>
+ <artifactId>spring-xml</artifactId>
+ <version>${spring-ws-version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
diff --git
a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java
b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java
new file mode 100644
index 00000000000..f3697ea4522
--- /dev/null
+++
b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.spring;
+
+import org.xml.sax.SAXParseException;
+
+import org.apache.camel.util.xml.BytesSource;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.xml.validation.XmlValidator;
+import org.springframework.xml.validation.XmlValidatorFactory;
+
+public class CamelSpringXSDValidateTest {
+
+ @Test
+ public void testValidateXSD() throws Exception {
+ Resource r = new ClassPathResource("camel-spring.xsd");
+ Resource r2 = new
ClassPathResource("org/springframework/beans/factory/xml/spring-beans.xsd");
+ XmlValidator val = XmlValidatorFactory.createValidator(new Resource[]
{ r, r2 }, XmlValidatorFactory.SCHEMA_W3C_XML);
+
+ Resource r3 = new
ClassPathResource("org/apache/camel/spring/processor/choice.xml");
+ SAXParseException[] err = val.validate(new
BytesSource(r3.getContentAsByteArray()));
+ Assertions.assertEquals(0, err.length);
+ }
+}
diff --git
a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
index da87308e0e9..5b77eb68d6c 100644
---
a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
+++
b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
@@ -33,25 +33,36 @@ public @interface ExternalSchemaElement {
/**
* Names of external XML element we expect
- *
- * @return
*/
String[] names() default {};
+ /**
+ * Names of external XML element we expect
+ */
+ String[] names2() default {};
+
/**
* XSD namespace of XML elements expected
- *
- * @return
*/
String namespace() default "";
+ /**
+ * XSD namespace of XML elements expected
+ */
+ String namespace2() default "";
+
/**
* In JAXB, when an element is annotated with {@code @XmlAnyElement}, the
actual objects used are of
* {@link org.w3c.dom.Element} class. These elements should be part of
wrapping {@link org.w3c.dom.Document} and
* this parameter allows to specify this root element name (in {@link
#namespace()}).
- *
- * @return
*/
String documentElement();
+ /**
+ * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the
actual objects used are of
+ * {@link org.w3c.dom.Element} class. These elements should be part of
wrapping {@link org.w3c.dom.Document} and
+ * this parameter allows to specify this root element name (in {@link
#namespace2()}).
+ */
+ String documentElement2();
+
}
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java
index 72d6faae36b..dd9ab235368 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java
@@ -52,8 +52,7 @@ import org.apache.camel.spi.annotations.ExternalSchemaElement;
@XmlType(propOrder = {
"componentScanning",
"beans",
- "springBeans",
- "blueprintBeans",
+ "springOrBlueprintBeans",
"dataFormats",
"restConfigurations",
"rests",
@@ -72,26 +71,19 @@ public class BeansDefinition {
// this is a place for <bean> element definition, without conflicting with
<bean> elements referring
// to "bean processors"
-
@XmlElement(name = "bean")
private List<BeanFactoryDefinition> beans = new ArrayList<>();
- // this is the only way I found to generate usable Schema without imports,
while allowing elements
- // from different namespaces
- @ExternalSchemaElement(names = { "beans", "bean", "alias" },
+ // support for legacy spring <beans> and blueprint <bean> files to be
parsed and loaded
+ // for migration and tooling effort (need to be in a single @XmlAnyElement
as otherwise
+ // this causes camel-spring-xml to generate an invalid XSD
+ @ExternalSchemaElement(names = { "beans", "bean", "alias" }, names2 =
"bean",
namespace =
"http://www.springframework.org/schema/beans",
- documentElement = "beans")
+ namespace2 =
"http://www.osgi.org/xmlns/blueprint/v1.0.0",
+ documentElement = "beans",
+ documentElement2 = "blueprint")
@XmlAnyElement
- private List<Element> springBeans = new ArrayList<>();
-
- // Blueprint XML is deprecated, but we need those so that Camel JBang can
- // load the routes and transform them
-
- @ExternalSchemaElement(names = { "bean" },
- namespace =
"http://www.osgi.org/xmlns/blueprint/v1.0.0",
- documentElement = "blueprint")
- @XmlAnyElement
- private List<Element> blueprintBeans = new ArrayList<>();
+ private List<Element> springOrBlueprintBeans = new ArrayList<>();
// the order comes from <camelContext>
(org.apache.camel.spring.xml.CamelContextFactoryBean)
// to make things less confusing, as it's not easy to simply tell JAXB to
use <xsd:choice maxOccurs="unbounded">
@@ -139,26 +131,16 @@ public class BeansDefinition {
this.beans = beans;
}
- public List<Element> getSpringBeans() {
- return springBeans;
- }
-
- /**
- * Spring XML beans
- */
- public void setSpringBeans(List<Element> springBeans) {
- this.springBeans = springBeans;
- }
-
- public List<Element> getBlueprintBeans() {
- return blueprintBeans;
+ public List<Element> getSpringOrBlueprintBeans() {
+ return springOrBlueprintBeans;
}
/**
- * Blueprint XML beans
+ * Support for legacy Spring beans and Blueprint bean files to be parsed
and loaded for migration and tooling
+ * effort.
*/
- public void setBlueprintBeans(List<Element> blueprintBeans) {
- this.blueprintBeans = blueprintBeans;
+ public void setSpringOrBlueprintBeans(List<Element>
springOrBlueprintBeans) {
+ this.springOrBlueprintBeans = springOrBlueprintBeans;
}
public List<RestConfigurationDefinition> getRestConfigurations() {
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 6b289389e57..46fa4335bdd 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
@@ -1368,18 +1368,18 @@ public class ModelParser extends BaseParser {
}
protected <T extends BeansDefinition> ElementHandler<T>
beansDefinitionElementHandler() {
return (def, key) -> {
- if
("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(parser.getNamespace())) {
- Element el = doParseDOMElement("blueprint",
"http://www.osgi.org/xmlns/blueprint/v1.0.0", def.getBlueprintBeans());
+ if
("http://www.springframework.org/schema/beans".equals(parser.getNamespace())) {
+ Element el = doParseDOMElement("beans",
"http://www.springframework.org/schema/beans", def.getSpringOrBlueprintBeans());
if (el != null) {
- doAddElement(el, def.getBlueprintBeans(),
def::setBlueprintBeans);
+ doAddElement(el, def.getSpringOrBlueprintBeans(),
def::setSpringOrBlueprintBeans);
return true;
}
return false;
}
- if
("http://www.springframework.org/schema/beans".equals(parser.getNamespace())) {
- Element el = doParseDOMElement("beans",
"http://www.springframework.org/schema/beans", def.getSpringBeans());
+ if
("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(parser.getNamespace())) {
+ Element el = doParseDOMElement("blueprint",
"http://www.osgi.org/xmlns/blueprint/v1.0.0", def.getSpringOrBlueprintBeans());
if (el != null) {
- doAddElement(el, def.getSpringBeans(),
def::setSpringBeans);
+ doAddElement(el, def.getSpringOrBlueprintBeans(),
def::setSpringOrBlueprintBeans);
return true;
}
return false;
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 931fc47b8b3..e185a32151c 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
@@ -2038,11 +2038,10 @@ public class ModelWriter extends BaseWriter {
}
protected void doWriteBeansDefinitionElements(BeansDefinition def) throws
IOException {
doWriteList(null, "route", def.getRoutes(),
this::doWriteRouteDefinition);
- domElements(def.getSpringBeans());
+ domElements(def.getSpringOrBlueprintBeans());
doWriteList("dataFormats", "dataFormat", def.getDataFormats(),
this::doWriteDataFormatDefinition);
- domElements(def.getBlueprintBeans());
- doWriteList(null, "bean", def.getBeans(),
this::doWriteBeanFactoryDefinition);
doWriteList(null, "component-scan", def.getComponentScanning(),
this::doWriteComponentScanDefinition);
+ doWriteList(null, "bean", def.getBeans(),
this::doWriteBeanFactoryDefinition);
doWriteList(null, "restConfiguration", def.getRestConfigurations(),
this::doWriteRestConfigurationDefinition);
doWriteList(null, "rest", def.getRests(), this::doWriteRestDefinition);
doWriteList(null, "routeConfiguration", def.getRouteConfigurations(),
this::doWriteRouteConfigurationDefinition);
diff --git
a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
index cda187e1fb8..c311c5b2ade 100644
---
a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
+++
b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
@@ -246,7 +246,7 @@ public class ModelParserTest {
BeansDefinition beans = parser.parseBeansDefinition().orElse(null);
assertNotNull(beans);
assertTrue(beans.getBeans().isEmpty());
- assertTrue(beans.getSpringBeans().isEmpty());
+ assertTrue(beans.getSpringOrBlueprintBeans().isEmpty());
}
@Test
@@ -257,7 +257,7 @@ public class ModelParserTest {
BeansDefinition beans = parser.parseBeansDefinition().orElse(null);
assertNotNull(beans);
assertEquals(2, beans.getBeans().size());
- assertTrue(beans.getSpringBeans().isEmpty());
+ assertTrue(beans.getSpringOrBlueprintBeans().isEmpty());
BeanFactoryDefinition b1 = beans.getBeans().get(0);
BeanFactoryDefinition b2 = beans.getBeans().get(1);
@@ -287,7 +287,7 @@ public class ModelParserTest {
BeansDefinition beans = parser.parseBeansDefinition().orElse(null);
assertNotNull(beans);
assertEquals(2, beans.getBeans().size());
- assertTrue(beans.getSpringBeans().isEmpty());
+ assertTrue(beans.getSpringOrBlueprintBeans().isEmpty());
BeanFactoryDefinition b1 = beans.getBeans().get(0);
BeanFactoryDefinition b2 = beans.getBeans().get(1);
@@ -314,7 +314,7 @@ public class ModelParserTest {
BeansDefinition beans = parser.parseBeansDefinition().orElse(null);
assertNotNull(beans);
assertEquals(2, beans.getBeans().size());
- assertTrue(beans.getSpringBeans().isEmpty());
+ assertTrue(beans.getSpringOrBlueprintBeans().isEmpty());
BeanFactoryDefinition b1 = beans.getBeans().get(0);
BeanFactoryDefinition b2 = beans.getBeans().get(1);
@@ -343,16 +343,17 @@ public class ModelParserTest {
BeansDefinition beans = parser.parseBeansDefinition().orElse(null);
assertNotNull(beans);
assertTrue(beans.getBeans().isEmpty());
- assertEquals(2, beans.getSpringBeans().size());
- Document dom = beans.getSpringBeans().get(0).getOwnerDocument();
+ assertEquals(2, beans.getSpringOrBlueprintBeans().size());
+ Document dom =
beans.getSpringOrBlueprintBeans().get(0).getOwnerDocument();
StringWriter sw = new StringWriter();
TransformerFactory.newInstance().newTransformer().transform(new
DOMSource(dom), new StreamResult(sw));
String document = sw.toString();
assertTrue(document.contains("class=\"java.lang.String\""));
- assertSame(beans.getSpringBeans().get(0).getOwnerDocument(),
beans.getSpringBeans().get(1).getOwnerDocument());
- assertEquals("s1", beans.getSpringBeans().get(0).getAttribute("id"));
- assertEquals("s2", beans.getSpringBeans().get(1).getAttribute("id"));
+ assertSame(beans.getSpringOrBlueprintBeans().get(0).getOwnerDocument(),
+ beans.getSpringOrBlueprintBeans().get(1).getOwnerDocument());
+ assertEquals("s1",
beans.getSpringOrBlueprintBeans().get(0).getAttribute("id"));
+ assertEquals("s2",
beans.getSpringOrBlueprintBeans().get(1).getAttribute("id"));
assertEquals(1, beans.getComponentScanning().size());
assertEquals("com.example",
beans.getComponentScanning().get(0).getBasePackage());
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 a4aa07d8b4e..d9d911932fa 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
@@ -2038,11 +2038,10 @@ public class ModelWriter extends BaseWriter {
}
protected void doWriteBeansDefinitionElements(BeansDefinition def) throws
IOException {
doWriteList(null, "route", def.getRoutes(),
this::doWriteRouteDefinition);
- domElements(def.getSpringBeans());
+ domElements(def.getSpringOrBlueprintBeans());
doWriteList("dataFormats", "dataFormat", def.getDataFormats(),
this::doWriteDataFormatDefinition);
- domElements(def.getBlueprintBeans());
- doWriteList(null, "bean", def.getBeans(),
this::doWriteBeanFactoryDefinition);
doWriteList(null, "component-scan", def.getComponentScanning(),
this::doWriteComponentScanDefinition);
+ doWriteList(null, "bean", def.getBeans(),
this::doWriteBeanFactoryDefinition);
doWriteList(null, "restConfiguration", def.getRestConfigurations(),
this::doWriteRestConfigurationDefinition);
doWriteList(null, "rest", def.getRests(), this::doWriteRestDefinition);
doWriteList(null, "routeConfiguration", def.getRouteConfigurations(),
this::doWriteRouteConfigurationDefinition);
diff --git
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
index 03b75a7b7c3..0e01cb758d0 100644
---
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
+++
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
@@ -322,23 +322,19 @@ public class XmlRoutesBuilderLoader extends
RouteBuilderLoaderSupport {
// <s:bean>, <s:beans> and <s:alias> elements - all the elements in
single BeansDefinition have
// one parent org.w3c.dom.Document - and this is what we collect from
each resource
- if (!app.getSpringBeans().isEmpty()) {
- Document doc = app.getSpringBeans().get(0).getOwnerDocument();
- // bind as Document, to be picked up later - bean id allows nice
sorting
- // (can also be single ID - documents will get collected in
LinkedHashMap, so we'll be fine)
- String id = String.format("camel-xml-io-dsl-spring-xml:%05d:%s",
counter.incrementAndGet(), resource.getLocation());
- getCamelContext().getRegistry().bind(id, doc);
- }
-
- // <s:bean> elements - all the elements in single BeansDefinition have
- // one parent org.w3c.dom.Document - and this is what we collect from
each resource
- if (!app.getBlueprintBeans().isEmpty()) {
- Document doc = app.getBlueprintBeans().get(0).getOwnerDocument();
- // bind as Document, to be picked up later - bean id allows nice
sorting
- // (can also be single ID - documents will get collected in
LinkedHashMap, so we'll be fine)
- String id =
String.format("camel-xml-io-dsl-blueprint-xml:%05d:%s",
counter.incrementAndGet(),
- resource.getLocation());
- getCamelContext().getRegistry().bind(id, doc);
+ if (!app.getSpringOrBlueprintBeans().isEmpty()) {
+ Document doc =
app.getSpringOrBlueprintBeans().get(0).getOwnerDocument();
+ String ns = doc.getDocumentElement().getNamespaceURI();
+ String id = null;
+ if ("http://www.springframework.org/schema/beans".equals(ns)) {
+ id = String.format("camel-xml-io-dsl-spring-xml:%05d:%s",
counter.incrementAndGet(), resource.getLocation());
+ } else if
("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(ns)) {
+ id = String.format("camel-xml-io-dsl-blueprint-xml:%05d:%s",
counter.incrementAndGet(),
+ resource.getLocation());
+ }
+ if (id != null) {
+ getCamelContext().getRegistry().bind(id, doc);
+ }
}
}
diff --git
a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml
b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml
index f1ba047e17c..3c0639abc82 100644
---
a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml
+++
b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml
@@ -23,11 +23,30 @@
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
- <camelContext id="SampleCamel"
xmlns="http://camel.apache.org/schema/spring">
-
- <route id="hello">
- <from uri="direct:hello"/>
- <to uri="mock:result"/>
+ <!-- spring beans -->
+ <bean id="orderService" class="com.foo.OrderService">
+ <argument index="0" value="true"/>
+ <argument index="1" ref="office"/>
+ </bean>
+ <!-- uses property placeholder ${xxx} syntax -->
+ <bean id="office" class="com.foo.Address">
+ <property name="zip" value="${zipCode}"/>
+ <property name="street" value="${streetName}"/>
+ </bean>
+
+ <camelContext id="SpringCamel"
xmlns="http://camel.apache.org/schema/spring">
+
+ <!-- anything inside here such as this should be skipped during
parsing -->
+ <propertyPlaceholder id="placeholder"
location="classpath:sql.properties"/>
+
+ <!-- we only parse (currently) embedded routes etc. -->
+ <route>
+ <from uri="timer:xml?period={{time:1000}}"/>
+ <setBody>
+ <simple>${random(1000)}</simple>
+ </setBody>
+ <bean ref="orderService"/>
+ <log message="${body}"/>
</route>
</camelContext>
diff --git
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm
index 381e05b05b2..4a14c770268 100644
---
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm
+++
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm
@@ -312,6 +312,14 @@ ${indent} doAddElement(el,
def.${member.getter}(), def::${mem
${indent} return true;
${indent} }
${indent} return false;
+${indent} }
+${indent} if
("${external.namespace2()}".equals(parser.getNamespace())) {
+${indent} Element el =
doParseDOMElement("${external.documentElement2()}", "${external.namespace2()}",
def.${member.getter}());
+${indent} if (el != null) {
+${indent} doAddElement(el, def.${member.getter}(),
def::${member.setter});
+${indent} return true;
+${indent} }
+${indent} return false;
${indent} }
#end
#if( $others.empty )
diff --git
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
index da87308e0e9..5b77eb68d6c 100644
---
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
+++
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java
@@ -33,25 +33,36 @@ public @interface ExternalSchemaElement {
/**
* Names of external XML element we expect
- *
- * @return
*/
String[] names() default {};
+ /**
+ * Names of external XML element we expect
+ */
+ String[] names2() default {};
+
/**
* XSD namespace of XML elements expected
- *
- * @return
*/
String namespace() default "";
+ /**
+ * XSD namespace of XML elements expected
+ */
+ String namespace2() default "";
+
/**
* In JAXB, when an element is annotated with {@code @XmlAnyElement}, the
actual objects used are of
* {@link org.w3c.dom.Element} class. These elements should be part of
wrapping {@link org.w3c.dom.Document} and
* this parameter allows to specify this root element name (in {@link
#namespace()}).
- *
- * @return
*/
String documentElement();
+ /**
+ * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the
actual objects used are of
+ * {@link org.w3c.dom.Element} class. These elements should be part of
wrapping {@link org.w3c.dom.Document} and
+ * this parameter allows to specify this root element name (in {@link
#namespace2()}).
+ */
+ String documentElement2();
+
}