我可以使用“Serializer”吗?

问题描述 投票:1回答:2

我一直在互联网上寻找一种快速简单的解析自定义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 parsing xml-serialization persistence
2个回答
1
投票

我想你想将一个对象保存到本地文件中。

是的,在android中你可以使用ObjectOutputStream类来编写Object(writeObject方法),并使用ObjectOutputStream来保存到文件中。相应的读取函数类是ObjectInputStream。但是,最重要的是要保存的类对象必须实现Serializable接口


1
投票

您可以使用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,因为它包含了许多有价值的信息,这些信息可能比这个答案更新(如果答案已经更新了很长时间)

© www.soinside.com 2019 - 2024. All rights reserved.