【读码练习/JSON-java】(二)解析XML的过程
JSON-java还支持XML和JSON的转换。所以学习下XML解析的基本方法。
先回顾XML格式的一些组成
CDATA
这部分由 "<![CDATA[" 开始,由 "]]>" 结束。
Meta
这部分有<!....>组成
Element
<p>This is a paragraph</p>
<br/>
Attribute
<E attr1="value1" attr2 />
Character Entities
& ' > < "
< > & "
XML解析过程
1 public static JSONObject toJSONObject(String string) throws JSONException {
2 JSONObject jo = new JSONObject();
3 XMLTokener x = new XMLTokener(string);
4 while (x.more() && x.skipPast("<")) {
5 parse(x, jo, null);
6 }
7 return jo;
8 }
解析XML其实分成两部分内容:解析和组织解析内容。在这里暂且忽视数据的组织。
XML.toJSONObject的功能是将XML解析,组织成一个JSON。
第二行 : 创建一个JSONOjbect。
即一个XML解析出得数据全部存放于一个JSONObject
第三行 : 创建一个XMLTokener。
它继承JSONTokenr。JSONTokener包装了一个Reader,具有向前探测一个字符,并且能后退的能力。
第四行 : 解析准备:读取到最前面的<号之后的位置。
x.more()判断reader是否结束。 x.skipPast(String to)是将reader读到指定的字符串之后。
解析一个XML的过程,其实是解析多个Elment的过程。而解析一个Element总是从<开始.
第五行 : 解析一个封闭或者不封闭的元素.
<!-- comment --> 非封闭元素
<TAG2/> 封闭元素
<a href=”www.w3c.com“>www.w3c.com</a>元素
1 private static boolean parse(XMLTokener x, JSONObject context,
2 String name) throws JSONException
parse首先会判断处理<之后的Token是一个character还是一个String。
以<+character的情况有:
<!-- comment -->
<!meta>
<![CDATA[ data ]]>
<? ....?>
</Tag> //没有Tagname Tagname不匹配 Tagname之后不是> 会抛出异常
以<+ String的处理。
1、看看有没有属性。(<String k=v k2)
2、看看是不是以/>结尾。(<String k=v k2/>)
3、看看以>结尾的后面什么内容。(<String k=v k2>)
<String>xxxx
如果是一个String就继续往后找
<String>xxxxx<
发现<符号预示有嵌套,所以会开始递归。(见以下代码)
1 } else if (token == LT) {
2 if (parse(x, jsonobject, tagName)) {
3 if (jsonobject.length() == 0) {
4 context.accumulate(tagName, "");
5 } else if (jsonobject.length() == 1 &&
6 jsonobject.opt("content") != null) {
7 context.accumulate(tagName,
8 jsonobject.opt("content"));
9 } else {
10 context.accumulate(tagName, jsonobject);
11 }
12 return false;
13 }
14 }
XMLTokener的方法解释
public String nextCDATA() throws JSONException
从reader解析出CDATA块。判断最后3位是]]>
public Object nextEntity(char ampersand) throws JSONException
从reader里解析转义实体。 & <
public Object nextContent() throws JSONException
从reader里解析outer token。有两个结果:
一是:一个<符号。<font> <a
一是:下一个<符号之前的字符串。<font> 点击" <a
在这里还有一个转义实体的处理
public boolean skipPast(String to) throws JSONException
从reader里读取一个to长度的buff和to进行比较,最后定位到匹配的to之后。
例如:skipPast("<");会定位到?号。
test skip to <? ddfdf ?>
public Object nextToken() throws JSONException
从reader读取下一个token。有三种可能
是一个character。【>/=!?】中的一种。
是一个Quoted String。"String"。
是一个到下列【>/=!?[]】character为止的String。