xml文件的解析有三种方式:
- DOM(document object model :文档对象模型):借助文档树模型对 xml 文档进行分析
- SAX(simple API for xml :xml 的简单 api):利用事件流的形式解析 XML
- PULL:利用事件流模型来解析 XML
备注:DOM 和 SAX 解析的优劣分析:DOM 是将文档一次性读入到内存,然后以文档树模进行分析节点信息。获取到希望获取的数据;而 SAX 是事件流的形式去分析 xml 文件。 DOM 可以做到对文档中部分节点的修改、删除和新增,而 SAX 无法做到。
以下使用XmlPullParser来进行解析。
1.XMl解析,一般用在哪些地方,怎么样去读取
xml可以用在内容判断的时候,比如多种显示
例如a客户需要123
b客户只需要23
xml的读取方式:
1.获取当前的xml
2.对当前的xml以文档的形式进行遍历
2.Xml读取时的几种方法
想要读取xml需要使用XmlPullParser
- 1.通过工厂类XmlPullParserFactory来创建
XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
- 2.通过android提供的实用工具类android.util.xml
XmlPullParser xmlPullParser = Xml.newPullParser();
- 3.通过XmlResourceParser来(XmlResourceParser继承
XmlPullParser)
XmlResourceParser xmlPullParser = getResources().getXml(R.xml.file_paths);
这里需要注意的是XmlResourceParser构建的xmlPullParser不再需要额外设置解码类型和xml。
可以直接获取。
3.Xml存放的位置
1. 存放在res/xml下的读取
存放在res下,存放的目录不同读取的情况也不同。
- 在res/raw目录
XmlPullParser xmlPullParser = Xml.newPullParser();
int configId = getResources().getIdentifier("xml_source", "raw", getPackageName());
InputStream inputStream = getResources().openRawResource(configId);
xmlPullParser.setInput(inputStream, "utf-8");
- 在res/xml目录
XmlResourceParser xmlPullParser = getResources().getXml(R.xml.xml_source);
XmlResourceParser在得到xml内容后不需要再设置解码方式。
XmlResourceParser是继承了XmlPullParser的
2. 存放在Asset下的读取
XmlPullParser xmlPullParser = Xml.newPullParser();
InputStream inputStream = getResources().getAssets().open("xml_source.xml");
xmlPullParser.setInput(inputStream, "utf-8");
3. 存放在本地下的读取
一般情况在本地的xml读取会判断一下xml是否存在。
private static InputStream getFilePublicInputStream(Context context, String fileName) {
String filePath = "atv/etc/" + fileName + ".xml";
Log.d(TAG, "PackageName = " + context.getPackageName() + " filename = " + fileName + " filePath = " + filePath);
if (new File(filePath).exists()) {
Log.d(TAG, filePath + " is exsited");
try {
FileInputStream inputStream = new FileInputStream(filePath);
return inputStream;
} catch (FileNotFoundException e) {
Log.e(TAG, "file not founded");
}
}
int configId = context.getResources().getIdentifier(fileName, "raw", context.getPackageName());
Log.d(TAG, filePath + " is not found,parse xml from app, configId= " + configId);
return context.getResources().openRawResource(configId);
}
XmlPullParser xmlPullParser = Xml.newPullParser();
InputStream inputStream = getFilePublicInputStream(context, fileName);
xmlPullParser.setInput(inputStream, "utf-8");
4.实际例子
下面以存放在raw目录下,使用XmlPullParserFactory来进行读取的方法
首先是xml
<?xml version="1.0" encoding="utf-8"?>
<keys>
<board id="xml1">
<source>android 01</source>
<source>android 02</source>
<source>android 03</source>
</board>
<board id="xml2">
<source>ios 01</source>
<source>ios 02</source>
<source>ios 05</source>
</board>
</keys>
try {
XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
int configId = getResources().getIdentifier("xml_source", "raw", getPackageName());
InputStream inputStream = getResources().openRawResource(configId);
xmlPullParser.setInput(inputStream, "utf-8");
int eventType = xmlPullParser.getEventType();
String board = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String keys = xmlPullParser.getName();
if (keys.equals("board")) {
board = xmlPullParser.getAttributeValue(null, "id");
}
if (board.equals("xml1")) {
if (keys.equals("source")) {
String result = xmlPullParser.nextText();
Log.d(TAG, "initData: result = " + result);
}
}
Log.d(TAG, "initData: keys = " + keys);
break;
case XmlPullParser.END_TAG:
Log.d(TAG, "initData: end");
break;
}
eventType = xmlPullParser.next();
}
inputStream.close();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
知识点补充:
<?xml version="1.0" encoding="utf-8"?>
<keys> //开始标签,对应START_TAG字段,标签名通过getName()读取
<board id="xml1">
//属性名 也就是id(不是id里面的内容)
//通过getAttributeName (int index)读取
//属性值 通过getAttributeValue(int index)或者getAttributeValue(String namespace, String name);读取
//一般namespace可以填null
<source>android 01</source> //内容通过getText()获取
<source>android 02</source>
<source>android 03</source>
</board>
<board id="xml2">
<source>ios 01</source>
<source>ios 02</source>
<source>ios 05</source>
</board>
</keys> 结束标签,对应END_TAG
int START_DOCUMENT = 0; 开始解析文档
int END_DOCUMENT = 1; 内容结束
int START_TAG = 2; 读取标签
int END_TAG = 3; 标签读取结束
int TEXT = 4; 读取文本
5.总结
- XmlPullParser的使用需要注意设置解码,不同的路径需要使用不同的读取方法,比如使用raw读取方式去读取xml的内容会报错。
- XmlPullParser读取本地的xml的时候需要注意文件是否存在的问题
- XmlPullParser的getAttributeValue(int index)避免空值,还有越界的情况
可以给作者评论,关注加喜欢吗?
如果还存在不懂的地方可以联系一下作者,我会帮忙解答!