0

我正在为 android 制作一个应用程序,并且正在从在线的 xml 文件中提取和解析标记属性的值。假设 xml 文件看起来像这样。

<a>
<b>
<c id="00001" time="1:00" day="Friday" name1="John" name2="Mary"></c>
<c id="00002" time="2:00" day="Monday" name1="Ed" name2="Kate"></c>
<c id="00003" time="3:00" day="Sunday" name1="Mary" name2="Ed"></c>
<c id="00004" time="4:00" day="Friday" name1="Kate" name2="John"></c>
</b>
</a>

该应用程序将为其设置一个名称(例如 John、Ed、Mary、Kate),我想提取名称出现在哪一行以及名称在哪个属性中的标签属性的值(例如 name1 , name2),名称将保持不变,但它会根据周改变行和属性。

我搜索了答案,发现我很可能会使用 XPath。谁能帮我解决这个问题?我的解析方法对使用 xpath 有影响吗?DOM 还是 SAX?

提前致谢!

4

2 回答 2

2

包文档javax.xml.xpath给出了很好的介绍,但这里也有一些示例代码:

InputSource xml = new InputSource(new StringReader("<a>\n" + 
    "<b>\n" + 
    "<c id=\"00001\" time=\"1:00\" day=\"Friday\" name1=\"John\" name2=\"Mary\"></c>\n" + 
    "<c id=\"00002\" time=\"2:00\" day=\"Monday\" name1=\"Ed\" name2=\"Kate\"></c>\n" + 
    "<c id=\"00003\" time=\"3:00\" day=\"Sunday\" name1=\"Mary\" name2=\"Ed\"></c>\n" + 
    "<c id=\"00004\" time=\"4:00\" day=\"Friday\" name1=\"Kate\" name2=\"John\"></c>\n" + 
    "</b>\n" + 
    "</a>"));

所以没有 SAX,但任何 DOMInputSource都可以。之后是:

String name = "John";

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

// the String.format is just here so you can see the XPath expression more
// clearly without all the ".."+x+".." string concat, feel free to replace
String expr = String.format("//a/b/c[@name1='%s']", name);
Node c = (Node) xpath.evaluate(expr, xml, XPathConstants.NODE);

NamedNodeMap attribs = c.getAttributes();
String id = attribs.getNamedItem("id").getNodeValue();
String time = attribs.getNamedItem("time").getNodeValue();
// etc.

如果元素名称c在整个文档中是唯一的,则可以将 XPath 表达式缩减为//c[@name1='%s'].

如果您需要同时匹配两者name1name2使用此节点测试:[@name1='%s' or @name2='%s']. 在这种情况下,您可能还需要获取NodeListfromevaluate()来处理多个匹配项:

NodeList c = (NodeList) xpath.evaluate(expr, xml, XPathConstants.NODESET);
于 2011-09-19T21:25:34.733 回答
0

上面的答案,关于 xpath 可能是最好的方法。但是,如果您想从 xml 图实际创建 POJO,您可以使用 XStream 之类的东西反序列化 xml,或者在更复杂的 xml 结构中,您可以使用 Trang 从 xml 创建模式,然后使用 jaxb 创建 java 类xjc 工具。

使用您的示例,我编写了一个小程序,展示了如何使用 XStream 进行操作:您可以在此处获取 XStream 的二进制或源代码分发:http: //x-stream.github.io/download.html

网站上有一些简单的示例,他们说它适用于 Android。

这是我的代码:

package misc;

import java.io.Reader;
import java.io.StringReader;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

public class ProcessMyXml {
@XStreamAlias("c")
public static class c{
    //<c id="00001" time="1:00" day="Friday" name1="John" name2="Mary"></c>
    @XStreamAsAttribute
    String time;
    @XStreamAsAttribute
    String day;
    @XStreamAsAttribute
    String name1;
    @XStreamAsAttribute
    String name2;
    @Override
    public String toString() {
        return time+","+day+","+name1+","+name2;
    }

}

public static class bClass{
    @XStreamImplicit
    List<c> cList;
}
@XStreamAlias("a")
public static class a{
    bClass b;
}

public static void main(String[] args) {
    XStream xs = new XStream();
    xs.processAnnotations(a.class);
    Reader reader = new StringReader("<a>\n" + 
            "<b>\n" + 
            "<c id=\"00001\" time=\"1:00\" day=\"Friday\" name1=\"John\" name2=\"Mary\"></c>\n" + 
            "<c id=\"00002\" time=\"2:00\" day=\"Monday\" name1=\"Ed\" name2=\"Kate\"></c>\n" + 
            "<c id=\"00003\" time=\"3:00\" day=\"Sunday\" name1=\"Mary\" name2=\"Ed\"></c>\n" + 
            "<c id=\"00004\" time=\"4:00\" day=\"Friday\" name1=\"Kate\" name2=\"John\"></c>\n" + 
            "</b>\n" + 
            "</a>");

    a aFromFile = (a)xs.fromXML(reader);
    List<c> cList = aFromFile.b.cList;
    for(c current_c:cList){
        System.out.println(current_c.toString());
    }
}

}

于 2011-09-20T00:29:03.687 回答