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

Croway 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 9a1f3883f947 Add namespacesRef to XPath/XQuery/XTokenize expressions 
(#25843)
9a1f3883f947 is described below

commit 9a1f3883f947936e56a1f7385d0790ad8be62dd4
Author: Marcin WiÄ™ckowski <[email protected]>
AuthorDate: Fri Aug 28 16:51:55 2026 +0200

    Add namespacesRef to XPath/XQuery/XTokenize expressions (#25843)
    
    * Add namespacesRef to XPath/XQuery/XTokenize expressions
    
    Co-authored-by: Claude Opus 5 <[email protected]>
    
    * NamespacesRef tests for XQuery and XML Tokenize
    
    Co-authored-by: Claude Opus 5 <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 5 <[email protected]>
---
 .../apache/camel/catalog/docs/xpath-language.adoc  | 80 +++++++++++++++++
 .../apache/camel/catalog/docs/xquery-language.adoc | 64 ++++++++++++++
 .../camel/catalog/docs/xtokenize-language.adoc     | 61 +++++++++++++
 .../org/apache/camel/catalog/languages/xpath.json  |  7 +-
 .../org/apache/camel/catalog/languages/xquery.json |  7 +-
 .../apache/camel/catalog/languages/xtokenize.json  |  7 +-
 .../org/apache/camel/catalog/models/xpath.json     |  7 +-
 .../org/apache/camel/catalog/models/xquery.json    |  7 +-
 .../org/apache/camel/catalog/models/xtokenize.json |  7 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  | 13 ++-
 .../apache/camel/catalog/schemas/camel-xml-io.xsd  | 13 ++-
 .../camel/catalog/schemas/camelYamlDsl-model.json  | 15 ++++
 .../org/apache/camel/language/xquery/xquery.json   |  7 +-
 .../camel-saxon/src/main/docs/xquery-language.adoc | 64 ++++++++++++++
 .../xpath/XPathNamespacesRefSaxonTest.java         | 89 +++++++++++++++++++
 .../language/xquery/XQueryNamespacesRefTest.java   | 69 +++++++++++++++
 .../camel/language/xtokenizer/xtokenize.json       |  7 +-
 .../src/main/docs/xtokenize-language.adoc          | 61 +++++++++++++
 .../xtokenizer/XMLTokenizeNamespacesRefTest.java   | 73 ++++++++++++++++
 .../org/apache/camel/language/xpath/xpath.json     |  7 +-
 .../camel-xpath/src/main/docs/xpath-language.adoc  | 80 +++++++++++++++++
 .../org/apache/camel/model/language/xpath.json     |  7 +-
 .../org/apache/camel/model/language/xquery.json    |  7 +-
 .../org/apache/camel/model/language/xtokenize.json |  7 +-
 .../model/language/NamespaceAwareExpression.java   | 27 ++++++
 .../language/XMLTokenizerExpressionReifier.java    | 28 +++---
 .../reifier/language/XPathExpressionReifier.java   | 28 +++---
 .../reifier/language/XQueryExpressionReifier.java  | 28 +++---
 .../camel/builder/xml/XPathNamespacesRefTest.java  | 61 +++++++++++++
 .../apache/camel/java/out/JavaDslModelWriter.java  | 12 ++-
 .../java/org/apache/camel/xml/in/ModelParser.java  | 12 ++-
 .../java/org/apache/camel/xml/out/ModelWriter.java | 12 ++-
 .../org/apache/camel/yaml/out/YamlModelWriter.java | 12 ++-
 .../dsl/xml/io/XmlXPathNamespacesRefTest.java      | 95 +++++++++++++++++++++
 .../dsl/yaml/deserializers/ModelDeserializers.java | 18 ++++
 .../resources/schema/camelYamlDsl-canonical.json   | 15 ++++
 .../resources/schema/camelYamlDsl-model.json       | 15 ++++
 .../generated/resources/schema/camelYamlDsl.json   | 15 ++++
 .../dsl/yaml/XPathNamespacesRefYamlDslTest.java    | 99 ++++++++++++++++++++++
 39 files changed, 1139 insertions(+), 104 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xpath-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xpath-language.adoc
index b3d35829e946..cb9d63a6009d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xpath-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xpath-language.adoc
@@ -27,6 +27,86 @@ include::partial$language-options.adoc[]
 
 You can use namespaces with XPath expressions using the `Namespaces` helper 
class.
 
+=== Sharing namespaces via a registry bean
+
+When the same prefix to URI mappings are needed by several expressions, you 
can register a
+single `org.apache.camel.support.builder.Namespaces` bean and refer to it from 
each
+expression with the `namespacesRef` option, instead of repeating the mappings 
inline.
+
+This is intended for XML and YAML DSL, where a `Namespaces` instance cannot be 
passed
+programmatically. In Java DSL you keep passing the builder directly.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+Namespaces ns = new Namespaces("c", "http://acme.com/cheese";)
+                     .add("w", "http://acme.com/wine";);
+
+from("direct:start")
+    .filter(xpath("/c:number = 55", ns))
+        .to("mock:result");
+----
+
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+      <property key="namespaces[w]" value="http://acme.com/wine"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="direct:start"/>
+    <filter>
+      <xpath namespacesRef="myNamespaces">/c:number = 55</xpath>
+      <to uri="mock:result"/>
+    </filter>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+        namespaces[w]: "http://acme.com/wine";
+- route:
+    from:
+      uri: "direct:start"
+      steps:
+        - filter:
+            expression:
+              xpath:
+                expression: "/c:number = 55"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value.
+
+If an expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
+The `namespacesRef` option is also available on the 
xref:xquery-language.adoc[XQuery] and
+xref:xtokenize-language.adoc[XML Tokenize] languages.
+
 == Variables
 
 Variables in XPath are defined in different namespaces.
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xquery-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xquery-language.adoc
index 5bb3c9829db0..03246085d3b7 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xquery-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xquery-language.adoc
@@ -198,6 +198,70 @@ in the line with `xmlns:foo="http://example.com/person"`:
 
 This namespace uses `foo` as prefix, so the `<xquery>` expression uses `foo:` 
to use this namespace.
 
+=== Sharing namespaces via a registry bean
+
+Declaring the prefixes on the XML root tag only works when the route itself is 
written in XML.
+To share one set of prefix to URI mappings across several expressions, 
register a
+`org.apache.camel.support.builder.Namespaces` bean and refer to it with the 
`namespacesRef`
+option:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+      <property key="namespaces[w]" value="http://acme.com/wine"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="direct:start"/>
+    <filter>
+      <xquery namespacesRef="myNamespaces">/c:person[@name='James']</xquery>
+      <to uri="mock:result"/>
+    </filter>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+        namespaces[w]: "http://acme.com/wine";
+- route:
+    from:
+      uri: "direct:start"
+      steps:
+        - filter:
+            expression:
+              xquery:
+                expression: "/c:person[@name='James']"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value. In Java DSL there is no need for this, as the `Namespaces` 
builder is passed
+to the expression directly, as shown above.
+
+If an expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
 == Using XQuery as transformation
 
 We can do a message translation using transform or setBody in the route,
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xtokenize-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xtokenize-language.adoc
index 838dd9b9bddb..ef1cc8255696 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xtokenize-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xtokenize-language.adoc
@@ -23,6 +23,67 @@ but also more efficiently tokenizing XML documents than the 
conventional xref:to
 include::partial$language-options.adoc[]
 // language options: END
 
+== Namespaces
+
+The XML Tokenize language is namespace aware, so a tokenized element can be 
selected by its
+prefix. The prefix to URI mappings can be declared inline, or shared across 
several expressions
+by registering a `org.apache.camel.support.builder.Namespaces` bean and 
referring to it with
+the `namespacesRef` option:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="file:inbox"/>
+    <split>
+      <xtokenize namespacesRef="myNamespaces">//c:order</xtokenize>
+      <to uri="mock:result"/>
+    </split>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+- route:
+    from:
+      uri: "file:inbox"
+      steps:
+        - split:
+            expression:
+              xtokenize:
+                expression: "//c:order"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value.
+
+If the expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
 == Example
 
 See xref:eips:split-eip.adoc[Split EIP], which has examples using the XML 
Tokenize language.
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
index df054242c695..e7d63b3180cd 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
@@ -27,8 +27,9 @@
     "threadSafety": { "index": 8, "kind": "attribute", "displayName": "Thread 
Safety", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
enable thread-safety for the returned result of the xpath expression. This 
applies to when using NODESET as the result type, and the returned set has 
multiple elements." },
     "preCompile": { "index": 9, "kind": "attribute", "displayName": "Pre 
Compile", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to enable 
pre-compiling the xpath expression during initialization phase. pre-compile is 
enabled by default." },
     "namespace": { "index": 10, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 11, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 12, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 13, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 11, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 12, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 13, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 14, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
index 56d3cd94a531..7f72b0d644f0 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
@@ -20,8 +20,9 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "configurationRef": { "index": 2, "kind": "attribute", "displayName": 
"Configuration Ref", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a saxon 
configuration instance in the registry to use for xquery (requires 
camel-saxon)." },
     "namespace": { "index": 3, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 4, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 4, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xtokenize.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xtokenize.json
index 4c7b65c9c1ff..2ee646173188 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xtokenize.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xtokenize.json
@@ -21,8 +21,9 @@
     "mode": { "index": 2, "kind": "attribute", "displayName": "Mode", "group": 
"common", "required": false, "type": "enum", "javaType": "java.lang.String", 
"enum": [ "i", "w", "u", "t" ], "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "i", "description": "The extraction mode. The 
available extraction modes are: i - injecting the contextual namespace bindings 
into the extracted token (default), w - wrapping the extracted token in its 
ancestor context, u - unwrap [...]
     "group": { "index": 3, "kind": "attribute", "displayName": "Group", 
"group": "common", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "To group N parts together." },
     "namespace": { "index": 4, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 5, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 6, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 7, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 8, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xpath.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xpath.json
index 383ba5c1ebfe..b0dc94d5a4df 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xpath.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xpath.json
@@ -24,8 +24,9 @@
     "threadSafety": { "index": 8, "kind": "attribute", "displayName": "Thread 
Safety", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
enable thread-safety for the returned result of the xpath expression. This 
applies to when using NODESET as the result type, and the returned set has 
multiple elements." },
     "preCompile": { "index": 9, "kind": "attribute", "displayName": "Pre 
Compile", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to enable 
pre-compiling the xpath expression during initialization phase. pre-compile is 
enabled by default." },
     "namespace": { "index": 10, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 11, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 12, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 13, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 11, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 12, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 13, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 14, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xquery.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xquery.json
index 445f35d90906..c85a4e3aef61 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xquery.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xquery.json
@@ -17,8 +17,9 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "configurationRef": { "index": 2, "kind": "attribute", "displayName": 
"Configuration Ref", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a saxon 
configuration instance in the registry to use for xquery (requires 
camel-saxon)." },
     "namespace": { "index": 3, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 4, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 4, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xtokenize.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xtokenize.json
index eae35f1315e3..91daa9ca76f1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xtokenize.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xtokenize.json
@@ -18,8 +18,9 @@
     "mode": { "index": 2, "kind": "attribute", "displayName": "Mode", "group": 
"common", "required": false, "type": "enum", "javaType": "java.lang.String", 
"enum": [ "i", "w", "u", "t" ], "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "i", "description": "The extraction mode. The 
available extraction modes are: i - injecting the contextual namespace bindings 
into the extracted token (default), w - wrapping the extracted token in its 
ancestor context, u - unwrap [...]
     "group": { "index": 3, "kind": "attribute", "displayName": "Group", 
"group": "common", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "To group N parts together." },
     "namespace": { "index": 4, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 5, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 6, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 7, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 8, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
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 be72acc1fe6c..70097ff0aea6 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
@@ -16318,7 +16318,18 @@ Whether to validate the bean has the configured 
method. Default value: true
   </xs:complexType>
   <xs:complexType abstract="true" name="namespaceAwareExpression">
     <xs:simpleContent>
-      <xs:extension base="tns:singleInputTypedExpressionDefinition"/>
+      <xs:extension base="tns:singleInputTypedExpressionDefinition">
+        <xs:attribute name="namespacesRef" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+Reference to a org.apache.camel.support.builder.Namespaces bean in the 
registry to use for the XML Namespaces of prefix
+to uri mappings.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
     </xs:simpleContent>
   </xs:complexType>
   <xs:complexType name="ognlExpression">
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 3fff6f740797..a628dc317c20 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
@@ -15461,7 +15461,18 @@ Whether to validate the bean has the configured 
method. Default value: true
   </xs:complexType>
   <xs:complexType abstract="true" name="namespaceAwareExpression">
     <xs:simpleContent>
-      <xs:extension base="tns:singleInputTypedExpressionDefinition"/>
+      <xs:extension base="tns:singleInputTypedExpressionDefinition">
+        <xs:attribute name="namespacesRef" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+Reference to a org.apache.camel.support.builder.Namespaces bean in the 
registry to use for the XML Namespaces of prefix
+to uri mappings.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
     </xs:simpleContent>
   </xs:complexType>
   <xs:complexType name="ognlExpression">
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
index 2a19bbe7cccc..2a965559ce02 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
@@ -15978,6 +15978,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "resultType",
         "type" : "string",
@@ -16032,6 +16037,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "objectModel",
         "type" : "string",
@@ -16105,6 +16115,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "resultType",
         "type" : "string",
diff --git 
a/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
 
b/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
index 56d3cd94a531..7f72b0d644f0 100644
--- 
a/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
+++ 
b/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
@@ -20,8 +20,9 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "configurationRef": { "index": 2, "kind": "attribute", "displayName": 
"Configuration Ref", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a saxon 
configuration instance in the registry to use for xquery (requires 
camel-saxon)." },
     "namespace": { "index": 3, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 4, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 4, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git a/components/camel-saxon/src/main/docs/xquery-language.adoc 
b/components/camel-saxon/src/main/docs/xquery-language.adoc
index 5bb3c9829db0..03246085d3b7 100644
--- a/components/camel-saxon/src/main/docs/xquery-language.adoc
+++ b/components/camel-saxon/src/main/docs/xquery-language.adoc
@@ -198,6 +198,70 @@ in the line with `xmlns:foo="http://example.com/person"`:
 
 This namespace uses `foo` as prefix, so the `<xquery>` expression uses `foo:` 
to use this namespace.
 
+=== Sharing namespaces via a registry bean
+
+Declaring the prefixes on the XML root tag only works when the route itself is 
written in XML.
+To share one set of prefix to URI mappings across several expressions, 
register a
+`org.apache.camel.support.builder.Namespaces` bean and refer to it with the 
`namespacesRef`
+option:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+      <property key="namespaces[w]" value="http://acme.com/wine"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="direct:start"/>
+    <filter>
+      <xquery namespacesRef="myNamespaces">/c:person[@name='James']</xquery>
+      <to uri="mock:result"/>
+    </filter>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+        namespaces[w]: "http://acme.com/wine";
+- route:
+    from:
+      uri: "direct:start"
+      steps:
+        - filter:
+            expression:
+              xquery:
+                expression: "/c:person[@name='James']"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value. In Java DSL there is no need for this, as the `Namespaces` 
builder is passed
+to the expression directly, as shown above.
+
+If an expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
 == Using XQuery as transformation
 
 We can do a message translation using transform or setBody in the route,
diff --git 
a/components/camel-saxon/src/test/java/org/apache/camel/language/xpath/XPathNamespacesRefSaxonTest.java
 
b/components/camel-saxon/src/test/java/org/apache/camel/language/xpath/XPathNamespacesRefSaxonTest.java
new file mode 100644
index 000000000000..273e0ae512aa
--- /dev/null
+++ 
b/components/camel-saxon/src/test/java/org/apache/camel/language/xpath/XPathNamespacesRefSaxonTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.language.xpath;
+
+import net.sf.saxon.xpath.XPathFactoryImpl;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.model.language.XPathExpression;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.support.builder.Namespaces;
+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.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests namespacesRef with Saxon, which resolves namespace prefixes when the 
expression is compiled rather than when it
+ * is evaluated. The referenced {@link Namespaces} bean must therefore be 
resolved before the expression is built, not
+ * afterwards, or compilation fails with "Namespace prefix has not been 
declared".
+ */
+class XPathNamespacesRefSaxonTest extends CamelTestSupport {
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("myNamespaces", new Namespaces("c", 
"http://acme.com/cheese";).add("w", "http://acme.com/wine";));
+        registry.bind("saxonFactory", new XPathFactoryImpl());
+    }
+
+    @Test
+    void testXPathWithNamespacesRef() {
+        Predicate cheese = predicate("/c:number = 55");
+        Predicate wine = predicate("/w:number = 77");
+
+        // 1 positive example per namespace
+        assertTrue(cheese.matches(exchange("<number 
xmlns=\"http://acme.com/cheese\";>55</number>")));
+        assertTrue(wine.matches(exchange("<number 
xmlns=\"http://acme.com/wine\";>77</number>")));
+
+        // negative, data-wise: correct namespace, wrong value
+        assertFalse(cheese.matches(exchange("<number 
xmlns=\"http://acme.com/cheese\";>99</number>")));
+
+        // negative, namespace-wise: correct value, wrong namespace URI
+        assertFalse(wine.matches(exchange("<number 
xmlns=\"http://acme.com/water\";>77</number>")));
+    }
+
+    @Test
+    void testXPathWithNamespacesRefAndResultType() {
+        // a resultType makes the language return a converting wrapper rather 
than the NamespaceAware builder,
+        // so the referenced namespaces must already be applied when the 
expression is built
+        XPathExpression definition = new XPathExpression("/c:number");
+        definition.setNamespacesRef("myNamespaces");
+        definition.setResultType(String.class);
+        definition.setFactoryRef("saxonFactory");
+        Expression expression = definition.createExpression(context);
+
+        assertEquals("55", expression.evaluate(exchange("<number 
xmlns=\"http://acme.com/cheese\";>55</number>"), String.class));
+    }
+
+    private Predicate predicate(String expression) {
+        XPathExpression definition = new XPathExpression(expression);
+        definition.setNamespacesRef("myNamespaces");
+        definition.setResultQName("BOOLEAN");
+        definition.setFactoryRef("saxonFactory");
+        return definition.createPredicate(context);
+    }
+
+    private Exchange exchange(String body) {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(body);
+        return exchange;
+    }
+}
diff --git 
a/components/camel-saxon/src/test/java/org/apache/camel/language/xquery/XQueryNamespacesRefTest.java
 
b/components/camel-saxon/src/test/java/org/apache/camel/language/xquery/XQueryNamespacesRefTest.java
new file mode 100644
index 000000000000..d8313fad8e3e
--- /dev/null
+++ 
b/components/camel-saxon/src/test/java/org/apache/camel/language/xquery/XQueryNamespacesRefTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.language.xquery;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.model.language.XQueryExpression;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.support.builder.Namespaces;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests that an xquery expression can reference a {@link Namespaces} bean 
from the registry via namespacesRef, instead
+ * of declaring the namespaces inline.
+ */
+class XQueryNamespacesRefTest extends CamelTestSupport {
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("myNamespaces", new Namespaces("c", 
"http://acme.com/cheese";).add("w", "http://acme.com/wine";));
+    }
+
+    @Test
+    void testXQueryWithNamespacesRef() {
+        Predicate cheese = predicate("/c:person[@name='James']");
+        Predicate wine = predicate("/w:person[@name='James']");
+
+        // 1 positive example per namespace
+        assertTrue(cheese.matches(exchange("<person 
xmlns=\"http://acme.com/cheese\"; name=\"James\"/>")));
+        assertTrue(wine.matches(exchange("<person 
xmlns=\"http://acme.com/wine\"; name=\"James\"/>")));
+
+        // negative, data-wise: correct namespace, wrong value
+        assertFalse(cheese.matches(exchange("<person 
xmlns=\"http://acme.com/cheese\"; name=\"Claus\"/>")));
+
+        // negative, namespace-wise: correct value, wrong namespace URI
+        assertFalse(wine.matches(exchange("<person 
xmlns=\"http://acme.com/water\"; name=\"James\"/>")));
+    }
+
+    private Predicate predicate(String expression) {
+        XQueryExpression definition = new XQueryExpression(expression);
+        definition.setNamespacesRef("myNamespaces");
+        return definition.createPredicate(context);
+    }
+
+    private Exchange exchange(String body) {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(body);
+        return exchange;
+    }
+}
diff --git 
a/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/language/xtokenizer/xtokenize.json
 
b/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/language/xtokenizer/xtokenize.json
index 4c7b65c9c1ff..2ee646173188 100644
--- 
a/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/language/xtokenizer/xtokenize.json
+++ 
b/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/language/xtokenizer/xtokenize.json
@@ -21,8 +21,9 @@
     "mode": { "index": 2, "kind": "attribute", "displayName": "Mode", "group": 
"common", "required": false, "type": "enum", "javaType": "java.lang.String", 
"enum": [ "i", "w", "u", "t" ], "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "i", "description": "The extraction mode. The 
available extraction modes are: i - injecting the contextual namespace bindings 
into the extracted token (default), w - wrapping the extracted token in its 
ancestor context, u - unwrap [...]
     "group": { "index": 3, "kind": "attribute", "displayName": "Group", 
"group": "common", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "To group N parts together." },
     "namespace": { "index": 4, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 5, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 6, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 7, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 8, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git a/components/camel-stax/src/main/docs/xtokenize-language.adoc 
b/components/camel-stax/src/main/docs/xtokenize-language.adoc
index 838dd9b9bddb..ef1cc8255696 100644
--- a/components/camel-stax/src/main/docs/xtokenize-language.adoc
+++ b/components/camel-stax/src/main/docs/xtokenize-language.adoc
@@ -23,6 +23,67 @@ but also more efficiently tokenizing XML documents than the 
conventional xref:to
 include::partial$language-options.adoc[]
 // language options: END
 
+== Namespaces
+
+The XML Tokenize language is namespace aware, so a tokenized element can be 
selected by its
+prefix. The prefix to URI mappings can be declared inline, or shared across 
several expressions
+by registering a `org.apache.camel.support.builder.Namespaces` bean and 
referring to it with
+the `namespacesRef` option:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="file:inbox"/>
+    <split>
+      <xtokenize namespacesRef="myNamespaces">//c:order</xtokenize>
+      <to uri="mock:result"/>
+    </split>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+- route:
+    from:
+      uri: "file:inbox"
+      steps:
+        - split:
+            expression:
+              xtokenize:
+                expression: "//c:order"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value.
+
+If the expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
 == Example
 
 See xref:eips:split-eip.adoc[Split EIP], which has examples using the XML 
Tokenize language.
diff --git 
a/components/camel-stax/src/test/java/org/apache/camel/language/xtokenizer/XMLTokenizeNamespacesRefTest.java
 
b/components/camel-stax/src/test/java/org/apache/camel/language/xtokenizer/XMLTokenizeNamespacesRefTest.java
new file mode 100644
index 000000000000..f05cf67900c8
--- /dev/null
+++ 
b/components/camel-stax/src/test/java/org/apache/camel/language/xtokenizer/XMLTokenizeNamespacesRefTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.language.xtokenizer;
+
+import java.util.Iterator;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.model.language.XMLTokenizerExpression;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.support.builder.Namespaces;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests that an xtokenize expression can reference a {@link Namespaces} bean 
from the registry via namespacesRef,
+ * instead of declaring the namespaces inline.
+ */
+class XMLTokenizeNamespacesRefTest extends CamelTestSupport {
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("myNamespaces", new Namespaces("c", 
"http://acme.com/cheese";).add("w", "http://acme.com/wine";));
+    }
+
+    @Test
+    void testXTokenizeWithNamespacesRef() {
+        Iterator<?> cheese
+                = tokenize("//c:order", "<orders 
xmlns:c=\"http://acme.com/cheese\";><c:order>one</c:order></orders>");
+        Iterator<?> wine = tokenize("//w:order", "<orders 
xmlns:w=\"http://acme.com/wine\";><w:order>two</w:order></orders>");
+
+        // 1 positive example per namespace
+        assertTrue(cheese.hasNext());
+        assertTrue(String.valueOf(cheese.next()).contains("one"));
+        assertTrue(wine.hasNext());
+        assertTrue(String.valueOf(wine.next()).contains("two"));
+
+        // negative, namespace-wise: matching local name, wrong namespace URI
+        Iterator<?> water
+                = tokenize("//c:order", "<orders 
xmlns:c=\"http://acme.com/water\";><c:order>three</c:order></orders>");
+        assertFalse(water.hasNext());
+    }
+
+    private Iterator<?> tokenize(String expression, String body) {
+        XMLTokenizerExpression definition = new 
XMLTokenizerExpression(expression);
+        definition.setNamespacesRef("myNamespaces");
+        Expression exp = definition.createExpression(context);
+
+        Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(body);
+
+        return assertInstanceOf(Iterator.class, exp.evaluate(exchange, 
Object.class));
+    }
+}
diff --git 
a/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
 
b/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
index df054242c695..e7d63b3180cd 100644
--- 
a/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
+++ 
b/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
@@ -27,8 +27,9 @@
     "threadSafety": { "index": 8, "kind": "attribute", "displayName": "Thread 
Safety", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
enable thread-safety for the returned result of the xpath expression. This 
applies to when using NODESET as the result type, and the returned set has 
multiple elements." },
     "preCompile": { "index": 9, "kind": "attribute", "displayName": "Pre 
Compile", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to enable 
pre-compiling the xpath expression during initialization phase. pre-compile is 
enabled by default." },
     "namespace": { "index": 10, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 11, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 12, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 13, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 11, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 12, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 13, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 14, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git a/components/camel-xpath/src/main/docs/xpath-language.adoc 
b/components/camel-xpath/src/main/docs/xpath-language.adoc
index b3d35829e946..cb9d63a6009d 100644
--- a/components/camel-xpath/src/main/docs/xpath-language.adoc
+++ b/components/camel-xpath/src/main/docs/xpath-language.adoc
@@ -27,6 +27,86 @@ include::partial$language-options.adoc[]
 
 You can use namespaces with XPath expressions using the `Namespaces` helper 
class.
 
+=== Sharing namespaces via a registry bean
+
+When the same prefix to URI mappings are needed by several expressions, you 
can register a
+single `org.apache.camel.support.builder.Namespaces` bean and refer to it from 
each
+expression with the `namespacesRef` option, instead of repeating the mappings 
inline.
+
+This is intended for XML and YAML DSL, where a `Namespaces` instance cannot be 
passed
+programmatically. In Java DSL you keep passing the builder directly.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+Namespaces ns = new Namespaces("c", "http://acme.com/cheese";)
+                     .add("w", "http://acme.com/wine";);
+
+from("direct:start")
+    .filter(xpath("/c:number = 55", ns))
+        .to("mock:result");
+----
+
+XML::
++
+[source,xml]
+----
+<camel xmlns="http://camel.apache.org/schema/xml-io";>
+
+  <bean name="myNamespaces" type="org.apache.camel.support.builder.Namespaces">
+    <properties>
+      <property key="namespaces[c]" value="http://acme.com/cheese"/>
+      <property key="namespaces[w]" value="http://acme.com/wine"/>
+    </properties>
+  </bean>
+
+  <route>
+    <from uri="direct:start"/>
+    <filter>
+      <xpath namespacesRef="myNamespaces">/c:number = 55</xpath>
+      <to uri="mock:result"/>
+    </filter>
+  </route>
+
+</camel>
+----
+
+YAML::
++
+[source,yaml]
+----
+- beans:
+    - name: myNamespaces
+      type: org.apache.camel.support.builder.Namespaces
+      properties:
+        namespaces[c]: "http://acme.com/cheese";
+        namespaces[w]: "http://acme.com/wine";
+- route:
+    from:
+      uri: "direct:start"
+      steps:
+        - filter:
+            expression:
+              xpath:
+                expression: "/c:number = 55"
+                namespacesRef: "myNamespaces"
+            steps:
+              - to: "mock:result"
+----
+====
+
+Each prefix is configured as a `namespaces[prefix]` property on the bean, with 
the namespace
+URI as the value.
+
+If an expression declares namespaces inline as well, then the inline 
namespaces win and
+`namespacesRef` is ignored.
+
+The `namespacesRef` option is also available on the 
xref:xquery-language.adoc[XQuery] and
+xref:xtokenize-language.adoc[XML Tokenize] languages.
+
 == Variables
 
 Variables in XPath are defined in different namespaces.
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xpath.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xpath.json
index 383ba5c1ebfe..b0dc94d5a4df 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xpath.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xpath.json
@@ -24,8 +24,9 @@
     "threadSafety": { "index": 8, "kind": "attribute", "displayName": "Thread 
Safety", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
enable thread-safety for the returned result of the xpath expression. This 
applies to when using NODESET as the result type, and the returned set has 
multiple elements." },
     "preCompile": { "index": 9, "kind": "attribute", "displayName": "Pre 
Compile", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to enable 
pre-compiling the xpath expression during initialization phase. pre-compile is 
enabled by default." },
     "namespace": { "index": 10, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 11, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 12, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 13, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 11, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 12, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 13, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 14, "kind": "attribute", "displayName": "Trim", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xquery.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xquery.json
index 445f35d90906..c85a4e3aef61 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xquery.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xquery.json
@@ -17,8 +17,9 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "configurationRef": { "index": 2, "kind": "attribute", "displayName": 
"Configuration Ref", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a saxon 
configuration instance in the registry to use for xquery (requires 
camel-saxon)." },
     "namespace": { "index": 3, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 4, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 4, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xtokenize.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xtokenize.json
index eae35f1315e3..91daa9ca76f1 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xtokenize.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/xtokenize.json
@@ -18,8 +18,9 @@
     "mode": { "index": 2, "kind": "attribute", "displayName": "Mode", "group": 
"common", "required": false, "type": "enum", "javaType": "java.lang.String", 
"enum": [ "i", "w", "u", "t" ], "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "i", "description": "The extraction mode. The 
available extraction modes are: i - injecting the contextual namespace bindings 
into the extracted token (default), w - wrapping the extracted token in its 
ancestor context, u - unwrap [...]
     "group": { "index": 3, "kind": "attribute", "displayName": "Group", 
"group": "common", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "To group N parts together." },
     "namespace": { "index": 4, "kind": "element", "displayName": "Namespace", 
"group": "common", "label": "common", "required": false, "type": "array", 
"javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Injects the XML Namespaces of prefix to uri mappings." },
-    "source": { "index": 5, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
-    "resultType": { "index": 6, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
-    "trim": { "index": 7, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
+    "namespacesRef": { "index": 5, "kind": "attribute", "displayName": 
"Namespaces Ref", "group": "advanced", "label": "advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings." },
+    "source": { "index": 6, "kind": "attribute", "displayName": "Source", 
"group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body." },
+    "resultType": { "index": 7, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
+    "trim": { "index": 8, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." }
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/language/NamespaceAwareExpression.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/language/NamespaceAwareExpression.java
index 6264651e532a..fc85ec7a6994 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/language/NamespaceAwareExpression.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/language/NamespaceAwareExpression.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
 import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
 import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlTransient;
 
@@ -45,6 +46,10 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
     private List<PropertyDefinition> namespace;
     @XmlTransient
     private Map<String, String> namespaces;
+    @XmlAttribute
+    @Metadata(label = "advanced",
+              description = "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.")
+    private String namespacesRef;
 
     protected NamespaceAwareExpression() {
     }
@@ -53,6 +58,7 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
         super(source);
         this.namespace = 
ProcessorDefinitionHelper.deepCopyDefinitions(source.namespace);
         this.namespaces = source.namespaces != null ? new 
LinkedHashMap<>(source.namespaces) : null;
+        this.namespacesRef = source.namespacesRef;
     }
 
     protected NamespaceAwareExpression(String expression) {
@@ -63,6 +69,7 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
         super(builder);
         this.namespace = builder.namespace;
         this.namespaces = builder.namespaces;
+        this.namespacesRef = builder.namespacesRef;
     }
 
     @Override
@@ -87,6 +94,14 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
         this.namespace = namespace;
     }
 
+    public String getNamespacesRef() {
+        return namespacesRef;
+    }
+
+    public void setNamespacesRef(String namespacesRef) {
+        this.namespacesRef = namespacesRef;
+    }
+
     public Map<String, String> getNamespaceAsMap() {
         if (namespaces == null && namespace != null) {
             namespaces = new HashMap<>();
@@ -113,6 +128,7 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
 
         private List<PropertyDefinition> namespace;
         private Map<String, String> namespaces;
+        private String namespacesRef;
 
         /**
          * Injects the XML Namespaces of prefix -> uri mappings
@@ -141,5 +157,16 @@ public abstract class NamespaceAwareExpression extends 
SingleInputTypedExpressio
             this.namespace = namespace;
             return (T) this;
         }
+
+        /**
+         * Reference to a {@link Namespaces} bean in the registry to use for 
the XML Namespaces of prefix -> uri
+         * mappings
+         *
+         * @param namespacesRef the id of the Namespaces bean in the registry
+         */
+        public T namespacesRef(String namespacesRef) {
+            this.namespacesRef = namespacesRef;
+            return (T) this;
+        }
     }
 }
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
index 344b49058198..883536f4300a 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
@@ -16,12 +16,12 @@
  */
 package org.apache.camel.reifier.language;
 
+import java.util.Map;
+
 import org.apache.camel.CamelContext;
-import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.XMLTokenizerExpression;
-import org.apache.camel.spi.NamespaceAware;
+import org.apache.camel.support.builder.Namespaces;
 
 public class XMLTokenizerExpressionReifier extends 
SingleInputTypedExpressionReifier<XMLTokenizerExpression> {
 
@@ -29,20 +29,14 @@ public class XMLTokenizerExpressionReifier extends 
SingleInputTypedExpressionRei
         super(camelContext, definition);
     }
 
-    @Override
-    protected void configurePredicate(Predicate predicate) {
-        configureNamespaceAware(predicate);
-    }
-
-    @Override
-    protected void configureExpression(Expression expression) {
-        configureNamespaceAware(expression);
-    }
-
-    protected void configureNamespaceAware(Object builder) {
-        if (definition.getNamespaces() != null && builder instanceof 
NamespaceAware namespaceAware) {
-            namespaceAware.setNamespaces(parseMap(definition.getNamespaces()));
+    private Map<String, String> resolveNamespaces() {
+        if (definition.getNamespaces() != null && 
!definition.getNamespaces().isEmpty()) {
+            return parseMap(definition.getNamespaces());
+        }
+        if (definition.getNamespacesRef() != null) {
+            return parseMap(mandatoryLookup(definition.getNamespacesRef(), 
Namespaces.class).getNamespaces());
         }
+        return null;
     }
 
     protected Object[] createProperties() {
@@ -51,7 +45,7 @@ public class XMLTokenizerExpressionReifier extends 
SingleInputTypedExpressionRei
         properties[1] = parseString(definition.getSource());
         properties[2] = parseString(definition.getMode());
         properties[3] = parseInt(definition.getGroup());
-        properties[4] = definition.getNamespaces();
+        properties[4] = resolveNamespaces();
         return properties;
     }
 
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
index 7136d3dd8bbe..904ea8d83222 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
@@ -16,17 +16,17 @@
  */
 package org.apache.camel.reifier.language;
 
+import java.util.Map;
+
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFactory;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.XPathExpression;
 import org.apache.camel.spi.Language;
-import org.apache.camel.spi.NamespaceAware;
+import org.apache.camel.support.builder.Namespaces;
 
 public class XPathExpressionReifier extends 
SingleInputTypedExpressionReifier<XPathExpression> {
 
@@ -34,20 +34,14 @@ public class XPathExpressionReifier extends 
SingleInputTypedExpressionReifier<XP
         super(camelContext, definition);
     }
 
-    @Override
-    protected void configurePredicate(Predicate predicate) {
-        configureNamespaceAware(predicate);
-    }
-
-    @Override
-    protected void configureExpression(Expression expression) {
-        configureNamespaceAware(expression);
-    }
-
-    protected void configureNamespaceAware(Object builder) {
-        if (definition.getNamespaces() != null && builder instanceof 
NamespaceAware namespaceAware) {
-            namespaceAware.setNamespaces(parseMap(definition.getNamespaces()));
+    private Map<String, String> resolveNamespaces() {
+        if (definition.getNamespaces() != null && 
!definition.getNamespaces().isEmpty()) {
+            return parseMap(definition.getNamespaces());
         }
+        if (definition.getNamespacesRef() != null) {
+            return parseMap(mandatoryLookup(definition.getNamespacesRef(), 
Namespaces.class).getNamespaces());
+        }
+        return null;
     }
 
     protected Object[] createProperties() {
@@ -62,7 +56,7 @@ public class XPathExpressionReifier extends 
SingleInputTypedExpressionReifier<XP
         properties[7] = parseBoolean(definition.getThreadSafety());
         properties[8] = parseBoolean(definition.getPreCompile());
         properties[9] = parseBoolean(definition.getLogNamespaces());
-        properties[10] = definition.getNamespaces();
+        properties[10] = resolveNamespaces();
         return properties;
     }
 
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
index b17affbfc990..a29d84563013 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
@@ -16,13 +16,13 @@
  */
 package org.apache.camel.reifier.language;
 
+import java.util.Map;
+
 import org.apache.camel.CamelContext;
-import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.XQueryExpression;
 import org.apache.camel.spi.Language;
-import org.apache.camel.spi.NamespaceAware;
+import org.apache.camel.support.builder.Namespaces;
 
 public class XQueryExpressionReifier extends 
SingleInputTypedExpressionReifier<XQueryExpression> {
 
@@ -30,27 +30,21 @@ public class XQueryExpressionReifier extends 
SingleInputTypedExpressionReifier<X
         super(camelContext, definition);
     }
 
-    @Override
-    protected void configurePredicate(Predicate predicate) {
-        configureNamespaceAware(predicate);
-    }
-
-    @Override
-    protected void configureExpression(Expression expression) {
-        configureNamespaceAware(expression);
-    }
-
-    protected void configureNamespaceAware(Object builder) {
-        if (definition.getNamespaces() != null && builder instanceof 
NamespaceAware namespaceAware) {
-            namespaceAware.setNamespaces(parseMap(definition.getNamespaces()));
+    private Map<String, String> resolveNamespaces() {
+        if (definition.getNamespaces() != null && 
!definition.getNamespaces().isEmpty()) {
+            return parseMap(definition.getNamespaces());
+        }
+        if (definition.getNamespacesRef() != null) {
+            return parseMap(mandatoryLookup(definition.getNamespacesRef(), 
Namespaces.class).getNamespaces());
         }
+        return null;
     }
 
     protected Object[] createProperties() {
         Object[] properties = new Object[3];
         properties[0] = asResultType();
         properties[1] = parseString(definition.getSource());
-        properties[2] = definition.getNamespaces();
+        properties[2] = resolveNamespaces();
         return properties;
     }
 
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/builder/xml/XPathNamespacesRefTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/builder/xml/XPathNamespacesRefTest.java
new file mode 100644
index 000000000000..71bfea370095
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/builder/xml/XPathNamespacesRefTest.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.builder.xml;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Predicate;
+import org.apache.camel.model.language.XPathExpression;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.support.builder.Namespaces;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests that an xpath expression can reference a {@link Namespaces} bean from 
the registry via namespacesRef, instead
+ * of declaring the namespaces inline.
+ */
+class XPathNamespacesRefTest extends ContextTestSupport {
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("myNamespaces", new Namespaces("c", 
"http://acme.com/cheese";).add("w", "http://acme.com/wine";));
+    }
+
+    @Test
+    void testXPathWithNamespacesRef() {
+        Predicate cheese = predicate("/c:number = 55");
+        Predicate wine = predicate("/w:number = 77");
+
+        // 1 positive example per namespace
+        assertThat(cheese.matches(createExchangeWithBody("<number 
xmlns=\"http://acme.com/cheese\";>55</number>"))).isTrue();
+        assertThat(wine.matches(createExchangeWithBody("<number 
xmlns=\"http://acme.com/wine\";>77</number>"))).isTrue();
+
+        // negative, data-wise: correct namespace, wrong value
+        assertThat(cheese.matches(createExchangeWithBody("<number 
xmlns=\"http://acme.com/cheese\";>99</number>"))).isFalse();
+
+        // negative, namespace-wise: correct value, wrong namespace URI
+        assertThat(wine.matches(createExchangeWithBody("<number 
xmlns=\"http://acme.com/water\";>77</number>"))).isFalse();
+    }
+
+    private Predicate predicate(String expression) {
+        XPathExpression definition = new XPathExpression(expression);
+        definition.setNamespacesRef("myNamespaces");
+        definition.setResultQName("BOOLEAN");
+        return definition.createPredicate(context);
+    }
+}
diff --git 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
index b1d7fdf89b82..0fb08beb668b 100644
--- 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
+++ 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
@@ -3545,11 +3545,15 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
         doWriteTypedExpressionDefinitionAttributes(sb, def);
         doWriteValue(sb, def.getExpression());
     }
+    protected void doWriteNamespaceAwareExpressionAttributes(StringBuilder sb, 
NamespaceAwareExpression def) {
+        doWriteSingleInputTypedExpressionDefinitionAttributes(sb, def);
+        doWriteAttribute(sb, "namespacesRef", def.getNamespacesRef(), null);
+    }
     protected void doWriteNamespaceAwareExpressionElements(StringBuilder sb, 
NamespaceAwareExpression def) {
         doWriteChildList(sb, "namespace", def.getNamespace(), 
this::doWritePropertyDefinition);
     }
     protected void doWriteNamespaceAwareExpression(StringBuilder sb, 
NamespaceAwareExpression def) {
-        doWriteSingleInputTypedExpressionDefinitionAttributes(sb, def);
+        doWriteNamespaceAwareExpressionAttributes(sb, def);
         doWriteValue(sb, def.getExpression());
         doWriteNamespaceAwareExpressionElements(sb, def);
     }
@@ -3623,14 +3627,14 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
         doWriteValue(sb, def.getExpression());
     }
     protected void doWriteXMLTokenizerExpression(StringBuilder sb, 
XMLTokenizerExpression def) {
-        doWriteSingleInputTypedExpressionDefinitionAttributes(sb, def);
+        doWriteNamespaceAwareExpressionAttributes(sb, def);
         doWriteAttribute(sb, "mode", def.getMode(), "i");
         doWriteAttribute(sb, "group", def.getGroup(), null);
         doWriteValue(sb, def.getExpression());
         doWriteNamespaceAwareExpressionElements(sb, def);
     }
     protected void doWriteXPathExpression(StringBuilder sb, XPathExpression 
def) {
-        doWriteSingleInputTypedExpressionDefinitionAttributes(sb, def);
+        doWriteNamespaceAwareExpressionAttributes(sb, def);
         doWriteAttribute(sb, "documentType", def.getDocumentTypeName(), null);
         doWriteAttribute(sb, "resultQName", def.getResultQName(), "NODESET");
         doWriteAttribute(sb, "saxon", def.getSaxon(), null);
@@ -3643,7 +3647,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
         doWriteNamespaceAwareExpressionElements(sb, def);
     }
     protected void doWriteXQueryExpression(StringBuilder sb, XQueryExpression 
def) {
-        doWriteSingleInputTypedExpressionDefinitionAttributes(sb, def);
+        doWriteNamespaceAwareExpressionAttributes(sb, def);
         doWriteAttribute(sb, "configurationRef", def.getConfigurationRef(), 
null);
         doWriteValue(sb, def.getExpression());
         doWriteNamespaceAwareExpressionElements(sb, def);
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 d2f9e108d076..ee55786610c3 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
@@ -2379,9 +2379,15 @@ public class ModelParser extends BaseParser {
         return doParse(new XMLTokenizerExpression(), (def, key, val) -> switch 
(key) {
                 case "group": def.setGroup(val); yield true;
                 case "mode": def.setMode(val); yield true;
-                default: yield 
singleInputTypedExpressionDefinitionAttributeHandler().accept(def, key, val);
+                default: yield 
namespaceAwareExpressionAttributeHandler().accept(def, key, val);
             }, namespaceAwareExpressionElementHandler(), 
expressionDefinitionValueHandler());
     }
+    protected <T extends NamespaceAwareExpression> AttributeHandler<T> 
namespaceAwareExpressionAttributeHandler() {
+        return (def, key, val) -> switch (key) {
+            case "namespacesRef": def.setNamespacesRef(val); yield true;
+            default: yield 
singleInputTypedExpressionDefinitionAttributeHandler().accept(def, key, val);
+        };
+    }
     protected <T extends NamespaceAwareExpression> ElementHandler<T> 
namespaceAwareExpressionElementHandler() {
         return (def, key) -> switch (key) {
             case "namespace": doAdd(doParsePropertyDefinition(), 
def.getNamespace(), def::setNamespace); yield true;
@@ -2398,13 +2404,13 @@ public class ModelParser extends BaseParser {
                 case "resultQName": def.setResultQName(val); yield true;
                 case "saxon": def.setSaxon(val); yield true;
                 case "threadSafety": def.setThreadSafety(val); yield true;
-                default: yield 
singleInputTypedExpressionDefinitionAttributeHandler().accept(def, key, val);
+                default: yield 
namespaceAwareExpressionAttributeHandler().accept(def, key, val);
             }, namespaceAwareExpressionElementHandler(), 
expressionDefinitionValueHandler());
     }
     protected XQueryExpression doParseXQueryExpression() throws IOException, 
XmlPullParserException {
         return doParse(new XQueryExpression(), (def, key, val) -> switch (key) 
{
                 case "configurationRef": def.setConfigurationRef(val); yield 
true;
-                default: yield 
singleInputTypedExpressionDefinitionAttributeHandler().accept(def, key, val);
+                default: yield 
namespaceAwareExpressionAttributeHandler().accept(def, key, val);
             }, namespaceAwareExpressionElementHandler(), 
expressionDefinitionValueHandler());
     }
     protected CustomLoadBalancerDefinition 
doParseCustomLoadBalancerDefinition() throws IOException, 
XmlPullParserException {
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 3e120b4988b6..89e3dfb53576 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
@@ -3001,12 +3001,16 @@ public class ModelWriter extends BaseWriter {
         doWriteValue(def.getExpression());
         endElement(name);
     }
+    protected void 
doWriteNamespaceAwareExpressionAttributes(NamespaceAwareExpression def) throws 
IOException {
+        doWriteSingleInputTypedExpressionDefinitionAttributes(def);
+        doWriteAttribute("namespacesRef", def.getNamespacesRef(), null);
+    }
     protected void 
doWriteNamespaceAwareExpressionElements(NamespaceAwareExpression def) throws 
IOException {
         doWriteList(null, "namespace", def.getNamespace(), 
this::doWritePropertyDefinition);
     }
     protected void doWriteNamespaceAwareExpression(String name, 
NamespaceAwareExpression def) throws IOException {
         startElement(name);
-        doWriteSingleInputTypedExpressionDefinitionAttributes(def);
+        doWriteNamespaceAwareExpressionAttributes(def);
         doWriteValue(def.getExpression());
         doWriteNamespaceAwareExpressionElements(def);
         endElement(name);
@@ -3106,7 +3110,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteXMLTokenizerExpression(String name, 
XMLTokenizerExpression def) throws IOException {
         startElement(name);
-        doWriteSingleInputTypedExpressionDefinitionAttributes(def);
+        doWriteNamespaceAwareExpressionAttributes(def);
         doWriteAttribute("mode", def.getMode(), "i");
         doWriteAttribute("group", def.getGroup(), null);
         doWriteValue(def.getExpression());
@@ -3115,7 +3119,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteXPathExpression(String name, XPathExpression def) 
throws IOException {
         startElement(name);
-        doWriteSingleInputTypedExpressionDefinitionAttributes(def);
+        doWriteNamespaceAwareExpressionAttributes(def);
         doWriteAttribute("documentType", def.getDocumentTypeName(), null);
         doWriteAttribute("resultQName", def.getResultQName(), "NODESET");
         doWriteAttribute("saxon", def.getSaxon(), null);
@@ -3130,7 +3134,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteXQueryExpression(String name, XQueryExpression def) 
throws IOException {
         startElement(name);
-        doWriteSingleInputTypedExpressionDefinitionAttributes(def);
+        doWriteNamespaceAwareExpressionAttributes(def);
         doWriteAttribute("configurationRef", def.getConfigurationRef(), null);
         doWriteValue(def.getExpression());
         doWriteNamespaceAwareExpressionElements(def);
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 fc56d46bb007..9fbb01f51fb6 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
@@ -2999,12 +2999,16 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
         doWriteValue(jo, def.getExpression());
         return jo;
     }
+    protected void doWriteNamespaceAwareExpressionAttributes(JsonObject jo, 
NamespaceAwareExpression def) {
+        doWriteSingleInputTypedExpressionDefinitionAttributes(jo, def);
+        doWriteAttribute(jo, "namespacesRef", def.getNamespacesRef(), null);
+    }
     protected void doWriteNamespaceAwareExpressionElements(JsonObject jo, 
NamespaceAwareExpression def) {
         doWriteChildList(jo, null, "namespace", def.getNamespace(), 
this::doWritePropertyDefinition);
     }
     protected JsonObject 
doWriteNamespaceAwareExpression(NamespaceAwareExpression def) {
         JsonObject jo = new JsonObject();
-        doWriteSingleInputTypedExpressionDefinitionAttributes(jo, def);
+        doWriteNamespaceAwareExpressionAttributes(jo, def);
         doWriteValue(jo, def.getExpression());
         doWriteNamespaceAwareExpressionElements(jo, def);
         return jo;
@@ -3104,7 +3108,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
     }
     protected JsonObject doWriteXMLTokenizerExpression(XMLTokenizerExpression 
def) {
         JsonObject jo = new JsonObject();
-        doWriteSingleInputTypedExpressionDefinitionAttributes(jo, def);
+        doWriteNamespaceAwareExpressionAttributes(jo, def);
         doWriteAttribute(jo, "mode", def.getMode(), "i");
         doWriteAttribute(jo, "group", def.getGroup(), null);
         doWriteValue(jo, def.getExpression());
@@ -3113,7 +3117,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
     }
     protected JsonObject doWriteXPathExpression(XPathExpression def) {
         JsonObject jo = new JsonObject();
-        doWriteSingleInputTypedExpressionDefinitionAttributes(jo, def);
+        doWriteNamespaceAwareExpressionAttributes(jo, def);
         doWriteAttribute(jo, "documentType", def.getDocumentTypeName(), null);
         doWriteAttribute(jo, "resultQName", def.getResultQName(), "NODESET");
         doWriteAttribute(jo, "saxon", def.getSaxon(), null);
@@ -3128,7 +3132,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
     }
     protected JsonObject doWriteXQueryExpression(XQueryExpression def) {
         JsonObject jo = new JsonObject();
-        doWriteSingleInputTypedExpressionDefinitionAttributes(jo, def);
+        doWriteNamespaceAwareExpressionAttributes(jo, def);
         doWriteAttribute(jo, "configurationRef", def.getConfigurationRef(), 
null);
         doWriteValue(jo, def.getExpression());
         doWriteNamespaceAwareExpressionElements(jo, def);
diff --git 
a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlXPathNamespacesRefTest.java
 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlXPathNamespacesRefTest.java
new file mode 100644
index 000000000000..4c01b3501008
--- /dev/null
+++ 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlXPathNamespacesRefTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.dsl.xml.io;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.support.builder.Namespaces;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests that a route loaded from plain XML DSL can reference a {@link 
Namespaces} bean from the registry via the xpath
+ * element's namespacesRef attribute, with the bean itself also declared in 
XML.
+ */
+class XmlXPathNamespacesRefTest {
+
+    @Test
+    void testXPathNamespacesRefFromXml() throws Exception {
+        try (DefaultCamelContext context = new DefaultCamelContext()) {
+            context.start();
+
+            Resource resource = 
ResourceHelper.fromString("xpathNamespacesRef.xml", """
+                    <camel xmlns="http://camel.apache.org/schema/xml-io";>
+                        <bean name="myNamespaces" 
type="org.apache.camel.support.builder.Namespaces">
+                            <properties>
+                                <property key="namespaces[c]" 
value="http://acme.com/cheese"/>
+                                <property key="namespaces[w]" 
value="http://acme.com/wine"/>
+                            </properties>
+                        </bean>
+                        <route id="xpathNamespacesRef">
+                            <from uri="direct:xpathNamespacesRef"/>
+                            <choice>
+                                <when>
+                                    <xpath resultQName="BOOLEAN" 
namespacesRef="myNamespaces">/c:number = 55</xpath>
+                                    <to uri="mock:cheeseMatch"/>
+                                </when>
+                                <when>
+                                    <xpath resultQName="BOOLEAN" 
namespacesRef="myNamespaces">/w:number = 77</xpath>
+                                    <to uri="mock:wineMatch"/>
+                                </when>
+                                <otherwise>
+                                    <to uri="mock:noMatch"/>
+                                </otherwise>
+                            </choice>
+                        </route>
+                    </camel>
+                    """);
+            PluginHelper.getRoutesLoader(context).loadRoutes(resource);
+
+            MockEndpoint cheeseMatch = context.getEndpoint("mock:cheeseMatch", 
MockEndpoint.class);
+            MockEndpoint wineMatch = context.getEndpoint("mock:wineMatch", 
MockEndpoint.class);
+            MockEndpoint noMatch = context.getEndpoint("mock:noMatch", 
MockEndpoint.class);
+
+            // positive example: cheese namespace
+            cheeseMatch.expectedMessageCount(1);
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/cheese\";>55</number>");
+            cheeseMatch.assertIsSatisfied();
+
+            // positive example: wine namespace
+            wineMatch.expectedMessageCount(1);
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/wine\";>77</number>");
+            wineMatch.assertIsSatisfied();
+
+            noMatch.expectedMessageCount(2);
+
+            // negative, data-wise: correct namespace, wrong value
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/cheese\";>99</number>");
+
+            // negative, namespace-wise: correct value, wrong namespace URI
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/water\";>77</number>");
+
+            noMatch.assertIsSatisfied();
+        }
+    }
+}
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 5a40d6b83956..d62465d1a36d 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
@@ -21026,6 +21026,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "id", type = "string", description = 
"The id of this node.", displayName = "Id"),
                     @YamlProperty(name = "mode", type = "enum:i,w,u,t", 
defaultValue = "i", description = "The extraction mode. The available 
extraction modes are: i - injecting the contextual namespace bindings into the 
extracted token (default), w - wrapping the extracted token in its ancestor 
context, u - unwrapping the extracted token to its child content, t - 
extracting the text content of the specified element.", displayName = "Mode"),
                     @YamlProperty(name = "namespace", type = 
"array:org.apache.camel.model.PropertyDefinition", description = "Injects the 
XML Namespaces of prefix to uri mappings.", displayName = "Namespace"),
+                    @YamlProperty(name = "namespacesRef", type = "string", 
description = "Reference to a org.apache.camel.support.builder.Namespaces bean 
in the registry to use for the XML Namespaces of prefix to uri mappings.", 
displayName = "Namespaces Ref"),
                     @YamlProperty(name = "resultType", type = "string", 
description = "The class of the result type (type from output).", displayName = 
"Result Type"),
                     @YamlProperty(name = "source", type = "string", 
description = "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body.", displayName = "Source"),
                     @YamlProperty(name = "trim", type = "boolean", 
defaultValue = "true", description = "Whether to trim the source code to remove 
leading and trailing whitespaces and line breaks.", displayName = "Trim")
@@ -21076,6 +21077,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setNamespace(val);
                     break;
                 }
+                case "namespacesRef": {
+                    String val = asText(node);
+                    target.setNamespacesRef(val);
+                    break;
+                }
                 case "resultType": {
                     String val = asText(node);
                     target.setResultTypeName(val);
@@ -21123,6 +21129,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "id", type = "string", description = 
"The id of this node.", displayName = "Id"),
                     @YamlProperty(name = "logNamespaces", type = "boolean", 
defaultValue = "false", description = "Whether to log namespaces which can 
assist during troubleshooting.", displayName = "Log Namespaces"),
                     @YamlProperty(name = "namespace", type = 
"array:org.apache.camel.model.PropertyDefinition", description = "Injects the 
XML Namespaces of prefix to uri mappings.", displayName = "Namespace"),
+                    @YamlProperty(name = "namespacesRef", type = "string", 
description = "Reference to a org.apache.camel.support.builder.Namespaces bean 
in the registry to use for the XML Namespaces of prefix to uri mappings.", 
displayName = "Namespaces Ref"),
                     @YamlProperty(name = "objectModel", type = "string", 
description = "The XPath object model to use.", displayName = "Object Model"),
                     @YamlProperty(name = "preCompile", type = "boolean", 
defaultValue = "true", description = "Whether to enable pre-compiling the xpath 
expression during initialization phase. pre-compile is enabled by default.", 
displayName = "Pre Compile"),
                     @YamlProperty(name = "resultQName", type = 
"enum:NUMBER,STRING,BOOLEAN,NODESET,NODE", defaultValue = "NODESET", 
description = "Sets the output type supported by XPath.", displayName = "Result 
QName"),
@@ -21183,6 +21190,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setNamespace(val);
                     break;
                 }
+                case "namespacesRef": {
+                    String val = asText(node);
+                    target.setNamespacesRef(val);
+                    break;
+                }
                 case "objectModel": {
                     String val = asText(node);
                     target.setObjectModel(val);
@@ -21253,6 +21265,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "expression", type = "string", 
required = true, description = "The expression value in your chosen language 
syntax.", displayName = "Expression"),
                     @YamlProperty(name = "id", type = "string", description = 
"The id of this node.", displayName = "Id"),
                     @YamlProperty(name = "namespace", type = 
"array:org.apache.camel.model.PropertyDefinition", description = "Injects the 
XML Namespaces of prefix to uri mappings.", displayName = "Namespace"),
+                    @YamlProperty(name = "namespacesRef", type = "string", 
description = "Reference to a org.apache.camel.support.builder.Namespaces bean 
in the registry to use for the XML Namespaces of prefix to uri mappings.", 
displayName = "Namespaces Ref"),
                     @YamlProperty(name = "resultType", type = "string", 
description = "The class of the result type (type from output).", displayName = 
"Result Type"),
                     @YamlProperty(name = "source", type = "string", 
description = "Source to use, instead of message body. You can prefix with 
variable:, header:, or property: to specify kind of source. Otherwise, the 
source is assumed to be a variable. Use empty or null to use default source, 
which is the message body.", displayName = "Source"),
                     @YamlProperty(name = "trim", type = "boolean", 
defaultValue = "true", description = "Whether to trim the source code to remove 
leading and trailing whitespaces and line breaks.", displayName = "Trim")
@@ -21298,6 +21311,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setNamespace(val);
                     break;
                 }
+                case "namespacesRef": {
+                    String val = asText(node);
+                    target.setNamespacesRef(val);
+                    break;
+                }
                 case "resultType": {
                     String val = asText(node);
                     target.setResultTypeName(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 5c915ce5da31..f67f6807d1b7 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
@@ -10576,6 +10576,11 @@
               "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
             }
           },
+          "namespacesRef" : {
+            "type" : "string",
+            "title" : "Namespaces Ref",
+            "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+          },
           "resultType" : {
             "type" : "string",
             "title" : "Result Type",
@@ -10635,6 +10640,11 @@
               "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
             }
           },
+          "namespacesRef" : {
+            "type" : "string",
+            "title" : "Namespaces Ref",
+            "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+          },
           "objectModel" : {
             "type" : "string",
             "title" : "Object Model",
@@ -10713,6 +10723,11 @@
               "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
             }
           },
+          "namespacesRef" : {
+            "type" : "string",
+            "title" : "Namespaces Ref",
+            "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+          },
           "resultType" : {
             "type" : "string",
             "title" : "Result Type",
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
index 2a19bbe7cccc..2a965559ce02 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
@@ -15978,6 +15978,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "resultType",
         "type" : "string",
@@ -16032,6 +16037,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "objectModel",
         "type" : "string",
@@ -16105,6 +16115,11 @@
         "ref" : "property",
         "description" : "Injects the XML Namespaces of prefix to uri 
mappings.",
         "title" : "Namespace"
+      }, {
+        "name" : "namespacesRef",
+        "type" : "string",
+        "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings.",
+        "title" : "Namespaces Ref"
       }, {
         "name" : "resultType",
         "type" : "string",
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 9324a3669b58..9f5731ff56af 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
@@ -14381,6 +14381,11 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
               }
             },
+            "namespacesRef" : {
+              "type" : "string",
+              "title" : "Namespaces Ref",
+              "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+            },
             "resultType" : {
               "type" : "string",
               "title" : "Result Type",
@@ -14444,6 +14449,11 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
               }
             },
+            "namespacesRef" : {
+              "type" : "string",
+              "title" : "Namespaces Ref",
+              "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+            },
             "objectModel" : {
               "type" : "string",
               "title" : "Object Model",
@@ -14526,6 +14536,11 @@
                 "$ref" : 
"#/items/definitions/org.apache.camel.model.PropertyDefinition"
               }
             },
+            "namespacesRef" : {
+              "type" : "string",
+              "title" : "Namespaces Ref",
+              "description" : "Reference to a 
org.apache.camel.support.builder.Namespaces bean in the registry to use for the 
XML Namespaces of prefix to uri mappings."
+            },
             "resultType" : {
               "type" : "string",
               "title" : "Result Type",
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/XPathNamespacesRefYamlDslTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/XPathNamespacesRefYamlDslTest.java
new file mode 100644
index 000000000000..5726b286eb07
--- /dev/null
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/XPathNamespacesRefYamlDslTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.yaml;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.support.builder.Namespaces;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests that a route loaded from YAML DSL can reference a {@link Namespaces} 
bean from the registry via the xpath
+ * step's namespacesRef property, with the bean itself also declared in YAML.
+ */
+class XPathNamespacesRefYamlDslTest {
+
+    @Test
+    void loadsXPathWithNamespacesRef() throws Exception {
+        try (DefaultCamelContext context = new DefaultCamelContext()) {
+            YamlRoutesBuilderLoader loader = new YamlRoutesBuilderLoader();
+            loader.setCamelContext(context);
+            RoutesBuilder routesBuilder = 
loader.loadRoutesBuilder(ResourceHelper.fromString("xpath-namespaces-ref.yaml", 
"""
+                    - beans:
+                        - name: myNamespaces
+                          type: org.apache.camel.support.builder.Namespaces
+                          properties:
+                            namespaces[c]: "http://acme.com/cheese";
+                            namespaces[w]: "http://acme.com/wine";
+                    - route:
+                        id: xpath-namespaces-ref
+                        from:
+                          uri: "direct:xpathNamespacesRef"
+                          steps:
+                            - choice:
+                                when:
+                                  - xpath:
+                                      expression: "/c:number = 55"
+                                      resultQName: "BOOLEAN"
+                                      namespacesRef: "myNamespaces"
+                                    steps:
+                                      - to: "mock:cheeseMatch"
+                                  - xpath:
+                                      expression: "/w:number = 77"
+                                      resultQName: "BOOLEAN"
+                                      namespacesRef: "myNamespaces"
+                                    steps:
+                                      - to: "mock:wineMatch"
+                                otherwise:
+                                  steps:
+                                    - to: "mock:noMatch"
+                    """));
+            context.addRoutes(routesBuilder);
+            context.start();
+
+            MockEndpoint cheeseMatch = context.getEndpoint("mock:cheeseMatch", 
MockEndpoint.class);
+            MockEndpoint wineMatch = context.getEndpoint("mock:wineMatch", 
MockEndpoint.class);
+            MockEndpoint noMatch = context.getEndpoint("mock:noMatch", 
MockEndpoint.class);
+
+            // positive example: cheese namespace
+            cheeseMatch.expectedMessageCount(1);
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/cheese\";>55</number>");
+            cheeseMatch.assertIsSatisfied();
+
+            // positive example: wine namespace
+            wineMatch.expectedMessageCount(1);
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/wine\";>77</number>");
+            wineMatch.assertIsSatisfied();
+
+            noMatch.expectedMessageCount(2);
+
+            // negative, data-wise: correct namespace, wrong value
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/cheese\";>99</number>");
+
+            // negative, namespace-wise: correct value, wrong namespace URI
+            
context.createProducerTemplate().sendBody("direct:xpathNamespacesRef",
+                    "<number xmlns=\"http://acme.com/water\";>77</number>");
+
+            noMatch.assertIsSatisfied();
+        }
+    }
+}

Reply via email to