PULL解析XML的运行机制详解


PULL解析简单易上手,基本上看一遍,基本上就会解析啦,但总是感觉对PULL解析的运行机制不是很了解,就总结了以下事件驱动到底是怎么执行的。

PULL: Android内置了PULL解析器。PULL解析器与SAX解析器类似,它提供了类似的事件,例如,开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发事件。每一种事件将作为数值代码被传送,因此使用一个switch来对感兴趣的事件进行处理。

这也是我最喜欢的方法,简单好用。

下面将对解析过程进行详细介绍,它到底是怎么运行的呢。

这是XML Pull Parsing官网:http://www.xmlpull.org/ 里边有详细的解析。

一、XmlPullParser 常见事件:

START_DOCUMENT: 文档开始

START_TAG : 标签开始

TEXT : 文本

END_DOCUMENT:文档结束

END_TAG:标签结束

CDSECT :CDATA sections was just read (this token is available only from nextToken())

在标记CDATA下,所有的标记、实体引用都被忽略,而被XML处理程序一视同仁地当做字符 数据看待,CDATA的形式如下:

<![CDATA[文本内容]]>
CDATA的文本内容中不能出现字符串“]]>”

另外,CDATA不能嵌套。
COMMENT :注释
DOCDECL: 就是

<DOCTYPE

IGNORABLE_WHITESPACE :可忽略的空白。在没用dtd约束文档时, IGNORABLE_WHITESPACE只会出现在根元素外面;对于有dtd约束的文档,空白由dtd约束文档定义。(dtd约束文档就是在DOCTYPE中指定的那个文件,它规定了可以在xml出现什么标签、以及标签可以出现在哪等)
。。。。
常有的标签就5个:START_DOCUMENT ,START_TAG, TEXT, END_DOCUMENT , END_TAG。

二、一些比较重要复杂的常见方法:结合源代码解析

1) int nextTag():

Call next() and return event if it is START_TAG or END_TAG otherwise throw an exception. It will skip whitespace TEXT before actual tag if any.
//调用next()返回START_TAG or END_TAG这两个事件,其他抛出异常。它会跳过空白text
本质执行过程就是这样:

int eventType = next();
if(eventType == TEXT && isWhitespace()) { // skip whitespace
eventType = next();
}
if (eventType != START_TAG && eventType != END_TAG) {
throw new XmlPullParserException(“expected start or end tag”, this, null);
}
return eventType;

2) String nextText():

If current event is START_TAG then if next element is TEXT then element content is returned or if next event is END_TAG then empty string is returned, otherwise exception is thrown. After calling this function successfully parser will be positioned on END_TAG.
//当前事件是START_TAG,下一元素是text就返回它的内容,或下一个事件是END_TAG那么返回空字符串“”,其他抛出异常。调用完这个函数事件定位在END_TAG。
The motivation for this function is to allow to parse consistently both empty elements and elements that has non empty content, for example for input:

<tag>foo</tag>. <tag></tag> (which is equivalent to both input can be parsed with the same code:

3. p.nextTag()
4. p.requireEvent(p.START_TAG, “”, “tag”);
5. String content = p.nextText();
6. p.requireEvent(p.END_TAG, “”, “tag”);

This function together with nextTag make it very easy to parse XML that has no mixed content.
本质执行过程就是这样:

 

if(getEventType() != START_TAG) {
throw new XmlPullParserException(
“parser must be on START_TAG to read next text”, this, null);
}
int eventType = next();
if(eventType == TEXT) {
String result = getText();
eventType = next();
if(eventType != END_TAG) {
throw new XmlPullParserException(
“event TEXT it must be immediately followed by END_TAG”, this, null);
}
return result;
} else if(eventType == END_TAG) {
return “”;
} else {
throw new XmlPullParserException(
“parser must be on START_TAG or TEXT to read text”, this, null);
}

 

3)int nextToken():

This method works similarly to next() but will expose additional event types (COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or IGNORABLE_WHITESPACE) if they are available in input.
//这个方法和next()相似,但是会揭露其他事件类型,例如:COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or IGNORABLE_WHITESPACE。如果它们在输入中。
即它可以返回所有的事件类型:空白,注释,CDSECT。。等等
注释太多,而且不常用,想研究的自己看源代码吧。

4)public int next()

//返回下一个解析事件
Get next parsing event - element content wil be coalesced and only one TEXT event must be returned for whole element content (comments and processing instructions will be ignored and emtity references must be expanded or exception mus be thrown if entity reerence can not be exapnded). If element content is empty (content is “”) then no TEXT event will be reported.
**另:next()与nextToken()的区别:
next:主要是用于返回比较高层的事件的。其中包括:START_TAG, TEXT, END_TAG, END_DOCUMENT
nextToken():返回所有事件。
While next() provides access to high level parsing events, nextToken() allows access to lower level tokens.

5) void require(int type,String namespace,String name)

Test if the current event is of the given type and if the
namespace and name do match. null will match any namespace and any name. If the current event is TEXT with isWhitespace()= true, and the required type is not TEXT, next () is called prior to the test.
//测试当前事件是给定事件类型。Namespace,name是null表示任意匹配。
如果当前事件是Text且为空,required type不是text,那么就会调用next()

if (getEventType() == TEXT && type != TEXT && isWhitespace ())
next ();

if (type != getEventType()
|| (namespace != null && !namespace.equals (getNamespace ()))
|| (name != null && !name.equals (getName ()))
throw new XmlPullParserException ( “expected “+ TYPES[ type ]+getPositionDesctiption());

更多详情见请继续阅读下一页的精彩内容

  • 1
  • 2
  • 下一页

相关内容