After some google hacking (and reading Building Oracle XML Applications, which I thought was way out of date, my first edition of Java and XML was useless) I found this kind of stuff:
XPath
To use XPath you need an XMLDocument object:
DOMParser p = new DOMParser();
p.parse(new StringReader(xml));
Document doc = p.getDocument();
XMLDocument xmldoc = (XMLDocument)doc ;
NodeList nl = xmldoc.selectNodes(xPath) ;
Now we have a loverly list of nodes, and off we go. Note that this suffers from the usual Java nonsense of returning a null if there’s nothing there.
Getting a String version of a DOM Document
toString()
Hmmm – just gives the object ID. How useful is that? Not very.
I noticed that the XMLDocument class has a print method that you can pass an OutputStream to. OK, I think, pass it a StringWriter?
StringWriter sw = new StringWriter() ;
xmldoc.print(sw);
System.out.println(sw.toString());
This compilies but throws a Null Pointer Exception. Must be the interfaces matching but not doing what they’re supposed to. I dig around in the class documentation and find that I can pass a PrintWriter – this works:
StringWriter sw = new StringWriter() ;
PrintWriter pw = new PrintWriter(sw );
xmldoc.print(pw);
System.out.println(sw.toString());
No idea why, haven’t got time to mess around finding out. It works. I think this is superior to a solution I saw where people were calling the serialize method on some weird class or writing your own code that dumps out the contents of a node and passing the root node to it (there are lots of examples on the Web if you look around). Note that this doesn’t work with fragments, at least it doesn’t seem to, have a play with it.
Coming up Fun with XPath: Combining many fields in a query. (when you aren’t trying to write some XSL).