tags:

views:

1031

answers:

7

I have small Strings with XML, like:

String myxml = "<resp><status>good</status><msg>hi</msg></resp>";

which I want to query to get their content.

What would be the simplest way to do this?

+1  A: 

You could try JXPath

willcodejavaforfood
A: 

convert this string into a DOM object and visit the nodes:

Document dom= DocumentBuilderFactory().newDocumentBuilder().parse(new InputSource(new StringReader(myxml)));
Element root= dom.getDocumentElement();
for(Node n=root.getFirstChild();n!=null;n=n.getNextSibling())
 {
 System.err.prinlnt("Current node is:"+n);
 }
Pierre
+11  A: 

XPath in Java 1.5 and above:

String xml = "<resp><status>good</status><msg>hi</msg></resp>";

XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();

InputSource source = new InputSource(new StringReader(
    xml));
String status = xpath.evaluate("/resp/status", source);

System.out.println("satus=" + status);
McDowell
Doesn't look very simple ;-)
Peter Štibraný
Yeah, I agree with Peter, this is hardly the *simplest* way. The good thing here is showing how to do it using pure JDK with no external libs. One a little simpler way: http://stackoverflow.com/questions/807418/simplest-way-to-query-xml-in-java/831595#831595
Jonik
Yep, even simple tasks that use the standard Java XML libraries show all too clearly that the authors have read the GoF book. But, depending on the application, the management of 3rd party libraries can create a host of different complications.
McDowell
That's also true. I personally prefer something easier than the standard libs, yet I'm somewhat frustrated with dom4j too, which prompted me to write this question: http://stackoverflow.com/questions/831865/what-xml-library-for-java-do-you-recommend-to-replace-dom4j. McDowell, I hope you don't mind me using your answers as "pure JDK" examples. :-)
Jonik
Not a problem, Jonik.
McDowell
+1  A: 

After your done with simple ways to query XML in java. Look at XOM.

JavaRocky
+3  A: 

Using a library such as dom4j:

String myxml = "<resp><status>good</status><msg>hi</msg></resp>";

Document document = new SAXReader().read(new StringReader(myxml));
String status = document.valueOf("/resp/msg");

System.out.println("status = " + status);

This does the same as McDowell's solution (sans the typo :).

dom4j has its warts, but I think it makes XML handling in Java easier. (Several other comparable XML libraries exist, see e.g. this question. Edit: Also, for my quest to find the best alternative to dom4j, see: What Java XML library do you recommend (to replace dom4j)?.)

Jonik
+2  A: 

Here is example of how to do that with XOM:

String myxml = "<resp><status>good</status><msg>hi</msg></resp>";

Document document = new Builder().build(myxml, "test.xml");
Nodes nodes = document.query("/resp/status");

System.out.println(nodes.get(0).getValue());

I like XOM more than dom4j for its simplicity and correctness. XOM won't let you create invalid XML even if you want to ;-) (e.g. with illegal characters in character data)

Peter Štibraný
Hmm, nice, this does look simple... But just to make comparison easier, could you perhaps edit it to work exactly like the solutions by McDowell and me? :) I guess you would need to add a line or three.
Jonik
Ok, it's changed now ;-) You're right ... getting string-value of all returned nodes requires some playing with indexes. I don't understand why there is no Nodes.getValue() method to return string-value of all returned nodes. (I also 'cheated' with new Builder().build(...) ;-) but you guys have similar chains in your code too).
Peter Štibraný
Thanks. You're right about the chaining :) But yeah, this still is pretty clean, largely thanks to Builder().build(). Now, if only you could do something like document.valueOf(xpath) in dom4j... +1
Jonik
Hmm, there's a small bug on the 2nd line here: the variable name should be "myxml".
Jonik
Fixed. Thanks! :)
Peter Štibraný
A: 

@The comments of this answer:

You can create a method to make it look simpler

String xml = "<resp><status>good</status><msg>hi</msg></resp>";

System.out.printf("satus= %s\n", getValue("/resp/status", xml ) );

The implementation:

public String getValue( String path, String xml ) { 
    return XPathFactory
               .newInstance()
               .newXPath()
               .evaluate( path , new InputSource(
                                 new StringReader(xml)));

}
OscarRyz
Sure, but also in the simpler solutions (http://stackoverflow.com/questions/807418/simplest-way-to-query-xml-in-java/831623#831623, http://stackoverflow.com/questions/807418/simplest-way-to-query-xml-in-java/831595#831595) you could create helper methods to make them even more simple! (For example, if I was really coding this (at work), I'd use XMLUtils.readFromString(String xml) which retuns Document, instead of that SAXReader stuff I used in my answer.)
Jonik