How to get xml nodes count in camel - java

I want to get the count of xml nodes present in the file with specific tags in camel exchange or camel route.
My xml tags are like this:
<parent>
<child>
<data>A</data>
</child>
<child>
<data>B</data>
</child>
<child>
<data>C</data>
<child>
<data>C1</data>
</child>
<child>
<data>C2</data>
</child>
</child>
</parent>
I want to count the <child> tags and it should return 5 for this.
Currently, I am getting size using Exchange but it is giving output as 3.
exchange.getIn().getBody(XmlTreesType.class).getParentTree().getChildNode().size();

This highly depends on your actual use case.
To extract the count, you could use the XPath language which allows you to extract information from XML easily.
To extract the count of all <child> nodes within your <parent> you could use the following:
count(/parent//child)
XPath expression.
To extract this value and store it in a header variable would look like this:
.from()
.setHeader("childCountHeader", xpath("count(/parent//child)", Integer.class));
Another typical use case in the camel Java DSL would be along the following, in order to directly route based on the count:
from()
.choice().xpath("count(/parent//child)>5")
//do something
.otherwise()
//do something else
.end();
If you want to use XPath inside vanilla java, as in a camel processor. You can build up an XPath processor as described in this answer.

Related

XPaths using EclipseLink MOXy and JAXB given a value of another element

I want to get the text value of a certain element in xml. In the XML below i want to get the value of SUBCHILD when the value of CODE is 'Code1' irrespective of the position of the MP entity when there could be many MP elements. Also i want to be able to do this using JAXB and MOXy with the #XMLPath attribute
The xml i have is this:
<RQ>
<PQ>
<MP>
<INFO>
<CODE>Code1</CODE>
</INFO>
<CHILD>
<SUBCHILD>VALUE for Code1</SUBCHILD>
</CHILD>
</MP>
<MP>
<INFO>
<CODE>Code2</CODE>
</INFO>
<CHILD>
<SUBCHILD>VALUE for Code2</SUBCHILD>
</CHILD>
</MP>
</PQ>
</RQ>
I want 'VALUE for Code1' irrespecive of its position, the MP element containing Code1 could be anywhere. The XPath i would use for this would be:
RQ/PQ/MP[INFO/CODE='Code1']/CHILD/SUBCHILD
but i cant seem to get the value i want from MOXy, is this functionality not supported, I know that you can map based on attributes, but i need it depending on the value of another element
Any help would be appreciated
MOXy currently does not support XPaths of the following form on its #XmlPath annotation.
There is an open bug to have an exception thrown if the XPath specified is not supported.
https://bugs.eclipse.org/397101
Can you open an enhancement request for the behaviour you are looking for?

Spring Batch Xml Item Read

I'm working with Spring Batch.
I think I already know how I can parse good-looking xml and binding object.
And I stuck with this problem.
<parent>
<child>
<key name="xxx">
<value>val</value>
</key>
<key name="yyy">
<value>val</value>
</key>
</child>
</parent>
How can I parse xml items for above xml to children defined like this?
class Child {
private String xxx;
private String yyy;
}
I know how I can parse when it looks like this.
<parent>
<child>
<xxx>val</xxx>
<yyy>val</yyy>
</child>
</parent>
Is there any XPath like mappings with Spring-Batch's XML item reader?
Use a Jaxb2Unmarshaller.
Check aroudn for a jaxb solution: it's full around the net.
In the worst case I remember you can write your own node parser and manage this form of your child tag.
I'm sorry but I can't add code because I'm not at work.
Hope can be help

XML parsing /JAVA

I have an XML, for example
<root>
<config x="xxx" y="yyyy" z="zzz" />
<properties>blah blah blah </properties>
<example>
<name>...</name>
<decr>...</descr>
</example>
<example>
<name>...</name>
<decr>...</descr>
</example>
</root>
and I need to get nodes config, and properties and all values in it.
Thank you
Xpath can fetch you the data in the config tag. You need to create an expression first like this
expression="//root/config/#x", to get value of x,y,z.
For properties, follow this thread :
Parsing XML with XPath in Java
Hope this helps
DOM,DOM4J,SAX..
if the size of XML file is small,you can use DOM or DOM4J,but the size is big , you use the SAX
If you directly want to query or fetch data XPath can help, but if you want the data as Java Objects so that you can use it further then use JAXB
You can use SAX parser to read the xml manipulate its event based parsing and consumes more memory.
If your xml is big and requires lot of manipulations then go-for DOM/DOM4j either is good. DOM4L is very latest. DOM is widely used in industry.
Based on your requirement go for good parser.
Thanks,
Pavan

OAI Jaxen XPath problem

I'm having big problems with Xpath evaluation using Jaxen.
Here's part of XML i'm evaluating on:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>2011-05-31T13:04:08+00:00</responseDate>
<request metadataPrefix="oai_dc" verb="ListRecords">http://citeseerx.ist.psu.edu/oai2</request>
<ListRecords>
<record>
<header>
<identifier>oai:CiteSeerXPSU:10.1.1.1.1484</identifier>
<datestamp>2009-05-24</datestamp>
</header>
<metadata>
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>Winner-Take-All..</dc:title>
<dc:relation>10.1.1.134.6077</dc:relation>
<dc:relation>10.1.1.65.2144</dc:relation>
<dc:relation>10.1.1.54.7277</dc:relation>
<dc:relation>10.1.1.48.5282</dc:relation>
</oai_dc:dc>
</metadata>
</record>
<resumptionToken>10.1.1.1.2041-1547151-500-oai_dc</resumptionToken>
</ListRecords>
</OAI-PMH>
I'm using Jaxen because in my use case it's much faster then Apache implementation. I'm using W3C DOM for XML representation.
I need to select all record arguments, and then on selected nodes evaluate other xpaths (it's needed because of my processing architecture).
I'm selecting all record nodes (this works):
/OAI-PMH/ListRecords/record
Then on every selected record node I'm evaluating other xpaths to get needed data:
Select identifier text value (this works):
header/identifier/text()
Select title text value (this does NOT work):
metadata/oai_dc:dc/dc:title/text()
I've registered namespaces prefixes with their URIs (oai_dc and dc). I also tried other xpaths but none of them work:
metadata/dc/title/text()
metadata//dc:title/text()
I've read other stackoverflow questions about xpaths, namespaces and solution to add prefix "oai" with URI "http://www.openarchives.org/OAI/2.0/". I tried adding that "oai:" prefix to nodes without defined prefix but as result I even didn't select record nodes. Any ideas what I'm doing wrong?
Solution:
Problem was about parser (thanks jasso). It wasn't set to be namespace aware - after changing that setting everything works fine, as expected.
I can't see how the XPath expression /OAI-PMH/ListRecords/record can possibly select anything, since your document does not have a {}OAI-PMH element, only a {http://www.openarchives.org/OAI/2.0/}OAI-PMH element. See http://jaxen.codehaus.org/faq.html

Finding all valid xpath from xml

I am trying to write a program in java where in i can find all the xpath for the given xml.I found out the link on the internet xpath generator but it does not work when one element can repeat multipletimes for example if we have xml like the following :-
<?xml version="1.0" encoding="UTF-8"?>
<Report>
<Name>
<FirstName>A</FirstName>
<LastName>B</LastName>
<MiddleName>C</MiddleName>
</Name>
<Name>
<FirstName>D</FirstName>
<LastName>E</LastName>
<MiddleName>S</MiddleName>
</Name>
</Report>
It will produce xpaths :-
/Report/Name/firstname for both firstname nodes.
but the expected should be /Report/Name1/firstname and /Report/Name[2]/firstname
Any ideas?
I think you may have to do this yourself.
Using a SAX parser will make it straightforward. Just maintain a stack of the elements you encounter and a count so you can increment the indexes (/Report/Name[1], /Report/Name[2]) easily.

Categories

Resources