How to get XML file in camel - apache

I am writing a code where I am sending some employees information inside an XML file to some other location using Apache camel. Now , I need to change some values in the XML. How can I parse the XML and change the value and then send it to the location. I tried to do using .process() , but it's not working. Any suggestions will be helpful.

Use Camel BeanIO and parse your XML into Java Models and process them use the same Camel BeanIO schema to convert them back to XML from Java Models.

Below you can see an example of modification of the XML document:
#Override
public void process(Exchange exchange) throws Exception {
//Get your XML from exchange (maybe, your need to convert them to DOM Document before processing)
Document doc = exchange.getIn().getBody(Document.class);
//Here you can modify your XML
//Modification example begin -------------
Element root = doc.getDocumentElement();
Element element = doc.createElement("newElement");
element.setTextContent("New element value");
root.appendChild(element);
//Modification example end ---------------
exchange.getIn().setBody(doc);
}
I think, in your attempt, you just did not set a changed body to the exchange.

If you want to work with Java POJO's and let a framework do the XML parsing / marshalling / unmarshalling, you can use the JAXB capability.
Then, you could use Java POJO's to do the "edits" (i.e change the values) and convert to (or from) XML as / when appropriate using the marshal / unmarshal feature. This avoids the need for parsing the XML directly yourself (though that would work too of course).
More info here.

Related

Writing text data from PCollection to GCS with custom file name

In a dataflow job written in Kotlin
using a PubSub subscription as input i receive a Proto object (Event) and map this object to Strings.
My pipeline has type:
PCollection<KV<Event, String>>
These strings are the lines of a file that must be written in GCS.
The Event Object has a "Id" that must be used to set the filename, and a "name" to set the folder.
Is it possible using FileIO ?
pipeline.apply(
FileIO.writeDynamic<String, String>()
.to("gs://my-bucket")
// withNaming?
)
My goal is to write the right lines in the right files, based on the information in the Event object
File-names can be customized by providing a FileNaming implementation to the withNaming() API.
However this currently does not support mapping input elements directly to final file names. Input elements can be mapped to groups using the dynamic destinations API and for each group you can provide a file-naming strategy.
To fully customize naming using input element values you might need to implement a new sink transform.

How to retrieve an array of values from Java API in Karate?

I'm reading WSDL path and XML Request from excel file. I need to use these two data in my feature file. Reading action has been done on Java side but I don't know how to pass these into Karate - feature file.
I'm aware of single value passing from Java API to Karate like this.
* xmlstring xmlVar = response
* def APIHelperClass = Java.type('com.org.utilities.APIHelperClass')
* def result = APIHelperClass.getResponseFromFeatureFile(xmlVar,'getMembersDetailsResponse.xml')
Suggest me how to receive multiple values / array from JavaAPI into Karate.
Thanks
Please refer to this example: cats-java.feature and the corresponding Java class: JavaDemo.java.
So if you return data as a Java List it will be a JSON array. And a Map becomes a JSON object. This is explained in the documentation.
In your case if you return a HashMap with 2 keys e.g. wsdlPath and xmlRequest you should be easily able to use it in Karate.

Conditionally, Converting of JSON to XML using MuleSoft

I have a simple conversion of JSON to XML using MuleSoft. In "Transform Message" component, I provided JSON Schema as Input and XML Schema as Output. When I run the app, the conversion happens if the file matches with both schema but it generates an empty XML file if it doesn't match.
I want below conditions:
1) If the file matches with schema, the converted output file should be sent to converted folder and the original file should move to Success folder.
2) If the file doesn't match with schema, the original file should move to the Failure folder instead of conversion.
Hope, I explained it comprehensively as I am new to MuleSoft. Here is a sample diagram which may simplify my requirement. Provide me with a new one if I badly designed the process.
First thing you need to create a flowVar that will hold your original payload.
When your doing your evaluation, if its XML then use a simple XPath expression like //elementName[not(node())]
Lastly, on your success use scatter-gather for multi-threading write. Pull your original payload from flowVar and write to Success and Write your regular payload to your Converted folder

