Splitter advice

2007-10-26 Thread Arjan Moraal

Hi all,

Take the following XML:
  cats
cat name=Gingercolour id=1//cat
cat name=Mr Bootscolour id=3//cat
cat name=Delphicolour id=1//cat
  /cats

Is it possible to use the Splitter to break split up this XML, but grouped
by colour id? So it should result in two messages:

  cats
cat name=Gingercolour id=1//cat
cat name=Delphicolour id=1//cat
  /cats

and

  cats
cat name=Mr Bootscolour id=3//cat
  /cats

Without the surrounding cats tags would be fine as well since I could add
these manually using setBody().

So far, I have set up this TestCase, but the problem is it breaks the xml up
into 3 messages instead of 2.

public void testGroupedXMLSplitter() throws Exception {
log.debug(testGroupedXMLSplitter());

final String xml = cats +
cat name=\Ginger\colour id=\1\//cat +
cat name=\Mr Boots\colour id=\3\//cat +
cat name=\Delphi\colour id=\1\//cat +
 /cats;

context.addRoutes(
new RouteBuilder() {
@Override
public void configure() {
from(direct:cats)
.splitter(xpath(/cats/cat/colour/@id))
.to(mock:result);
}
}
);

resultEndpoint.expectedMessageCount(2);

template.send(direct:cats, new Processor() {
public void process(Exchange exchange) {
Message in = exchange.getIn();
in.setBody(xml);
}
});

resultEndpoint.assertIsSatisfied();
}

Any help would be appreciated very much!

Thanks,
Arjan

-- 
View this message in context: 
http://www.nabble.com/Splitter-advice-tf4696876s22882.html#a13425803
Sent from the Camel - Users mailing list archive at Nabble.com.



Re: Splitter advice

2007-10-26 Thread James Strachan
I guess this is a great use case for XQuery, where you can use the
kinda SQL-ish nature to iterate through all values of the colour id,
then for each of them create a kinda nested document; then split that
into pieces. (You could use XSLT as well).

So transform into something like

colours
 colour id=1 cat/ cat/ /colour

Then split on /colours/colour

On 26/10/2007, Arjan Moraal [EMAIL PROTECTED] wrote:

 Hi all,

 Take the following XML:
   cats
 cat name=Gingercolour id=1//cat
 cat name=Mr Bootscolour id=3//cat
 cat name=Delphicolour id=1//cat
   /cats

 Is it possible to use the Splitter to break split up this XML, but grouped
 by colour id? So it should result in two messages:

   cats
 cat name=Gingercolour id=1//cat
 cat name=Delphicolour id=1//cat
   /cats

 and

   cats
 cat name=Mr Bootscolour id=3//cat
   /cats

 Without the surrounding cats tags would be fine as well since I could add
 these manually using setBody().

 So far, I have set up this TestCase, but the problem is it breaks the xml up
 into 3 messages instead of 2.

 public void testGroupedXMLSplitter() throws Exception {
 log.debug(testGroupedXMLSplitter());

 final String xml = cats +
 cat name=\Ginger\colour id=\1\//cat +
 cat name=\Mr Boots\colour id=\3\//cat +
 cat name=\Delphi\colour id=\1\//cat +
  /cats;

 context.addRoutes(
 new RouteBuilder() {
 @Override
 public void configure() {
 from(direct:cats)
 .splitter(xpath(/cats/cat/colour/@id))
 .to(mock:result);
 }
 }
 );

 resultEndpoint.expectedMessageCount(2);

 template.send(direct:cats, new Processor() {
 public void process(Exchange exchange) {
 Message in = exchange.getIn();
 in.setBody(xml);
 }
 });

 resultEndpoint.assertIsSatisfied();
 }

 Any help would be appreciated very much!

 Thanks,
 Arjan


 --
 View this message in context: 
 http://www.nabble.com/Splitter-advice-tf4696876s22882.html#a13425803
 Sent from the Camel - Users mailing list archive at Nabble.com.




-- 
James
---
http://macstrac.blogspot.com/

Open Source SOA
http://open.iona.com


Re: Splitter advice

2007-10-26 Thread Arjan Moraal

Thanks James.

Not sure if I'm ready for XQuery yet. I think I was hoping for a one-line
solution ;)

But I now managed to do it with a custom expression:

context.addRoutes(
new RouteBuilder() {
@Override
public void configure() {
from(direct:cats)
.splitter(new ExpressionExchange() {
public Object evaluate(Exchange exchange) {
log.debug(evaluate());
HashMapString,String snippets = new
HashMapString,String();
org.dom4j.Document xmlDoc = 
(new
DOMReader()).read(exchange.getIn().getBody(
org.w3c.dom.Document.class));   
 
IteratorNode it =
xmlDoc.selectNodes(cats/cat).iterator();
while (it.hasNext()) {
Node child = it.next();
String key =
child.valueOf(colour/@id);
if (snippets.containsKey(key)) {
snippets.put(key,
snippets.get(key)+child.asXML());
} else {
snippets.put(key, child.asXML());
}
}
return snippets.values();
}
  })
.setBody(el(cats${in.body}/cats))
.to(mock:result);
}
}
);



James.Strachan wrote:
 
 I guess this is a great use case for XQuery, where you can use the
 kinda SQL-ish nature to iterate through all values of the colour id,
 then for each of them create a kinda nested document; then split that
 into pieces. (You could use XSLT as well).
 
 So transform into something like
 
 colours
  colour id=1 cat/ cat/ /colour
 
 Then split on /colours/colour
 

-- 
View this message in context: 
http://www.nabble.com/Splitter-advice-tf4696876s22882.html#a13428590
Sent from the Camel - Users mailing list archive at Nabble.com.



Re: Splitter advice

2007-10-26 Thread James Strachan
On 26/10/2007, Arjan Moraal [EMAIL PROTECTED] wrote:

 Thanks James.

 Not sure if I'm ready for XQuery yet. I think I was hoping for a one-line
 solution ;)

Yeah - me too :) Well with enough XQuery knowledge, it would be about
a one liner :). I confess I'm no XQuery ninja either. Something
vaguely like...

for $x in distinct-values(//colour/@id) return //cat[colour/@id = $x]

Though warning I've never done much with XQuery so the above could be
total garbage :)



 But I now managed to do it with a custom expression:

[snip]

Yeah - its nice that folks can always drop down to good old Java code
and solve problems that way; then over time hopefully we'll be able to
solve these kinds of issues in more elegant ways.

-- 
James
---
http://macstrac.blogspot.com/

Open Source SOA
http://open.iona.com