欢迎来到 jackNEss'窝窝
I like simple mind

浅谈js读取XML文件事宜

2012年01月02日

题外话

这篇文章的产生其实是因为——我不懂。原生js的话我一般就仅限于 ajax 与后台传传参数,json的话,原生的json其实更easy些,就是个js而已。基于JQuery的话,直接查查api,然后按照例子调用即可,完全无视实现过程。正好手头上遇到这么一个需求,本人又不怎么想用Jquery,本以为网上一搜一堆才是,谁知道搜出来的 各种坑爹,要么 和例子结合得太紧了 抽离成通用的修改幅度比较大,要么 代码是贴上去了,考下来 一个粘贴 打开浏览器一个 F5,恭喜,报错(!@#$%^),各种无语,这不是误人子弟吗、亲。最后脑子转过来了,用AJAX的实现方法一试,”data loaded”,当场松了一口气。

下面我就介绍一下不坑爹的 JS 读取 XML 文件的方法。

加载XML文件

读取XML文件分2个工序:加载 and 解释,下面先说说第一个工序:加载。

异步请求

说起异步请求,学习过AJAX的童鞋应该对 XMLHttpRequest() 并不陌生,没错,同样地,加载XML文件也需要这个方法。

XMLHttpRequest()

XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。

//javascript document
xmlhttp = new XMLHttpRequest();

浏览器支持情况的话,嗯 IE7+ 都支持,只有IE6 和他的前辈不给力。IE5.5、IE6 可以用 ActiveObject()来代替。

ActiveObject()

在这里就不作太多扩展了,就是 异步传输中 IE5.5、IE6 使用的对象。

//javascript document
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

结合2种方式,做到全浏览器兼容的写法如下:

//javascript document
var xmlhttp;
try{
	xmlhttp = new XMLHttpRequest();
}
catch(e){
	try{
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	catch(er){
		
	}
}

XMLHttpRequest.open()

下面来介绍下 异步传输中用到的 open() 方法。

//javascript document
var httpRequest = new XMLHttpRequest();
httpRequest.open(type,url,async[, username, password]);
属性 说明
type string 类型。
必选参数。
异步传输的传递方式。
取值为 “GET” 或者 “POST”
url string 类型。
必选参数。
异步传输的传递方式。要求这个 URL 与包含脚本的文本具有相同的主机名和端口。
取值为 “GET” 或者 “POST”
async bool 类型。
必选参数。
参数指示请求使用应该异步地执行。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。
取值为 true 或者 false
username string 类型
可选参数。
为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。
password string 类型
可选参数。
为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。

值得注意的是,open() 方法只是对属性进行设置,请求还没发出的,请求发出要用到 send()方法,并且, url地址 和 发出请求的页面 必须在同一个域之下

XMLHttpRequest.send()

用于发送一个 HTTP 请求。使用传递给 open() 方法的参数,以及传递给该方法的可选请求体。

//javascript document
var httpRequest = new XMLHttpRequest();
httpRequest.send(body);
属性 说明
body 如果通过调用 open() 指定的 HTTP 方法是 POST 或 PUT,body 参数指定了请求体,作为一个字符串或者 Document 对象。如果请求体不适必须的话,这个参数就为 null。对于任何其他方法,这个参数是不可用的,应该为 null(有些实现不允许省略该参数)。

XMLHttpRequest.onreadystatechange

每当 XMLHttpRequest对象状态 XMLHttpRequest.status 发生改变都会触发此事件。

XMLHttpRequest.status

只读属性,表示当前 http请求的状态。下面来介绍下 XMLHttpRequest.status的值对应的意思。

status取值 说明
0 Uninitialized
初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。
1 Open
open() 方法已调用,但是 send() 方法未调用。请求还没有被发送。
2 Sent
Send() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。
3 Receiving
所有响应头部都已经接收到。响应体开始接收但未完成。
4 Loaded
HTTP 响应已经完全接收。

XMLHttpRequest.statusText

由服务器返回的 HTTP 状态代码,如 200 表示成功,而 404 表示 “Not Found” 错误。当 readyState 小于 3 的时候读取这一属性会导致一个异常。

XMLHttpRequest.responseXML

对请求的响应,解析为 XML 并作为 Document 对象返回。

更多的 XMLHttpRequest 对象相关知识可以参考 这里

异步请求函数 xmlLoader()

下面是根据上面说的方法整合出来的 用于读取xml文件的一个方法,其中 callback(data) 中的 data 为 XMLHttpRequest.responseXML 内容

//javascript document
function xmlLoader(url,callback){
	var xmlhttp;
	try{
		xmlhttp = new XMLHttpRequest();
	}
	catch(e){
		try{
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(er){
			return;
		}
	}
	
	xmlhttp.open("GET",url,true);
	xmlhttp.send(null);
	xmlhttp.onreadystatechange = function(){
		if(xmlhttp.readyState == 4){
			if(xmlhttp.status == 200){
				if( typeof callback == "function"){
					callback.call(this,xmlhttp.responseXML)
				}
				//return xmlhttp.responseXML;
			}
		}
	}
	
}

XML文件数据查询

读取完 XML文件,然后就对读取的数据进行解释:数据查询,下面来说说这个解释过程。

获取XML文件的根节点

获取XML文件的节点,我们可以这样写:

//javascript document
//假设 responseXML 为 返回的 XML数据
var root = responseXML.documentElement;

这样我们就可以访问XML的任何节点,对其进行这样那样的操作了。

节点获取

节点获取,经过测试发觉,只支持 getElementsByTagName()方法获取,并不支持 getElementById()。

假设我们要获取所有 <reviewinf>节点,我们可以这样写:

//javascript document
//假设 responseXML 为 返回的 XML数据
var root = responseXML.documentElement;
var reviewinfs = root.getElementsByTagName("reviewinf");

属性提取

属性获取,假设我们要获取 <reviewinf>标签里 source 属性的内容,我们并不能直接用 如 reviewinfs[0].source or reviewinfs[0]["source"] 这样的形式来获取,必须要使用 reviewinfs[0].getAttribute(“source”) 这种形式。

假设我们要获取 reviewinfs集合 第一个子集 的 source属性,我们可以这样写:

//javascript document
//假设 responseXML 为 返回的 XML数据
var root = responseXML.documentElement;
var reviewinfs = root.getElementsByTagName("reviewinf");

var reviewinfs00_source = reviewinfs[0].getAttribute("source");

整合上面几个我做个简易的属性查询方法:

xml属性查询xmlDataSearch()

//javascript document
function xmlDataSearch(responseXML,tagName,attribute,value){
	var root = responseXML.documentElement;
	tagName == null? tagName = "*":"";
	var tags = root.getElementsByTagName(tagName);
	var tags_len = tags.length;
	for( var i = 0; i < tags_len; i++ ){
		if(tags[i].getAttribute(attribute) == value){
			return tags[i];
		}
	}
	return false;
}

下面是函数属性的简单介绍:

属性 说明
responseXML 返回的 XMLHttpRequest.responseXML 对象
tagName 要查找的 标签名字
attribute 筛选条件中的 属性名
value 筛选条件中的 属性 的值

当然 上面这个筛选只能匹配单个,而且功能考虑得比较浅显,只适合 简单的XML文件数据读取,复杂的…嘛方法一样,具体问题具体分析吧,这里就不多介绍了。

XML文件

在做这个XML读取功能的时候遇到,“啊,明明是正确的 为什么读取不了数据呢?”,通过排错法得知原理是 flash部门的童鞋们的 XML文件写得不标准导致的,所以在这里也稍微介绍下 XML格式的写法与注意的几个细节。

基本格式

XML文件通常的抬头是这样写的:

<!--xml document -->
<?xml version="1.0" encoding="utf-8"?>

标签 tag 要注意的几个细节

然后 下面的自定义标签,可以有2种形式, 自闭合 and 一般,即

<!--xml document -->
<previewinf></previewinf>

<previewinf />	

以上这2种写法都是允许的。

值得注意的是 自定义标签 必须 全部都是小写,不能出现 骆驼式写法

例如:

<previewInf />		

这样的写法在我们异步加载XML的时候会不被识别导致报错。

属性 Attribute

属性的话 基本上 小写and 骆驼式都是可识别的,只要符合我们命名规则的一般规律即可。

参考例子

假设我们有这样的一个 XML文件 要进行异步读取:

<?xml version="1.0" encoding="utf-8"?>
<data>
	<reviewinf id="1" source="hello jackness01"></reviewinf>
	<reviewinf id="2" source="hello jackness02"></reviewinf>
	<reviewinf id="3" source="hello jackness03"></reviewinf>
	<reviewinf id="4" source="hello jackness04"></reviewinf>
	<reviewinf id="5" source="hello jackness05"></reviewinf>
	<reviewinf id="6" source="hello jackness06"></reviewinf>
	<reviewinf id="7" source="hello jackness07"></reviewinf>
	<reviewinf id="8" source="hello jackness08"></reviewinf>
	<reviewinf id="9" source="hello jackness09"></reviewinf>
	<reviewinf id="10" source="hello jackness10"></reviewinf>
</data>	

现在需求是 读取 id为1 中的 source属性的信息,我们 js方面可以运用以上所说的2个方法来进行实现,即:

//javascript document	
xmlLoader("datasource.xml",function(data){
	
	var targetSource = xmlDataSearch(data,"reviewinf","id","3");
	alert(targetSource.getAttribute("source"));
	
});	

参考例子:http://www.jackness.org/lab/xml_loader/demo.html

分类javascript
阅读 1,815
  • 评论加载中...

标签云

分类目录

最新留言

  • 评论加载中...

与我联系

如有疑问or建议可通过以下方式跟我取得联系.

Q Q:373435871
Email:jackness1208@gmail.com
© Copyright 2011 - 2014 jackNEss.org All Rights Reserved 粤ICP备14065612号
首页 | 关于我 | 网站地图 | RSS