我一直在互联网上寻找一种快速简单的解析自定义XML文件的方法,这些文件包含数据元素和属性,如下所示:
<book>
<book type="sci-fi">
<book cost="25">
</book>
除此之外,我将在其中包含一个包含这些元素的书类。很简单,我可以创建一个XML:读取书类并将其转换为XML的文件。并且还能够读取XML并转换为新的书类。
所以我发现了这个thing
其中包括以下内容:
Serializer serializer = new Persister();
Example example = new Example("Example message", 123);
File result = new File("example.xml");
serializer.write(example, result);
我可以在Android应用中使用这些功能吗? Serializer和persister?或者它被称为有些不同?
我想你想将一个对象保存到本地文件中。
是的,在android中你可以使用ObjectOutputStream类来编写Object(writeObject方法),并使用ObjectOutputStream来保存到文件中。相应的读取函数类是ObjectInputStream。但是,最重要的是要保存的类对象必须实现Serializable接口
您可以使用Android附带的XML解析器。 Reference
public List parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
parser.nextTag();
return readFeed(parser);
} finally {
in.close();
}
}
这将返回解析器,并返回数据。 InputStream是您读取的流。
此外,这是来自android文档的复制示例,并添加了解释:
private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List entries = new ArrayList();
parser.require(XmlPullParser.START_TAG, ns, "feed");//We read the parser inputted, but we try to find a specific tag. This can be the base tag, or if you have multiple of the same type, get the first.
while (parser.next() != XmlPullParser.END_TAG) {//As long as the parser doesn't detect an end tag
if (parser.getEventType() != XmlPullParser.START_TAG) {//and it isn't a start tag
continue;
}
String name = parser.getName();//we parse the tag found by the reader
//Then there are if-statements to determine what type of tag it is. This example uses a specific type to look for, as this looks for <entry>
if (name.equals("entry")) {
entries.add(readEntry(parser));//If it is that tag, add it to the list of content
} else {
skip(parser);//else skip it
}
}
return entries;
}
此外,这可以应用于创建类:
首先是入门级
public static class Entry {
public final String title;
public final String link;
public final String summary;
private Entry(String title, String summary, String link) {
this.title = title;
this.summary = summary;
this.link = link;
}
}
然后解析:
// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the tag.
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "entry");//finds the children of the tag "entry"
String title = null;
String summary = null;
String link = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
//and using if-statements, we find the different types of tags, and distribute the content to the appropriate strings
String name = parser.getName();
if (name.equals("title")) {
title = readTitle(parser);
} else if (name.equals("summary")) {
summary = readSummary(parser);
} else if (name.equals("link")) {
link = readLink(parser);
} else {
skip(parser);
}
}
//And finally, we create a new entry
return new Entry(title, summary, link);
}
//The following methods are the methods used to parse the different tags.
//They are used as separate methods to make it more clear what goes where,
//instead of pushing all these into the same method
// Processes title tags in the feed.
private String readTitle(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "title");
return title;
}
// Processes link tags in the feed.
private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
String link = "";
parser.require(XmlPullParser.START_TAG, ns, "link");
String tag = parser.getName();
String relType = parser.getAttributeValue(null, "rel");
if (tag.equals("link")) {
if (relType.equals("alternate")){
link = parser.getAttributeValue(null, "href");
parser.nextTag();
}
}
parser.require(XmlPullParser.END_TAG, ns, "link");
return link;
}
// Processes summary tags in the feed.
private String readSummary(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "summary");
String summary = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "summary");
return summary;
}
// For the tags title and summary, extracts their text values.
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
...
}
这可以很容易地修改以满足您的需求:将标记名称更改为您的标记,并将示例类修改为您想要的任何内容。我不确定您是否可以从属性中获取实例的价格,但如果添加子标签,则可能会得到相同的结果。例:
<book>
<type>sci-fi</type>
<cost>
<currency>USD</currency>
<price>25</price>
</cost>
</book>
有了成本,您也可以直接申请25。
或者您可以继续使用属性系统,但是您需要添加一些more code。此外,您当前的XML文件从未关闭标签(<book type="sci-fi">
),您不应该在书签中重复书签。不是因为它气馁,而是因为你最终遇到了困难的情况,试图找出解析器找到的书签。
此外,要编写XML文件,有许多不同的方法。要在本地保存它,您可以使用Serializable更轻松地执行此操作:
public class Something implements Serializable{
...
}
然后使用Object [In / Out] putStream来读或写:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("o.ser")));
//Save the object
oos.writeObject(instance);
// close the writing.
oos.close();
并加载:
ObjectInputStream ois= new ObjectInputStream(new FileInputStream(new File("o.ser")));
instance = (Something) ois.readObject();//or Something instance = (Something)...
ois.close;
但是如果你真的想保存到.xml文件,这里有一种方法:
(这使用内部存储,因此当应用程序将被删除时。外部写入的概念(公共访问区域)是相同的,但是不同的写入方法)
public static String getString(String basetag, List<String> tags/*Raw name, e.g. book*/, List<String> value){
if(basetag == null || basetag.equals("") || basetag.equals(" ")){
throw new IllegalArgumentException("There has to be a base tag.");
}
String retval = "<" + basetag + ">\n";
if(tags == null || value == null){
throw new IllegalArgumentException("There have to be tags and values!");
}
if(tags.size() != value.size()){
throw new IllegalArgumentException("There has to be as many tags as there are values");
}
assert tags.size() != 0;
assert value.size() != 0;
for(int i = 0; i < tags.size(); i++){
String s = "<%s>%s</%s>\n";
retval += String.format(Locale.ENGLISH, s, tags.get(i), value.get(i), tags.get(i));
}
return retval;
}
public static void save(String filename, String data, Context c){
if(data != null && filename != null) {
try {
//Create the file if not exists
File file = new File(c.getFilesDir() + "/", filename);
if (file.getParentFile().mkdirs())
file.createNewFile();
//Access file and write
FileOutputStream fos = c.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
throw new NullPointerException("Filename and/or data is null");
}
}
private static List load(String fn, Context c){
String collected = null;
FileInputStream fis = null;
try{
fis = c.openFileInput(fn);
return parse(fis);
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
fis.close();
} catch(NullPointerException npe){
return null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static List parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
parser.nextTag();
return readFeed(parser);
} finally {
in.close();
}
}
为了这篇文章的结尾,我真的建议你阅读the android documentation on this subject,因为它包含了许多有价值的信息,这些信息可能比这个答案更新(如果答案已经更新了很长时间)