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

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


The following commit(s) were added to refs/heads/main by this push:
     new 6985d372bba CAMEL-20151: camel-xpath - Add xpath as function to simple 
for basic templating (#12194)
6985d372bba is described below

commit 6985d372bba15131672895d245f5ffa76336ddc2
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Fri Nov 24 16:30:44 2023 +0100

    CAMEL-20151: camel-xpath - Add xpath as function to simple for basic 
templating (#12194)
---
 .../camel-xpath/src/main/docs/xpath-language.adoc  | 57 ++++++++++++++++++
 .../modules/languages/pages/simple-language.adoc   |  3 +
 .../simple/ast/SimpleFunctionExpression.java       |  9 +++
 .../camel/language/SimpleXPathTransformTest.java   | 69 ++++++++++++++++++++++
 4 files changed, 138 insertions(+)

diff --git a/components/camel-xpath/src/main/docs/xpath-language.adoc 
b/components/camel-xpath/src/main/docs/xpath-language.adoc
index da7706b8b94..43f736a571b 100644
--- a/components/camel-xpath/src/main/docs/xpath-language.adoc
+++ b/components/camel-xpath/src/main/docs/xpath-language.adoc
@@ -513,6 +513,63 @@ eg to refer to a file on the classpath you can do:
 .setHeader("myHeader").xpath("resource:classpath:myxpath.txt", String.class)
 ----
 
+== Transforming a XML message
+
+For basic XML transformation where you have a fixed structure you can 
represent with a combination of using
+Camel simple and XPath language as:
+
+Given this XML body
+
+[source,xml]
+----
+<order id="123">
+  <item>Brake</item>
+  <first>scott</first>
+  <last>jackson</last>
+  <address>
+    <co>sweden</co>
+    <zip>12345</zip>
+  </address>
+</order>
+----
+
+Which you want to transform to a smaller structure:
+
+[source,xml]
+----
+<user>
+  <rool>123</rool>
+  <country>sweden</country>
+  <fullname>scott</fullname>
+</user>
+----
+
+Then you can use simple as template and XPath to grab the content from the 
message payload, as shown in the route snippet below:
+
+[source,java]
+----
+from("direct:start")
+        .transform().simple("""
+                <user>
+                  <rool>${xpath(/order/@id)}</rool>
+                  <country>${xpath(/order/address/co/text())}</country>
+                  <fullname>${xpath(/order/first/text())}</fullname>
+                </user>""")
+        .to("mock:result");
+----
+
+Notice how we use `${xpath(exp}` syntax in the simple template to use xpath 
that will be evaluated on the message body,
+to extract the content to be used in the output (see previous for output).
+
+Since the simple language can output anything you can also use this to output 
in plain text or JSon etc.
+
+[source,java]
+----
+from("direct:start")
+        .transform().simple("The order ${xpath(/order/@id)} is being shipped 
to ${xpath(/order/address/co/text())}")
+        .to("mock:result");
+----
+
 == Dependencies
 
 To use XPath in your camel routes you need to add the dependency on
diff --git 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index b2f43ee25c2..9d9452bb9b1 100644
--- 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++ 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -255,6 +255,9 @@ where the ID is _myGenerator_.
 |jq(exp) | Object | When working with JSon data, then this allows to use the 
JQ language
 for example to extract data from the message body (in JSon format). This 
requires having camel-jq JAR on the classpath.
 
+|xpath(exp) | Object | When working with XML data, then this allows to use the 
XPath language
+for example to extract data from the message body (in XML format). This 
requires having camel-xpath JAR on the classpath.
+
 |=======================================================================
 
 == OGNL expression support
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index edf10b84a0c..d0f93f30cce 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -462,6 +462,15 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
             exp = StringHelper.removeQuotes(exp);
             return ExpressionBuilder.languageExpression("jq", exp);
         }
+        remainder = ifStartsWithReturnRemainder("xpath(", function);
+        if (remainder != null) {
+            String exp = StringHelper.beforeLast(remainder, ")");
+            if (exp == null) {
+                throw new SimpleParserException("Valid syntax: ${xpath(exp)} 
was: " + function, token.getIndex());
+            }
+            exp = StringHelper.removeQuotes(exp);
+            return ExpressionBuilder.languageExpression("xpath", exp);
+        }
 
         return null;
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/SimpleXPathTransformTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/SimpleXPathTransformTest.java
new file mode 100644
index 00000000000..dbba17e0d76
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/SimpleXPathTransformTest.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;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+public class SimpleXPathTransformTest extends ContextTestSupport {
+
+    private static String EXPECTED = """
+            <user>
+              <rool>123</rool>
+              <country>sweden</country>
+              <fullname>scott</fullname>
+            </user>""";
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start")
+                        .transform().simple("""
+                                <user>
+                                  <rool>${xpath(/order/@id)}</rool>
+                                  
<country>${xpath(/order/address/co/text())}</country>
+                                  
<fullname>${xpath(/order/first/text())}</fullname>
+                                </user>""")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    @Test
+    public void testTransform() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived(EXPECTED);
+
+        template.sendBody("direct:start", """
+                <order id="123">
+                  <item>Brake</item>
+                  <first>scott</first>
+                  <last>jackson</last>
+                  <address>
+                    <co>sweden</co>
+                    <zip>12345</zip>
+                  </address>
+                </order>
+                """);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+}

Reply via email to