我正在为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?
提前致谢!
答案 0 :(得分:2)
package documentation for 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,但任何DOM InputSource
都可以。之后是:
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']
。
如果您需要与name1
和name2
进行匹配,请使用此节点测试:[@name1='%s' or @name2='%s']
。在这种情况下,您可能还需要从NodeList
获取evaluate()
来处理多个匹配项:
NodeList c = (NodeList) xpath.evaluate(expr, xml, XPathConstants.NODESET);
答案 1 :(得分: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());
}
}
}