mapping a string containing xml in BizTalk

I have an xml document with a node that may optionally contain a string of escaped xml. I'd like to be able to transform that content using xsl in a BizTalk map. Any suggestion how?
I've tried:
msxsl:node-set(string). This creates a nameless single node with no content.
The document() function using a url prefix of 'data:text/xml' as suggested by helderdarocha here.
for-each selecting the text() of the node containing the string
using xpath() in an orchestration to extract the string then make a multipart message. It won't let me use an xmlDocument message as one of the messages in a multipart message transform.
Do I have to use a C# helper assembly to accomplish this?
I have tackled a similar issue in a project, where I have a series of 2 mappings (both native xslt).
The first map will map your input document to an intermediate format. This format has one "any" node (instead of the escaped XML node), where eventually, I put in the unescaped XML. I unescape using a C# extension object.
The C# code could just be a wrapper for System.Web.HttpUtility.HtmlDecode()
In the second mapping, you can map using plain XPath.
Example Input message:
<root>
<someNode>blabla</someNode>
<any><root2><myValue>escapedXml</myValue></root2></any>
</root>
Intermediate format:
<root>
<someNode>blabla</someNode>
<any>
<root2>
<myValue>escapedXml</myValue>
</root2>
</any>
</root>
In your second mapping, you could use XPaths like /root/any/root2/myValue/text() without any issue.
Important Note:
If you need to do XSD validation against this intermediate format, this is a good way to do this as well. You would just need to create the appropriate intermediate XSD according to your needs. In my case this was needed, so I had to validate this unescaped format using a receive pipeline execution in an orchestration.

XSLT vs. XQuery

I am new to those two technologies, I sketched their roles in generating an HTML out of raw XML file as I understood in these steps(Please correct me if I was wrong):
XML data source (database, RSS, ...)
XQuery (Data manipulation FLWR)
XSLT (Data representation through templating)
The resulting XHTML document to be delivered
I am wondering about the technical details of using them, to be specific, here are the questions:
How to implement XQuery in a PHP web server (I am using WAMP suite).
How can I request .xq page (can I do that directly, or should I use a CGI to do that?)
How can I pass the resulting XML page from XQuery call to XSLT for templating?
Could you give me some pointers the development environment to create a website using these technologies, thanks.
-- Update: I understand now that difference between XQuery and XSLT is a difference in point of view since two different working groups are maintaining them, both will do the job though in different approaches.
I am using XSLT only for both data operations and representation, I am implementing structured templating approach which is found here XSLT Abstractions in order to organize the work a little bit.
I have a system that works along the lines you describe. It runs like this;
Inputs
The XML data is a plain text file eg. "data.xml".
The XSL stylesheet is a plain text file eg. "style.xsl".
The xquery is a plain text file eg. "test.xq".
An xquery processor is running as a service on port 2409. (More about this below.)
Flow
A PHP script eg. "index.php" runs. It contacts the xquery processor like this;
$xml = file_get_contents("http://localhost:2409/test.xq");
The test.xq query is executed by the xquery processor. The test.xq query uses the doc function to load the data;
declare variable $root := doc("data.xml");
When test.xq finishes, the result is returned by the xquery processor to index.php.
Back in index.php, $xml now contains the result of the test.xq xquery. An XSLT processor is invoked to transform the XML into XHTML. The PHP code is something like;
$doc = new DOMDocument();
$doc->loadXML($xml);
$stylesheet = new DOMDocument();
$stylesheet->load("style.xsl");
$processor = new XSLTProcessor();
$processor->importStylesheet($stylesheet);
$xhtml = $processor->transformToXML($doc);
echo $xhtml;
The only part of all that which is not achievable using standard components is the xquery processor. I had to write that bit using a Java servlet to invoke the Saxon xquery processor. Both Java and Saxon are free but it still took a lot of learning to get it working.
You can see it working here.
I like this technique because a) it separates logic from presentation and b) it runs fast.