Android parse Plist file
Asked Answered
H

2

8

Hello Im trying to parse an plist file that contains array of dict's. Im trying to do this using xmlwise. The content of the plistfile is here

So far I only have this in my activity and im getting the content of the plistfile, but how to parse the content into an arraylist?

Map<String, Object> properties = null;
try {
    InputStream inputStream = getResources().openRawResource(R.raw.first_5);
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        properties = Plist.fromXml(sb.toString());
        // TODO do something with the object here
        Log.v("--", properties.values() + " " + properties.size());
        Log.v("--", "OB "+properties.get());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        br.close();
    }
}
Heartsome answered 14/5, 2014 at 8:50 Comment(1)
Take a look into existing lib code.google.com/p/plist/source/checkoutBrazee
C
2

Quick question. What should be the content of the ArrayList? I was wondering if you are mentioning about a list of Object in you Map<String, Object> properties map then why cant you just get the values from the map as

Map<String, Object> properties = new HashMap<String, Object>();
List<Object> plist = new ArrayList<Object>(properties.values());

Apart from that checking your plist the structure is like a Dict root element and a list of Dicts in it. I assume you need to get this as a list. If so consider using Android PList parser by longevitysoft. This is simple and opensource. Its basically a SAXParser parsing Apple PList.

You can then iterate through this array and get approriate object. In your xml its and array of Dict object, so you could do something like this

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import com.longevitysoft.android.xml.plist.PListXMLHandler;
import com.longevitysoft.android.xml.plist.PListXMLParser;
import com.longevitysoft.android.xml.plist.domain.Array;
import com.longevitysoft.android.xml.plist.domain.Dict;
import com.longevitysoft.android.xml.plist.domain.PList;
import com.longevitysoft.android.xml.plist.domain.PListObject;

public class PlistReader {

    public static void main(String[] args) throws Exception {
        PListXMLParser parser = new PListXMLParser();
        PListXMLHandler handler = new PListXMLHandler();
        parser.setHandler(handler);
        parser.parse(readFile("plist.xml"));
        PList pList = ((PListXMLHandler) parser.getHandler()).getPlist();
        Dict root = (Dict) pList.getRootElement();
        // This Array class is java.util.ArrayList<PListObject> underneath the
        // covers
        Array theList = root.getConfigurationArray("Objects");
        for (PListObject obj : theList) {
            switch (obj.getType()) {
                case DICT:
                    Dict dictionaryObj = (Dict) obj;
                    // dictionaryObj.getConfigurationObject(key);
                    // dictionaryObj.getConfigurationInteger(key);
                    // dictionaryObj.getConfiguration(key);
                    // dictionaryObj.getConfigurationArray(key)
                    break;

                case STRING:
                    com.longevitysoft.android.xml.plist.domain.String stringObj = (com.longevitysoft.android.xml.plist.domain.String) obj;
                    break;

                default:
                    break;
            }
        }
    }

    private static String readFile(String path) throws IOException {
        byte[] encoded = Files.readAllBytes(Paths.get(path));
        return new String(encoded);
    }

}

When i tried parsing your xml i got some exception. That was because the PListXMLHandler was checking for localName and not qualifiedName. This could be easily fixed by checking for localName in startElement() and endElement() methods like.

if(isEmpty(localName)){
    localName = qName;
}

Hope this helps.

Crenellate answered 16/5, 2014 at 21:14 Comment(3)
Where do you get the Paths class in this line Paths.get(path)Heartsome
Oh that that is an input stream, now to main issue is how can I create object out of those values? Can u help me with that too?Heartsome
Sorry. Missed this question. Updated the code in answer. You could just iterate through the array of object then cast it to appropriate type and do whatever you want. Basically the types will ARRAY, DATA, DATE, DICT, REAL, INTEGER, STRING, TRUE or FALSE. So each object have appropriate methods to extract value from them.Crenellate
T
0

You can also try Google dd-plist.jar libraries or SAXON parse for parsing plist.

Go through this conversion :

https://code.google.com/p/plist/wiki/Examples http://developer.android.com/reference/javax/xml/parsers/SAXParser.html

You can use dd-plist jar for doing this, Download dd-plist.jar from Google its nice and fast.

I am putting an example working for me from Google code colud. Link is here. http://plist.googlecode.com/svn-history/r61/trunk/src/com/dd/plist/XMLPropertyListParser.java

package com.dd.plist.test;

import com.dd.plist.*;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import junit.framework.TestCase;

public class ParseTest extends TestCase {

