21

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?

9 Answers9

38

XPath using Java 1.5 and above, without external dependencies:

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);
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
McDowell
  • 107,573
  • 31
  • 204
  • 267
  • 1
    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 May 06 '09 at 20:47
  • 1
    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 May 06 '09 at 21:15
  • 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 May 06 '09 at 21:52
7

Using dom4j, similar to McDowell's solution:

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);

XML handling is a bit simpler using dom4j. And several other comparable XML libraries exist. Alternatives to dom4j are discussed here.

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Jonik
  • 80,077
  • 70
  • 264
  • 372
6

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ý
  • 32,463
  • 16
  • 90
  • 116
  • 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 May 06 '09 at 20:50
  • 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ý May 06 '09 at 20:59
  • 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 May 06 '09 at 21:55
2

You could try JXPath

willcodejavaforfood
  • 43,223
  • 17
  • 81
  • 111
2

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

JavaRocky
  • 19,203
  • 31
  • 89
  • 110
2

@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)));

}
Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 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 May 06 '09 at 22:08
1

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
  • 34,472
  • 31
  • 113
  • 192
0

Here is a code snippet of querying your XML with VTD-XML

import com.ximpleware.*;
public class simpleQuery {

    public static void main(String[] s) throws Exception{
        String myXML="<resp><status>good</status><msg>hi</msg></resp>";
        VTDGen vg = new VTDGen();
        vg.setDoc(myXML.getBytes());
        vg.parse(false);
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/resp/status");
        int i = ap.evalXPath();
        if (i!=-1)
            System.out.println(" result ==>"+vn.toString(i));
    }
}
vtd-xml-author
  • 3,319
  • 4
  • 22
  • 30
0

You can use Jerry to query XML similar to jQuery.

jerry(myxml).$("status")
deamon
  • 89,107
  • 111
  • 320
  • 448