安卓解析XML文件
创建模拟数据(XML文件)
- 在main目录下创建assets目录:用来存放XML文件
main目录右键 --> new --> Folder --> assets
- 在assets目录下创建xml文件:
<?xml version="1.0" encoding="UTF-8" ?> //xml声明:版本+编码方式
<XX> //根标签
<YY aa = "???" bb = "???">AA</YY> //子标签 aa/bb为标签属性
<ZZ>BB</ZZ> //子标签 BB为标签的值
</XX>
- 安卓代码中获取assets中的文件
(1).获取到输入流
在Context(Activity……等可以获取到上下文)中
getAssets().open("文件路径") //这里的路径为assets目录下开始的路径
例如:getAssets().open("test/test.xml");
或
getAssets().open("data.xml")
assets目录结构:
|----assets
---------|data.xml
---------|test
--------------|test.xml
(2).获取文件:(适用于WebVeiw控件设置html文件,其他的文件好像读取不到)
file:///android_assets/目录名/文件名
三种常用的解析方法
SAX解析
先看一下解析的具体步骤:
步骤如下:
1. 获得SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
2. 获得SAXParser
SAXparser saxparser = factory.newSAXParser();
3. 传入输入流进行解析
saxparser.parser(getAssets().open("XX/XX.xml"),DefaultHandler);
注意:
上面步骤代码第三步中传入的参数DefaultHandler是需要自己重写的,并且具体的解析就发生在其中。
重写帮助类
import org.xml.sax.helpers.DefaultHandler;
public calss SAXparserHelper extends DefaultHandler{
@Override
public void startDocument (){}
//表示开始读取xml文档
@Override
public void startElement (String uri, String localName,
String qName, Attributes attributes){}
//表示开始读到一个元素标签:参数分别表示:
// uri --> 标签的命名空间,如果没有就返回空。
// localName --> 表示无前缀的本地名称,一般就是我们设置的标签名。
// qName --> 表示有前缀的限定名称,如果没有命名,也是空的。
// attributes --> 包含这个标签所带有的所有属性数组。
// 在使用中,一般通过判断localName是否一直进行属性值的获取
@Override
public void characters (char[] ch, int start, int length){
//对应读取到的标签中的值,设置的值只当作String处理,需要自己转换为其他数据类型,eg:
String values = new String(ch,start,length);
Integer.parserInt(data);//转换为int类型。
// ch --> 字符数组,里面会包含标签的值所对应的数据,
// 但里面的数据并不都是这个标签中的,需要和下面两个数值进行搭配使用。
// start --> 标签值在ch中的开始位置
// length --> 标签值在ch中的长度
}
@Override
public void endElement (String uri, String localName, String qName){}
//这三个参数和startElement中所表示的含义一样,表示结束对某一标签的数据读取完毕。
@Override
public void endDocument (){}
//表示结束XML文档的读取
}
SAX解析:采用事件驱动的方式读取xml文件,触发这5个事件的时候会回调给函数,执行函数中的逻辑,
进行相应的操作。
Dom解析
步骤如下:
1.创建DocumentBuiderFactory
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
2.创建Builder
DocumentBuilder domBuilder = dbFactory.newDocumentBuilder();
3.创建Document
Document dom = domBuilder.parse(inputStream);
Dom解析:解析时传入输入流,会将输入流解析为一个Document对象,这个Document对象包含整个xml的树状结构。
使用Element 和 Node将XML文件中的标签保存在其中,通过根节点获得子节点的方式,遍历整个树状结构。因为包含整个XML文件的信息,所以也比较占用内存。
示例:获取所有同名的元素,并获取该元素的子元素。
test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<XX>
<YY a1 = "mm" a2 = "nn" >
<Z1>M</Z1>
<Z2>N</Z2>
</YY>
<YY a1 = "m1" a2 = "n1" >
<Z1>M1</Z1>
<Z2>N</Z2>
</YY>
<YY a1 = "m2" a2 = "n2" >
<Z1>M2</Z1>
<Z2>N1</Z2>
</YY>
</XX>
保存为Document类之后
<XX>,<YY>,<Z1>,<Z2> --> Element(Node)
a1,a2 --> Attribute
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder domBuilder = dbFactory.newDocumentBuilder();
//获得的dom会包含上面示例xml的所有节点信息
Document dom = domBuilder.parse(inputStream);
//获得所有元素名为YY的元素信息,保存为NodeList:节点列表
NodeList YList = dom.getElementsByTagName("YY");
//遍历YY列表获得每一个YY中带有的数据
for(int i = 0;i < YList.getLength();i++){
Element YY = (Element) YList.item(i);//节点转换为元素
//通过属性名获得元素的属性信息,
YY.getAttribute("a1");
YY.getAttribute("a2");
//YY列表下面还有ZZ数据,遍历每一个Z
NodeList ZList = YY.getChildNodes();
for(int j = 0;j < ZList.getLength();j++){
Node ZNode = ZList.item(j);
if(ZNode.getNodeType() == Node.ELEMENT_NODE){
Element ZElement = (Element)ZNode();
//不同的Z根据Name获取所保存的不同类型数据
swith(ZElement.getName){
case Z1:
//获取N/M的值
String value = ZElement.getFirstChild.getNodeValues();break;
case Z2:
……
}
}
}
}
PULL解析
步骤如下:
1.获得XmlPullParserFactory实例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
2.获得XmlPullParser解析器
XmlPullParser parser = factory.newPullParser();
3.设置数据
parser.setInput(输入流,"编码类型");
代码示例:xml文件格式和上例相同
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
parser.setInput(inputStream,"UTF-8");
int eventType = parser.getEnventType();
while(eventType != XmlPullParser.END_DOCUMENT){
switch(eventType){
//开始读取到XML文档
case XmlPullParser.START_DOCUMENT:
执行逻辑;break;
//读取到标签的时候,进行标签名的判断和值的获得
case XmlPullParser.START_TAG:
if(parser.getName().equals("XX")){
}else if(parser.getName().equals("YY")){
}else if(parser.getName().equals("Z1")){
//需要在读取到Name的时候获取到值,nextTet()
String value = parser.nextText();
}
break;
//读到了值的时候,但是这个时候获取不到标签名,所以没办法进行特定的赋值处理
case XmlPullParser.TEXT:
执行逻辑;break;
//督导某一个标签的</>时候
case XmlPullParser.END_TAG:
执行逻辑;break;
}
}
Pull解析:也是和事件驱动有关,根据不同的事件,处理不同的执行逻辑。
int值 事件名 代表的逻辑
0 START_DOCUMENT 开始读取文档
2 START_TAG 开始读取标签
4 TEXT 子标签中的数据
3 END_TAG 结束标签
1 END_DOCUMENT 结束文档