Positioning the cursor in a Java service

OK, I thought this would be simple, but …

I’m passing a document in to a Java service. I want to position the cursor at some point in that document (like “x/y/z”). So I try (naturally) cursor.first(“x/y/z”). This returns false (doesn’t find the element) so my code throws an exception. Now, of course, I can successfully do cursor.first(“x”).

So does first(“key”) really not accept a path as its key, only a simple string? It seems that can’t be right. Do I really have to do:

cursor.first(“x”);
cursor.first(“y”);
cursor.first(“z”);

?

If you have the “node” representation of the document, you can do a queryDoc that will snag the contents using a path.

OK, so I take it it really isn’t that simple :-). What we’ve done so far has been to simply declare the inputs we need in the Java service explicitly and force the calling Flow to extract them (map them in). This works fine, so I’ll leave it as-is. I just thought the Java service would be able to navigate the document containing these parameters, which I know is already in the pipeline. Thanks.

You can use the IDataTreeCursor to use the down() and up() methods. But be aware that these are deprecated and there is no replacement.

Thanks Rupinder. My situation actually doesn’t warrant using deprecated methods, so I’ll stick with extracting my required inputs from the document in the Flow service and declaring them individually as inputs to my Java service. It’s surprising though, that there isn’t a way to pass in a path as the key to first(). Seems like that would be very convenient. Well, back to the wishlist. :slight_smile:

Record structures are stored in objects accessible via the IData interface. Nested records are thus nested IData structures. You should be able to get to “x/y/z” with the following code:

IData xRec = IDataUtil.getIData(cursor, “x”);
IDataCursor xCursor = xRec.getCursor();
IData yRec = IDataUtil.getIData(xCursor, “y”);
IDataCursor yCursor = yRec.getCursor();
String zVal = IDataUtil.getString(yCursor, “z”);
yCursor.destroy();
xCursor.destroy();
cursor.destroy();

Following my ‘Keep it simple’ philosophy, you could use a regular flow service to drill down to the node you want (using XQL for example), then just pass this node to your java service (if you need a java service), rather than have your java service parsing XML.

I agree, Will.

You would still use IDataUtil.getIData to get the desired node from the pipeline as an IData, but use the queryDocument (now called pub.xml:queryXMLNode in WM6) to do what it does well.

Mark

Well it’s actually even simpler than that for my case (where I only need the value, not the IData object). I have a document “x” in the pipeline, which contains a “y”, which contains a “z”. My Java service needs “z”. So in my Flow I can just expand down to “x/y/z” and map z to my Java service’s declared input.

It just so happened that I knew at this point that the document “x” was in the pipeline. So I thought I could avoid introducing another variable (set of variables) by using something like first() to select the element I wanted. All good information though. So thanks, it’s been a learning experience.