在Java中查询XML的最简单方法

21

我有一些包含XML的小字符串,例如:

String myxml = "<resp><status>good</status><msg>hi</msg></resp>";
我想查询它们的内容,最简单的方法是什么?
9个回答

38

使用Java 1.5及以上版本,无需外部依赖即可使用XPath

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

1
是的,我同意Peter的观点,这绝不是最简单的方法。好的一点是展示了如何使用纯JDK而没有外部库来完成它。还有一种更简单的方法:https://dev59.com/Y3RA5IYBdhLWcg3w1BqW#831595 - Jonik
1
是的,即使是使用标准Java XML库的简单任务也清楚地显示出作者已经阅读了GoF书籍。但是,根据应用程序的不同,管理第三方库可能会带来许多不同的复杂性问题。 - McDowell
这也是真的。我个人更喜欢比标准库更容易的东西,但我对dom4j也有些沮丧,这促使我写下了这个问题:https://dev59.com/eHRA5IYBdhLWcg3wxA9N。 McDowell,希望您不介意我使用您的答案作为“纯JDK”示例。 :-) - Jonik

7

使用dom4j,类似于McDowell的解决方案

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

使用dom4j处理XML会更加简单一些。还有几个其他可比较的XML库存在。替代dom4j的选择在这里讨论


6
这是一个使用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());

我更喜欢XOM而不是dom4j,因为它简单和正确。即使你想要创建无效的XML(例如在字符数据中使用非法字符),XOM也不会让你这样做;-)


嗯,不错,这看起来很简单...但为了更容易地进行比较,你能否编辑它,使其与McDowell和我提供的解决方案完全相同? :) 我想你可能需要添加一行或三行代码。 - Jonik
好的,现在已经改变了;-) 你是对的...获取所有返回节点的字符串值需要一些索引操作。我不明白为什么没有Nodes.getValue()方法来返回所有返回节点的字符串值。(我也“作弊”使用了new Builder().build(...) ;-) 但你们的代码中也有类似的链)。 - Peter Štibraný
谢谢。你说得对,关于链式调用的问题 :) 但是,这仍然非常干净,很大程度上要归功于Builder().build()。现在,如果只能在dom4j中做类似于document.valueOf(xpath)的事情就好了... +1 - Jonik

2

@这个答案的评论:

您可以创建一个方法,使其看起来更简单。

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

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

实现方式:
public String getValue( String path, String xml ) { 
    return XPathFactory
               .newInstance()
               .newXPath()
               .evaluate( path , new InputSource(
                                 new StringReader(xml)));

}

当然,但在更简单的解决方案中(https://dev59.com/Y3RA5IYBdhLWcg3w1BqW#831623,https://dev59.com/Y3RA5IYBdhLWcg3w1BqW#831595),你可以创建辅助方法使它们更加简单!(例如,如果我真的在工作中编写这个代码,我会使用XMLUtils.readFromString(String xml)来返回Document,而不是我在答案中使用的SAXReader。) - Jonik

2
你可以尝试使用JXPath

2

如果你已经掌握了在Java中查询XML的简单方法,请看一下XOM。


1
将此字符串转换为DOM对象并访问节点:
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);
 }

0

这里是一个查询你的 XML 的代码片段,使用 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));
    }
}

0

你可以使用Jerry来查询类似于jQuery的XML。

jerry(myxml).$("status")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接