Android解析Plist文件
Posted
技术标签:
【中文标题】Android解析Plist文件【英文标题】:Android parse Plist file 【发布时间】:2014-07-02 05:23:07 【问题描述】:您好,我正在尝试解析包含 dict 数组的 plist 文件。我试图使用xmlwise 来做到这一点。 plistfile的内容是here
到目前为止,我的活动中只有这个,并且我正在获取 plistfile 的内容,但是如何将内容解析为 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();
【问题讨论】:
查看现有库code.google.com/p/plist/source/checkout 谢谢,我去看看 【参考方案1】:快速提问。 ArrayList 的内容应该是什么?我想知道您是否在Map<String, Object> properties
地图中提到了Object
列表,那么为什么您不能从地图中获取值作为
Map<String, Object> properties = new HashMap<String, Object>();
List<Object> plist = new ArrayList<Object>(properties.values());
除了检查您的 plist 之外,该结构就像一个字典根元素和其中的字典列表。我假设您需要将此作为列表。如果是这样,请考虑使用 longevitysoft 的android PList parser。这是简单且开源的。它基本上是一个 SAXParser 解析 Apple PList。
然后您可以遍历这个数组并获得合适的对象。在你的 xml 它和字典对象数组中,所以你可以做这样的事情
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);
当我尝试解析您的 xml 时,我遇到了一些异常。那是因为 PListXMLHandler 正在检查 localName 而不是qualifiedName。这可以通过检查 startElement() 和 endElement() 方法中的 localName 来轻松解决。
if(isEmpty(localName))
localName = qName;
希望这会有所帮助。
【讨论】:
这一行的Paths类在哪里得到Paths.get(path)
哦,那是一个输入流,现在主要问题是如何从这些值中创建对象?你也可以帮我吗?
对不起。错过了这个问题。更新了答案中的代码。您可以只遍历对象数组,然后将其转换为适当的类型并做任何您想做的事情。基本上,这些类型将是 ARRAY、DATA、DATE、DICT、REAL、INTEGER、STRING、TRUE 或 FALSE。所以每个对象都有适当的方法来从中提取价值。【参考方案2】:
您也可以尝试使用 Google dd-plist.jar
库或 SAXON parse 来解析 plist。
完成这个转换:
https://code.google.com/p/plist/wiki/Examples http://developer.android.com/reference/javax/xml/parsers/SAXParser.html
您可以使用 dd-plist jar 来执行此操作,从 Google 下载 dd-plist.jar 又快又好。
我从 Google 代码列中举了一个对我有用的示例。 链接在这里。 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));
【讨论】:
以上是关于Android解析Plist文件的主要内容,如果未能解决你的问题,请参考以下文章
Android 上的 Apache Commons Configuration Plist 解析器 - 没有可用的验证 SAXParser 实现