Spring xslt processing works on a string but not a dom - java

I'm using Apache Camel 2.10.4 to create xml documents. I want to view the xml as html in one use case so my Camel route (defined in Spring DSL) uses an xslt to transform the xml document to html.
The xml is generated in a Java bean and output as a DOM Document.
If I use convertBodyTo to convert the Document to a String before handing it to the xslt all is well. If I leave this out, the xslt processor doesn't find the elements in my document.
This returns an html string with a table containing a row for each schedule item in my TVAnytime xml document:
<route>
<from uri="direct:show_bn"/>
<to uri="bean:gen"/>
<convertBodyTo type="java.lang.String"/>
<to uri="xslt:tva2html.xslt"/>
<setHeader headerName="Content-Type">
<constant>text/html;</constant>
</setHeader>
</route>
This returns the html with no rows in the table:
<route>
<from uri="direct:show_bn"/>
<to uri="bean:gen"/>
<to uri="xslt:tva2html.xslt"/>
<setHeader headerName="Content-Type">
<constant>text/html;</constant>
</setHeader>
</route>
The method executed in the bean has this signature:
public org.w3c.dom.Document process();
Any idea why this is happening? I suspect something wrong with namespace aware processing when the xslt processing gets a DOM.

I just added a quick test in camel-core, I cannot reproduce the error.

Related

How to use method with parameters in Camel XML DSL?

I've got a problem with using method with parameters in Camel XML DSL.
What I've done is something like this:
I've created below bean before my camelContext
<bean id="properties" class="java.util.Properties"/>
The thing I would like to do is using method 'put' from HashTable, which extends Properties.
When I call a method without parameter it's working perfectly fine.
<method ref="properties" method="NAME OF METHOD THAT HAS NO PARAMETERS">
or
<bean ref="properties" method="SAME AS ABOVE"/>
Method that I'm trying to use:
public synchronized V put(K key, V value)
But when I'm trying to use something like the code below I would like to assign some parameters
I've tried a lot of possibilities, maybe it's impossible or my knowledge of syntax is poor:
<method ref="properties" method="put" argument="key_el" arugment="val_el"/>
<method ref="properties" method="put" value="key_el" value="val_el"/>
<method ref="properties" method="put?keyEl&valEl"/>
<method ref="properties" method="put">
<argument id="key" value="someKey" type="java.lang.String"/>
<argument id="value" value="someValue" type="java.lang.String"/>
</method>
There's plenty more that I've tired, some of them are just not worth of showing. I read from people apache and camel documentation, that there's possibility to make it somehow but there was no example of doing that in XML DSL.
Thanks in advance for any hints and help.
You can call beans method with arguments using method="put('key', 'value')". You can also use simple syntax there if you need values from the Exchange like body, headers or exchange properties `method="put('bodyValue', ${body})"``
This approach also works with simple language. Say if you have object stored in to message header you can call it's methods using ${headers.helloBean.hello('Tim')}
<bean id="ExampleProperties" class="java.util.Properties" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="testRoute">
<from uri="direct:testRoute" />
<bean ref="ExampleProperties" method="put('bodyValue', ${body})" />
<setBody>
<simple>${bean:ExampleProperties?method=get('bodyValue')}</simple>
</setBody>
<log message="Body value: ${body}" />
</route>
</camelContext>
Be careful when storing values to beans instead of using body, headers or exchange properties as beans persist between exchanges.

Camel split CSV file on regex

I am working on one case where I have csv file with below data
100| Some Delimited Data
200| Some Delimited Data
100| Some Delimited Data
400| Some Delimited Data
400| Some Delimited Data
200| Some Delimited Data
I am trying to make camel route where
when 100
marshal csv & send to Bean
when 200
marshal csv & send to bean
I am trying to route it with camel.
Example when I do in XML I can parse XML in route
I cannot use Camel-Bindy as I don't have fixed delimiters in row
example
Row 1 can have 10 '|' (pipes / delimiter)
Row 2 can have 20 '|' (pipes / delimiter)
Row 3 can have 16 '|' (pipes / delimiter)
They are variable in length which I have handled in bean. Is there any way where I can parse or use any regex?
Since you are always using | as a delimiter, you can use the default CSV support to load the content as a list of lists, then split the body to get each row as a list and then process that list (row) in your bean:
<unmarshal>
<csv delimiter="|"/>
</unmarshal>
<split>
<simple>${body}</simple> <!-- Body will be a list of lists -->
<choice>
<when>
<simple>${body[0]} == '100'</simple>
<to uri="bean:processor100"/>
</when>
<when>
<simple>${body[0]} == '200'</simple>
<to uri="bean:processor200"/>
</when>
</choice>
</split>

How to use xpath in camel when the outermost element has an xmlns attribute?

I am having some trouble using xpath to extract the "Payload" values below using apache-camel. I use the below xpath in my route for both of the example xml, the first example xml returns SomeElement and SomeOtherElement as expected, but the second xml seems unable to parse the xml at all.
xpath("//Payload/*")
This example xml parses just fine.
<Message>
<Payload>
<SomeElement />
<SomeOtherElement />
</Payload>
</Message>
This example xml does not parse.
<Message xmlns="http://www.fake.com/Message/1">
<Payload>
<SomeElement />
<SomeOtherElement />
</Payload>
</Message>
I found a similar question about xml and xpath, but it deals with C# and is not a camel solution.
Any idea how to solve this using apache-camel?
Your 2nd example xml, specifies a default namespace: xmlns="http://www.fake.com/Message/1" and so your xpath expression will not match, as it specifies no namespace.
See http://camel.apache.org/xpath.html#XPath-Namespaces on how to specify a namespace.
You would need something like
Namespaces ns = new Namespaces("fk", "http://www.fake.com/Message/1");
xpath("//fk:Payload/*", ns)
I'm not familiar with Apache-Camel, this was just a result of some quick googling.
An alternative maybe to just change your xPath to something like
xpath("//*[local-name()='Payload']/*)
Good luck.

DOM xml parsing difficulties in java

<XML>
<log>
<date>20022014</date>
<time>2323</time>
<schools>
<school name="ahss"/>
<student>shiva</student>
<class>B</class>
</schools>
</log>
<log>...</log>
</XML>
need to parse this xml format using DOM i have tried many substitutes but i couldn't get it
is there any one to give shoulder

How to display xml with two parent nodes

How to generate xml using dom parser in java , as shown below
<result>
<schma_index>
<id>8</id>
<name>raja</name>
<schma_index>
</result>
Above should be display like
<Massage>No privilege</Mesaage>
<result>
<schma_index>
<id>8</id>
<name>raja</name>
<schma_index>
</result>
You can't have two root elements in xml. Read about well-formed xml. You can however generate Message and result xml's separately and then concatenate them. However, the parser's can't parse the result xml.
In a "Valid" XML, there can be only one root element. As per this specification:"There is exactly one element, called the root, or document element, no part of which appears in the content of any other element."
So, you have two options:
create two seperate xml files - one containing Message and other results
enclose Message & Results with some other root element:
i.e,
<root>
<Massage>No privillage</Mesaage>
<result>
<schma_index>
<id>8</id>
<name>raja</name>
<schma_index>
</result>
</root>

Categories