    /**
     * Test the xml reader/writer
     */
    public static void testXml() throws Exception {
        System.out.println(new File("test-files/"));

        // parse an example plist file
        NSObject x = PropertyListParser.parse(new File("test-files/test1.plist"));

        // check the data in it
        NSDictionary d = (NSDictionary)x;
        assertTrue(d.count() == 5);
        assertTrue(((NSString)d.objectForKey("keyA")).toString().equals("valueA"));
        assertTrue(((NSString)d.objectForKey("key&B")).toString().equals("value&B"));
        assertTrue(((NSDate)d.objectForKey("date")).getDate().equals(new Date(1322472090000L)));
        assertTrue(Arrays.equals(((NSData)d.objectForKey("data")).bytes(),
                                 new byte[]{0x00,0x00,0x00,0x04,0x10,0x41,0x08,0x20,(byte)0x82}));
        NSArray a = (NSArray)d.objectForKey("array");
        assertTrue(a.count() == 4);
        assertTrue(a.objectAtIndex(0).equals(new NSNumber(true)));
        assertTrue(a.objectAtIndex(1).equals(new NSNumber(false)));
        assertTrue(a.objectAtIndex(2).equals(new NSNumber(87)));
        assertTrue(a.objectAtIndex(3).equals(new NSNumber(3.14159)));

        // read/write it, make sure we get the same thing
        PropertyListParser.saveAsXML(x, new File("test-files/out-testXml.plist"));
        NSObject y = PropertyListParser.parse(new File("test-files/out-testXml.plist"));
        assertTrue(x.equals(y));
    }

    /**
     *  Test the binary reader/writer.
     */
    public static void testBinary() throws Exception {
        NSObject x = PropertyListParser.parse(new File("test-files/test1.plist"));

        // save and load as binary
        PropertyListParser.saveAsBinary(x, new File("test-files/out-testBinary.plist"));
        NSObject y = PropertyListParser.parse(new File("test-files/out-testBinary.plist"));
        assertTrue(x.equals(y));
    }

    /**
     *  NSSet only occurs in binary property lists, so we have to test it separately.
     */
    public static void testSet() throws Exception {
        NSSet s = new NSSet();
        s.addObject(new NSNumber(1));
        s.addObject(new NSNumber(2));
        s.addObject(new NSNumber(3));

        PropertyListParser.saveAsBinary(s, new File("test-files/out-testSet.plist"));
        NSObject t = PropertyListParser.parse(new File("test-files/out-testSet.plist"));
        assertTrue(s.equals(t));
    }

    public static void testASCII() throws Exception {
        NSObject x = PropertyListParser.parse(new File("test-files/test1-ascii.plist"));
        NSDictionary d = (NSDictionary)x;        
        assertTrue(d.count() == 5);        
        assertTrue(((NSString)d.objectForKey("keyA")).toString().equals("valueA"));
        assertTrue(((NSString)d.objectForKey("key&B")).toString().equals("value&B"));
        assertTrue(((NSDate)d.objectForKey("date")).getDate().equals(new Date(1322472090000L)));
        assertTrue(Arrays.equals(((NSData)d.objectForKey("data")).bytes(),
                                 new byte[]{0x00,0x00,0x00,0x04,0x10,0x41,0x08,0x20,(byte)0x82}));
        NSArray a = (NSArray)d.objectForKey("array");
        assertTrue(a.count() == 4);
        assertTrue(a.objectAtIndex(0).equals(new NSNumber(true)));
        assertTrue(a.objectAtIndex(1).equals(new NSNumber(false)));
        assertTrue(a.objectAtIndex(2).equals(new NSNumber(87)));
        assertTrue(a.objectAtIndex(3).equals(new NSNumber(3.14159)));
        NSObject y = PropertyListParser.parse(new File("test-files/test1-ascii-gnustep.plist"));
        assertTrue(x.equals(y));
    }

    public static void testASCIIWriting() throws Exception {
        File in = new File("test-files/test1.plist");
        File out = new File("test-files/out-test1-ascii.plist");
        NSDictionary x = (NSDictionary)PropertyListParser.parse(in);
        PropertyListParser.saveAsASCII(x, out);
        NSDictionary y = (NSDictionary)PropertyListParser.parse(out);
        assertTrue(x.equals(y));
    }

    public static void testGnuStepASCIIWriting() throws Exception {
        File in = new File("test-files/test1.plist");
        File out = new File("test-files/out-test1-ascii-gnustep.plist");
        NSDictionary x = (NSDictionary)PropertyListParser.parse(in);
        PropertyListParser.saveAsGnuStepASCII(x, out);
        NSObject y = PropertyListParser.parse(out);
        assertTrue(x.equals(y));
    }
}
Theatrics answered 23/5, 2014 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.