Tuesday, 6 July 2010

JDOM, XPath and Namespaces

The combination of JDOM and XPath seems to be the source of greatest woe for me of late - following my last blog post I spent (wasted) another day wrestling with these technologies on another sticking point. I'll not claim to be an XPath guru by any stretch (I am learning though!), but it does seem to throw some real curveballs. The latest was down to attempting to extract a List of JDOM sub-Elements from an Element using XPath.selectNodes(element). It continually refused to work, and seemed to be related to the fact that there was a namespace declaration in the root Element. After much head scratching and the help of the wider community, it came out that all that was needed was to wrap the Element in a Document. Can anyone with a deeper knowledge shed a light on why?

Here's the code that doesn't (but to my mind should) work:

Namespace ns = Namespace.getNamespace("srv","http://ess.com/ws/srv");
XPath filterXpression = XPath.newInstance("//srv:ItemCost");
filterXpression.addNamespace(ns);
List nodes = filterXpression.selectNodes(response);

And here's the working code:

Document build = new Document(response);
XPath filterXpression = XPath.newInstance("//srv:ItemCost");
List nodes = filterXpression.selectNodes(build);

You can get the full lowdown in this StackOverflow question.

Wednesday, 30 June 2010

JDOM & XPath Contexts

Second post today - its been a week of minor but frustrating issues so far and I want to publish as many solutions as I can find time for.

This issue had me scratching my head for a good few hours, and there didn't seem to be much solid documentation online to help out. I was using a combination of JDOM 1.0 and XPath to manipulate a short XML document (arriving via a SOAP interface). Here's the basic document structure that was the subject (Names have been changed to protect the innocent):

<srv:Root>
<srv:Name>Overall Name</srv:Name>
<srv:Items>
<srv:Item>
<srv:ItemName>Name 1</srv:ItemName>
<srv:ItemPrice>20</srv:ItemPrice>
</srv:Item>
<srv:Item>
<srv:ItemName>Name 2</srv:ItemName>
<srv:ItemPrice>30</srv:ItemPrice>
</srv:Item>
</srv:Items>
</srv:Root>

The above conforms to the schema set out for the message, everything validates fine. I was using the following to extract the Items, then iterate through each Item and print out the ItemName and the ItemPrice:


XPath itemXpression = XPath.newInstance("//srv:Item");
itemXpression.addNamespace(ns);
XPath itemXpression = XPath.newInstance("//srv:ItemName");
itemnameXpression.addNamespace(ns);
XPath itemXpression = XPath.newInstance("//srv:ItemPrice");
itempriceXpression.addNamespace(ns);

List nodes = itemXpression.selectNodes(document);

// Ensure we have some items to iterate through
if(!nodes.isEmpty()) {

Iterator it = nodes.iterator();

//Init list of Item
List items = new ArrayList();

//Iterate through all items
while(it.hasNext()) {

Element item = (Element)it.next();

Item i = new Item();

// Evaluate XPath expressions for values
String itemname = itemnameXpression.valueOf(item);
String itemprice = itempriceXpression.valueOf(item);

System.out.println(itemname);
System.out.println(itemprice);

}
}
}


However, the code always prints out the Name and Price of the first item twice, rather than the details of the first and then the details of the second.
I tried mixing it up with using pure JDOM to no avail, tried numerous different approaches, and ether got NPEs or that first item repeated twice. In the end, the solution was simply to adjust the XPath search expression from "//srv:Item..." to "/srv:Item...". It seems that despite the fact I'm explicitly passing in an Element containing only one Item (and using an XMLOutputter verifies this), preceeding the expression with // resets the search context to the overall document root. Strange behaviour, but there you go.

Useless Eclipse Error Messages

I had an absolute nightmare the other day with a web services project I was working on in Eclipse (actually Spring STS). I had written a WSDL file and accompanying Schema, and Eclipse was giving me a warning triangle at the very top of the document with the following useless error message:

WS-I: A problem occured while running the WS-I WSDL conformance check:
org.eclipse.wst.wsi.internal.analyzer.WSIAnalyzerException:
The conformance validation process failed.

The only further detail available is:

Nested exception is:
java.lang.NullPointerException The WSDLAnalyzer was unable to
validate the given WSDL File.

No indication of where there might be an error, or what might be causing the problem. After much removing and replacing of segments of the file, and external validation of the Schema document, my advice to anyone else facing this error is to double, triple and quadruple check the spelling and capitalisation of the name fields in the operations within the definition. Changing a few 'c's to 'C's sorted the issue out for me, but methinks its time for some more informative error messages Eclipse Team!

Tuesday, 8 June 2010

What's the time?

I've been having issues with a number of CentOS hosts not holding the correct time - they seem to be drifting incessantly, despite the fact that they should be syncing to a number of NTP servers. Looking at the output of an ntpdate, I get the following error:

[root@nx-01 ~]# ntpdate
8 Jun 09:29:09 ntpdate[4267]: no servers can be used, exiting

Although the log messages are showing that the server is quite happily synchronised to its NTP peers:

Jun 8 09:08:20 nx-01 ntpd[1698]: synchronized to LOCAL(0), stratum 10
Jun 8 09:09:25 nx-01 ntpd[1698]: synchronized to 77.75.105.150, stratum 2
Jun 8 09:13:41 nx-01 ntpd[1698]: synchronized to 62.84.188.34, stratum 2

Forcing ntp to update by shutting down the daemon and passing a server as an argument to ntpdate also has no effect - the drift remains.

After some head scratching, I've come across the root cause of this issue. The servers in question are actually DomU instances on a Xen host, and by default they attempt to synchronize their clocks with the Dom0. I've since updated my Dom0's to use correct NTP settings, but for reference if you need to break this dependency you can do it with the following command:

echo 1 > /proc/sys/xen/independent_wallclock

To make it permanent you can append that line to the bottom of /etc/rc.d/rc.local.

Wednesday, 26 November 2008

Xmas Come Early

My copy of the Processing book arrived from Waterstone's this morning, so I'm very much looking forward to delving in and exploring further. I've been reading snippets on Safari, and playing around with the Processing environment a little, but I've been holding back a concerted effort until the hardcopy hit my desk. I will start producing some stuff this week and get it posted.

Tuesday, 4 November 2008

Syntax Highlighting Experiment

As this will likely involve posting a fair bit of Java code, it would be nice to have it nicely presented, syntax highlighted and line numbered. I've found a Blogger Widget here for the Google Code SyntaxHighlighter which seems to work OK. All you need to do is put your code between HTML <pre> tags and set the class to Java as follows:

<pre name="mycode" class="java">
...
</pre>

Lets try that out with some sample code:



public class massWriting {

private String test;
private int i;

// test method
public void test(int j) {
System.out.println(i*j);
}

}



Joy!