Android--3种解析XML数据的步骤
采用DOM解析时具体处理步骤是:
1 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例
2 然后利用DocumentBuilderFactory创建DocumentBuilder
3 然后加载XML文档(Document),
4 然后获取文档的根结点(Element),
5 然后获取根结点中所有子节点的列表(NodeList),
6 然后使用再获取子节点列表中的需要读取的结点。
采用SAX解析时具体处理步骤是:
1 创建SAXParserFactory对象
2 根据SAXParserFactorynewSAXParser()方法返回一个SAXParser解析器
3 根据SAXParser解析器获取事件源对象XMLReader
4 实例化一个DefaultHandler对象
5 连接事件源对象XMLReader到事件处理类DefaultHandler中
6 调用XMLReader的parse方法从输入源中获取到的xml数据
7 通过DefaultHandler返回我们需要的数据集合。
采用PULL解析基本处理方式:
1:当导航到XmlPullParserSTART_DOCUMENT,可以不做处理,当然你可以实例化集合对象等等。
2:当导航到XmlPullParserSTART_TAG,则判断是否是river标签,如果是,则实例化river对象,并调用getAttributeValue方法获取标签中属性值。
3:当导航到其他标签,比如Introduction时候,则判断river对象是否为空,如不为空,则取出Introduction中的内容,nextText方法来获取文本节点内容
4:它一定会导航到XmlPullParserEND_TAG的,有开始就要有结束嘛。在这里我们就需要判读是否是river结束标签,如果是,则把river对象存进list集合中了,并设置river对象为null
几种解析技术的比较与总结:
对于Android的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。
1 DOM在处理XML文件时,将XML文件解析成树状结构并放入内存中进行处理。当XML文件较小时,我们可以选DOM,因为它简单、直观。>
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:StreamingAPIforXML(StAX)
ava的sax解析是基于事件的解析:当解析到xml的某个部分的时候,会触发特定事件,可以在自定义的解析类中定义当事件触发时要做得事情。
我们可以继承orgxmlsaxhelpersDefaultHandler类(该类是orgxmlsaxhelpersContentHandler的接口实现类)来覆盖ContentHandler接口的各种方法,这些方法将定义各个事件所触发的程序动作。
package comthomasxmlsax;
import orgxmlsaxAttributes;
import orgxmlsaxLocator;
import orgxmlsaxSAXException;
import orgxmlsaxhelpersDefaultHandler;
public class ThomasSAXHandler extends DefaultHandler {
private StringBuffer xml;//格式化后的XML文件内容
private static int step = 0;//元素层次
public ThomasSAXHandler(){
thisxml = new StringBuffer();
}
public StringBuffer getXml() {
return xml;
}
public void setXml(StringBuffer xml) {
thisxml = xml;
}
/
给字符串添加TAB,使其能格式化输出,在这里第step层元素缩进step个Tab
/
private void appendTab(){
for(int i = 1 ; i<step; i++){
for(int j = 0 ;j<4; j++){
xmlappend(' ');
}
}
}
/
接收元素中字符数据的通知。
@param ch - 字符。
@param start - 字符数组中的开始位置。
@param length - 从字符数组中使用的字符数。
/
public void characters(char[] ch, int start, int length) throws SAXException {
String text = new String(ch,start,length);
text = texttrim();
if(!textequals("")){
step++;
appendTab();
xmlappend(text)append("\r\n");
step--;
}
}
/
接收文档的结尾的通知。
@exception SAXException - 任何 SAX 异常,可能包装另外的异常。
/
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
/
接收元素结束的通知
@param uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
@param localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
@param qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
@exception SAXException - 任何 SAX 异常,可能包装另外的异常。
/
public void endElement(String uri, String localName, String qName) throws SAXException {
appendTab();
xmlappend("</");
if(!uriequals("")){
xmlappend(uri+":");
}
xmlappend(qName)append(">\r\n");
step--;
}
/
结束前缀 URI 范围的映射。
@param prefix - 被映射的前缀。当默认的映射范围结束时,这是一个空字符串。
@exception SAXException - 客户端可能会在处理期间抛出一个异常
/
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
/
接收元素内容中可忽略的空白的通知。
@param ch 来自 XML 文档的字符
@param start 数组中的开始位置
@param length 从数组中读取的字符的个数
@exception SAXException - 任何 SAX 异常,可能包装另外的异常
/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
}
/
接收处理指令的通知。
@param target 处理指令目标
@param data 处理指令数据,如果未提供,则为 null。该数据不包括将其与目标分开的任何空白
/
public void processingInstruction(String target, String data) throws SAXException {
// TODO Auto-generated method stub
}
/
接收用来查找 SAX 文档事件起源的对象
@param locator 可以返回任何 SAX 文档事件位置的对象
/
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
/
接收跳过的实体的通知。将不为标记结构(如元素开始标记或标记声明)内的实体引用调用此方法。(XML 建议书要求报告所跳过的外部实体。SAX 还报告内部实体扩展 / 非扩展,但不包括在标记结构内部。)
@param name - 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头,如果它是外部 DTD 子集,则将是字符串 "[dtd]"
@exception SAXException - 任何 SAX 异常,可能包装另外的异常
/
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
/
接收文档的开始的通知
@exception - SAXException - 任何 SAX 异常,可能包装另外的异常
/
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
/
接收元素开始的通知。
@param uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
@param localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
@param qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
@param attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。
@exception SAXException - 任何 SAX 异常,可能包装另外的异常
/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
step++;//元素层次加一
appendTab();
xmlappend("<");
if(!uriequals("")){
xmlappend(uri+":");
}
xmlappend(qName);
for(int i = 0, size = attributesgetLength(); i<size; i++){
xmlappend(' ')append(attributesgetQName(i))append("=\"")append(attributesgetValue(i))append("\"");
}
xmlappend(">\r\n");
}
/
开始前缀 URI 名称空间范围映射。
@param prefix - 声明的名称空间前缀。对于没有前缀的默认元素名称空间,使用空字符串。
@param uri - 将前缀映射到的名称空间 URI
@exception - SAXException - 客户端可能会在处理期间抛出一个异常
/
public void startPrefixMapping(String prefix, String uri) throws SAXException {
// TODO Auto-generated method stub
}
}
上面是我们自定义的解析器,可以在带有main方法的类中加以测试
package comthomasxmlsax;
import javaxxmlparsersSAXParser;
import javaxxmlparsersSAXParserFactory;
import orgxmlsaxInputSource;
public class Test {
public static void main(String[] args){
try{
SAXParserFactory sf = SAXParserFactorynewInstance();
SAXParser sp = sfnewSAXParser();
ThomasSAXHandler handler = new ThomasSAXHandler();
spparse(new InputSource("filmxml"),handler);
Systemoutprintln(handlergetXml());
}
catch(Exception e){
eprintStackTrace();
}
}
}
下面是filmxml
<xml version="10" encoding="gb2312">
<Kungfu-vips>
<vip>
<name lang="en,ch">Bruce Li</name>
<age>32</age>
<sex>male</sex>
</vip>
<vip>
<name lang="en,ch">Jakie Chen</name>
<age>39</age>
<sex>male</sex>
</vip>
<vip>
<name lang="en,ch">Jet Li</name>
<age>39</age>
<sex>male</sex>
</vip>
</Kungfu-vips>
运行test类,可以看到输出结果:
<Kungfu-vips>
<vip>
<name lang="en,ch">
Bruce Li
</name>
<age>
32
</age>
<sex>
male
</sex>
</vip>
<vip>
<name lang="en,ch">
Jakie Chen
</name>
<age>
39
</age>
<sex>
male
</sex>
</vip>
<vip>
<name lang="en,ch">
Jet Li
</name>
<age>
39
</age>
<sex>
male
</sex>
</vip>
</Kungfu-vips>
这个外部实体声明显然不对,而且,个人觉得这里应使用外部一般实体。
------------------------------------割割更健康-------------------------------------------------------------------
实体(Entity)是包含了文档片断或者说部分文档内容的虚拟存储单元,用来存储XML声明、DTD、各种元素或者其他形式的文本和二进制数据。
实体,在DTD中定义的,一共有4种。
根据定义的位置分----内部/外部
内部实体:完全在文档的DTD中定义的实体
外部实体:存在于一个独立文件中,而在本文档中引用的实体
根据使用的范围分----一般/参数
一般实体:在DTD中定义,可以在XML文档中使用的实体;
参数实体:在外部DTD中定义,且只能在外部DTD中使用的实体。
有一点需注意:参数实体不能在XML文档中使用,并且也不能在内部定义的DTD中使用。
所以这四类就是
内部一般实体------
在DTD中的定义语法:<!ENTITY Entity_Name Entity_content>
在DTD或XML中的引用语法:& Entity_Name;(这个“;”绝对不能丢!)
“<!ENTITY” 定义该句为实体的指令, ENTITY为关键字
“Entity_Name”要定义的实体名称
“Entity_content”定义实体中所包含的具体内容
内部参数实体-----
在DTD中的定义语法:<!ENTITY % Entity_Name Entity_content>
在在本DTD文档中的引用语法: % Entity_Name;
注意:所谓参数实体,就是不能在XML中引用的实体。
外部一般实体-----
在DTD中的定义语法:<!ENTITY Entity_Name SYSTEM “Entity_URL”>
在XML中引用语法:& Entity_Name;(但凡引用,";"都必须有)
"SYSTEM”为定义外部实体的关键字
"Entity_URL”为能够找到该外部实体的URL地址
外部参数实体-----
在DTD中的定义语法:<!ENTITY % Entity_Name SYSTEM “Entity_URL”>
在另一个DTD中的定义语法:% Entity_Name;
(之所以为另一个DTD,就是"外部"的含义所在,不然就和内部参数实体一样了不是)
---------------------------------------割割更清楚------------------------------------------------------------------
所以,根据4类定义,我们应该使用外部一般实体,
Double_L1988同学,你应该在DTD中写的定义为
<!ENTITY %img1 SYSTEM "1jpg" NDATA jpg>
<!ENTITY %img2 SYSTEM "2jpg" NDATA jpg>
<!ENTITY %img3 SYSTEM "3jpg" NDATA jpg>
<!ENTITY %img4 SYSTEM "4jpg" NDATA jpg>
在xml中的引用:
<image source="%img1;"/> 注意:1后面可是有个分号的!!
要想做到“HTML读取照片并显示在表格中”,个人觉得,最好在为XML文档写一个xsl样式单文件。
---------------------------------------最后再割割------------------------------------------------------------------
第一次作答,终于体会到网络的两大初衷:信息交流;资源共享。(。。。虽然不知道有没有帮上忙)感觉很有成就感,我对xml挺感兴趣的,希望以后多多交流,共同进步。
明天考统计,求人品。。。。。。。
以上就是关于android开发从后台获取xml数据怎么解析全部的内容,包括:android开发从后台获取xml数据怎么解析、xml有哪些解析技术区别是什么、求java解析xml文档的sax方法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)