第 30 章 XML

第 30 章 XML

1.IE 中的 XML 2.DOM2 中的 XML

3.跨浏览器处理 XML

随着互联网的发展,Web 应用程序的丰富,开发人员越来越希望能够使用客户端来操作 XML 技术。而 XML 技术一度成为存储和传输结构化数据的标准。所以,本章就详细探讨一下 JavaScript 中使用 XML 的技术。
对于什么是 XML,干什么用的,这里就不在赘述了,在以往的 XHTML 或 PHP 课程都有涉及到,可以理解成一个微型的结构化的数据库,保存一些小型数据用的。

一.IE 中的 XML

在统一的正式规范出来以前,浏览器对于 XML 的解决方案各不相同。DOM2 级提出了动态创建 XML DOM 规范,DOM3 进一步增强了 XML DOM。所以,在不同的浏览器实现 XML 的处理是一件比较麻烦的事情。

1.创建 XMLDOM 对象

IE 浏览器是第一个原生支持 XML 的浏览器,而它是通过 ActiveX 对象实现的。这个对象,只有 IE 有,一般是 IE9 之前采用。微软当年为了开发人员方便的处理 XML,创建了 MSXML 库,但却没有让 Web 开发人员通过浏览器访问相同的对象。

var xmlDom = new ActiveXObject('MSXML2.DOMDocument');
ActiveXObject 类型

XML 版本字符串 说明

Microsoft.XmlDom 最初随同 IE 发布,不建议使用

MSXML2.DOMDocument 脚本处理而更新的版本,仅在特殊情况作为备份用

MSXML2.DOMDocument.3.0 在 JavaScript 中使用,这是最低的建议版本

MSXML2.DOMDocument.4.0 脚本处理时并不可靠,使用这个版本导致安全警告

MSXML2.DOMDocument.5.0 脚本处理时并不可靠,使用这个版本导致安全警告

MSXML2.DOMDocument.6.0 脚本能够可靠处理的最新版本

PS:在这六个版本中微软只推荐三种:

1.MSXML2.DOMDocument.6.0 最可靠最新的版本

2.MSXML2.DOMDocument.3.0 兼容性较好的版本

3.MSXML2.DOMDocument 仅针对 IE5.5 之前的版本

PS:这三个版本在不同的 windows 平台和浏览器下会有不同的支持,那么为了实现兼容,我们应该考虑这样操作:从 6.0->3.0->备用版本这条路线进行实现。

function createXMLDOM() { var version = [
'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i ++) {try {var xmlDom = new ActiveXObject(version[i]);return xmlDom;} catch (e) {//跳过}}throw new Error('您的系统或浏览器不支持 MSXML!');	//循环后抛出错误}
2.载入 XML

如果已经获取了 XMLDOM 对象,那么可以使用 loadXML()和 load()这两个方法可以分别载入 XML 字符串或 XML 文件。

xmlDom.loadXML('<root version="1.0"><user>Lee</user></root>');alert(xmlDom.xml);

PS:loadXML 参数直接就是 XML 字符串,如果想效果更好,可以添加换行符\n。.xml属性可以序列化 XML,获取整个 XML 字符串。

xmlDom.load('test.xml');	//载入一个 XML 文件alert(xmlDom.xml);

当你已经可以加载了 XML,那么你就可以用之前学习的 DOM 来获取 XML 数据,比如标签内的某个文本。

var user = xmlDom.getElementsByTagName('user')[0];	//获取<user>节点alert(user.tagName);	//获取<user>元素标签alert(user.firstChild.nodeValue);	//获取<user>里的值 Lee

DOM 不单单可以获取 XML 节点,也可以创建。

var email= xmlDom.createElement('email');xmlDom.documentElement.appendChild(email);
3.同步及异步

load()方法是用于服务器端载入 XML 的,并且限制在同一台服务器上的 XML 文件。那

么在载入的时候有两种模式:同步和异步。

所谓同步:就是在加载 XML 完成之前,代码不会继续执行,直到完全加载了 XML 再返回。好处就是简单方便、坏处就是如果加载的数据停止响应或延迟太久,浏览器会一直堵塞从而造成假死状态。

xmlDom.async = false;	//设置同步,false,可以用 PHP 测试假死

所谓异步:就是在加载 XML 时,JavaScript 会把任务丢给浏览器内部后台去处理,不会造成堵塞,但要配合

readystatechange 事件使用,所以,通常我们都使用异步方式。
xmlDom.async = true;	//设置异步,默认

通过异步加载,我们发现获取不到 XML 的信息。原因是,它并没有完全加载 XML 就返回了,也就是说,在浏览器内部加载一点,返回一点,加载一点,返回一点。这个时候,我们需要判断是否完全加载,并且可以使用了,再进行获取输出。

XML DOM 中 readystatechange 事件

就绪状态 说明

1 DOM 正在加载

2 DOM 已经加载完数据

3 DOM 已经可以使用,但某些部分还无法访问

4 DOM 已经完全可以

PS:readyState 可以获取就绪状态值

var xmlDom = createXMLDOM();xmlDom.async = true;	//异步,可以不写xmlDom.onreadystatechange = function () {if (xmlDom.readyState == 4) {	//完全加载了,再去获取 XMLalert(xmlDom.xml);}}

xmlDom.load(‘test.xml’); //放在后面重点体现异步的作用

PS:可以通过 readyState 来了解事件的执行次数,将 load()方法放到最后不会因为代码的顺序而导致没有加载。并且 load()方法必须放在 onreadystatechange 之后,才能保证就绪状态变化时调用该事件处理程序,因为要先触发。用 PHP 来测试,在浏览器内部执行时,是否能操作,是否会假死。

PS:不能够使用 this,不能够用 IE 的事件处理函数,原因是 ActiveX 控件为了预防安全性问题。

PS:虽然可以通过 XML DOM 文档加载 XML 文件,但公认的还是 XMLHttpRequest

对象比较好。这方面内容,我们在 Ajax 章节详细了解。

4.解析错误

在加载 XML 时,无论使用 loadXML()或 load()方法,都有可能遇到 XML 格式不正确的情况。为了解决这个问题,微软的 XML DOM 提供了 parseError 属性。

parseError 属性对象

属性 说明

errorCode		发生的错误类型的数字代号filepos		发生错误文件中的位置line		错误行号linepos		遇到错误行号那一行上的字符的位置reason		错误的解释信息
if (xmlDom.parseError == 0) {		
alert(xmlDom.xml);		
} else {		throw new Error('错误行号:' + xmlDom.parseError.line +'\n 错误代号:' + xmlDom.parseError.errorCode +'\n 错误解释:' + xmlDom.parseError.reason);}

二.DOM2 中的 XML

IE 可以实现了对 XML 字符串或 XML 文件的读取,其他浏览器也各自实现了对 XML

处理功能。DOM2 级在 document.implementaion 中引入了 createDocument()方法。IE9、Firefox、Opera、Chrome 和 Safari 都支持这个方法。

1.创建 XMLDOM 对象

var xmlDom = document.implementation.createDocument('','root',null);	//创建 xmlDomvar user = xmlDom.createElement('user');	//创建 user 元素xmlDom.getElementsByTagName('root')[0].appendChild(user);	//添加到 root 下var value = xmlDom.createTextNode('Lee');	//创建文本xmlDom.getElementsByTagName('user')[0].appendChild(value);	//添加到 user 下alert(xmlDom.getElementsByTagName('root')[0].tagName);alert(xmlDom.getElementsByTagName('user')[0].tagName);alert(xmlDom.getElementsByTagName('user')[0].firstChild.nodeValue);

PS:由于 DOM2 中不支持 loadXML()方法,所以,无法简易的直接创建 XML 字符串。所以,只能采用以上的做法。

PS:createDocument()方法需要传递三个参数,命名空间,根标签名和文档声明,由于 JavaScript 管理命名空间比较困难,所以留空即可。文档声明一般根本用不到,直接 null 即可。命名空间和文档声明留空,表示创建 XMLDOM 对象不需要命名空间和文档声明。

PS:命名空间的用途是防止太多的重名而进行的分类,文档类型表明此文档符合哪种规范,而这里创建 XMLDOM 不需要使用这两个参数,所以留空即可。

2.载入 XML

DOM2 只支持 load()方法,载入一个同一台服务器的外部 XML 文件。当然,DOM2 也有 async 属性,来表面同步或异步,默认异步。
//同步情况下

var xmlDom = document.implementation.createDocument('','root',null);xmlDom.async = false;xmlDom.load('test.xml');alert(xmlDom.getElementsByTagName('user')[0].tagName);//异步情况下var xmlDom = document.implementation.createDocument('','root',null);xmlDom.async = true;addEvent(xmlDom, 'load', function () {	//异步直接用 onload 即可alert(this.getElementsByTagName('user')[0].tagName);});xmlDom.load('test.xml');

PS:不管在同步或异步来获取 load()方法只有 Mozilla 的 Firefox 才能支持,只不过新版的 Opera 也是支持的,其他浏览器则不支持。

3.DOMParser 类型

由于 DOM2 没有 loadXML()方法直接解析 XML 字符串,所以提供了 DOMParser 类型来创建 XML DOM 对象。IE9、Safari、Chrome 和 Opera 都支持这个类型。

var xmlParser = new DOMParser();	//创建 DOMParser 对象var xmlStr = '<user>Lee</user></root>';	//XML 字符串var xmlDom = xmlParser.parseFromString(xmlStr, 'text/xml');	//创建 XML DOM 对象

alert(xmlDom.getElementsByTagName(‘user’)[0].tagName); //获取 user 元素标签名

PS:XML DOM 对象是通过 DOMParser 对象中的 parseFromString 方法来创建的,两个

参数:XML 字符串和内容类型 text/xml。

4.XMLSerializer 类型

由于 DOM2 没有序列化 XML 的属性,所以提供了 XMLSerializer 类型来帮助序列化

XML 字符串。IE9、Safari、Chrome 和 Opera 都支持这个类型。var serializer = new XMLSerializer();	//创建 XMLSerializer 对象var xml = serializer.serializeToString(xmlDom);  //序列化 XMLalert(xml);

5.解析错误

在 DOM2 级处理 XML 发生错误时,并没有提供特有的对象来捕获错误,而是直接生成另一个错误的 XML 文档,通过这个文档可以获取错误信息。

var errors = xmlDom.getElementsByTagName('parsererror');if (errors.length > 0) {throw new Error('XML 格式有误:' + errors[0].textContent);}

PS:errors[0].firstChild.nodeValue 也可以使用 errors[0].textContent 来代替。

三.跨浏览器处理 XML

如果要实现跨浏览器就要思考几个个问题:1.load()只有 IE、Firefox、Opera 支持,所以无法跨浏览器;2.获取 XML DOM 对象顺序问题,先判断先进的 DOM2 的,然后再去判断落后的 IE;3.针对不同的 IE 和 DOM2 级要使用不同的序列化。4.针对不同的报错进行不同的报错机制。

//首先,我们需要跨浏览器获取 XML DOM function getXMLDOM(xmlStr) {

var xmlDom = null;if (typeof window.DOMParser != 'undefined') {	//W3CxmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml'); var errors = xmlDom.getElementsByTagName('parsererror');if (errors.length > 0) {throw new Error('XML 解析错误:' + errors[0].firstChild.nodeValue);}} else if (typeof window.ActiveXObject != 'undefined') { //IE var version = [
'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i ++) { try {
xmlDom = new ActiveXObject(version[i]); } catch (e) {
//跳过}}xmlDom.loadXML(xmlStr); if (xmlDom.parseError != 0) {
throw new Error('XML 解析错误:' + xmlDom.parseError.reason);}} else { throw new Error('您所使用的系统或浏览器不支持 XML DOM!');
}return xmlDom;}

//其次,我们还必须跨浏览器序列化

XML function serializeXML(xmlDom) {var xml = '';if (typeof XMLSerializer != 'undefined') {xml = (new XMLSerializer()).serializeToString(xmlDom);} else if (typeof xmlDom.xml != 'undefined') { xml = xmlDom.xml;
} else {throw new Error('无法解析 XML!');}return xml;}

PS:由于兼容性序列化过程有一定的差异,可能返回的结果字符串可能会有一些不同。至于 load()加载 XML 文件则因为只有部分浏览器支持而无法跨浏览器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55265.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云服务器部署k8s需要什么配置?

云服务器部署k8s需要什么配置&#xff1f;云服务器部署K8s需要至少2核CPU、4GB内存、50GBSSD存储的主节点用于管理集群&#xff0c;工作节点建议至少2核CPU、2GB内存、20GBSSD。还需安装Docker&#xff0c;选择兼容的Kubernetes版本&#xff0c;配置网络插件&#xff0c;以及确…

客运自助售票系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;乘客管理&#xff0c;司机管理&#xff0c;车票信息管理&#xff0c;订单信息管理&#xff0c;退票信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;车票信息&#…

JSON的C实现(上)

JSON的C实现&#xff08;上&#xff09; JSON的C实现&#xff08;上&#xff09;前言JSON简介JSON的C实现思路小结 JSON的C实现&#xff08;上&#xff09; 前言 JSON是众多项目中较为常见的数据交换格式&#xff0c;为不同项目、系统间的信息交换提供了一个规范化标准。JSON…

SpringBoot3+Vue3开发后台管理系统脚手架

后台管理系统脚手架 介绍 在快速迭代的软件开发世界里&#xff0c;时间就是生产力&#xff0c;效率决定成败。对于构建复杂而庞大的后台系统而言&#xff0c;一个高效、可定制的后台脚手架&#xff08;Backend Scaffold&#xff09;无疑是开发者的得力助手。 脚手架 后台脚…

从0到1深入浅出构建Nest.Js项目

Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用JavaScript 的渐进增强的能力&#xff0c;使用并完全支持 TypeScript &#xff08;仍然允许开发者使用纯 JavaScript 进行开发&#xff09;&#xff0c;并结合了 OOP &#xff08;面向对…

【Redis】知识点整理(源于javaguide)

一、什么是Redis Redis是一种开源的内存数据库&#xff0c;它支持键值存储&#xff0c;常被用作数据缓存、消息代理和队列等。它以高性能和支持多种数据结构而闻名&#xff0c;如字符串、哈希、列表、集合和有序集合。Redis也支持持久化&#xff0c;可以将数据存储在磁盘上&am…

【Docker】docker的存储

介绍 docker存储主要是涉及到3个方面&#xff1a; 第一个是容器启动时需要的镜像 镜像文件都是基于图层存储驱动来实现的&#xff0c;镜像图层都是只读层&#xff0c; 第二个是&#xff1a; 容器读写层&#xff0c; 容器启动后&#xff0c;docker会基于容器镜像的读层&…

服务器数据恢复—raid磁盘故障导致数据库文件损坏的数据恢复案例

服务器存储数据恢复环境&故障&#xff1a; 存储中有一组由3块SAS硬盘组建的raid。上层win server操作系统层面划分了3个分区&#xff0c;数据库存放在D分区&#xff0c;备份存放在E分区。 RAID中一块硬盘的指示灯亮红色&#xff0c;D分区无法识别&#xff1b;E分区可识别&a…

Python机器学习中的模型评估与优化技术

Python机器学习中的模型评估与优化技术 目录 &#x1f4ca; 模型评估与优化 1.1 交叉验证与模型评估指标 准确率、精确率、召回率、F1-score 1.2 超参数调优 网格搜索与随机搜索使用Scikit-learn的GridSearchCV与RandomizedSearchCV 1. &#x1f4ca; 模型评估与优化 1.1 …

【理论科学与实践技术】数学与经济管理中的学科与实用算法

在现代商业环境中&#xff0c;数学与经济管理的结合为企业提供了强大的决策支持。包含一些主要学科&#xff0c;包括数学基础、经济学模型、管理学及风险管理&#xff0c;相关的实用算法和这些算法在中国及全球知名企业中的实际应用。 一、数学基础 1). 发现人及著名学者 发…

开源项目 - 交通工具检测 yolo v3 物体检测 单车检测 车辆检测 飞机检测 火车检测 船只检测

开源项目 - 交通工具检测 yolo v3 物体检测 单车检测 车辆检测 飞机检测 火车检测 船只检测 开源项目地址&#xff1a;https://gitcode.net/EricLee/yolo_v3 示例&#xff1a;

物理学基础精解【44】

文章目录 球面方程一、球面方程的一般形式二、球面方程的其他形式三、球面方程的性质四、球面方程的应用五、球面方程与其他几何图形的关系 球面方程的几何意义1. 定义球面的形状和大小2. 描述球面的对称性3. 确定球面上点的位置4. 反映球面的曲率性质5. 与其他几何图形的关系6…

前端学习第二天笔记 CSS选择 盒子模型 浮动 定位 CSS3新特性 动画 媒体查询 精灵图雪碧图 字体图标

CSS学习 CSS选择器全局选择器元素选择器类选择器ID选择器合并选择器 选择器的优先级字体属性背景属性文本属性表格属性表格边框折叠边框表格文字对齐表格填充表格颜色 关系选择器后代选择器子代选择器相邻兄弟选择器通用兄弟选择器 CSS盒子模型弹性盒子模型父元素上的属性flex-…

大厂面试真题-说一下Mybatis的缓存

首先看一下原理图 Mybatis提供了两种缓存机制&#xff1a;一级缓存&#xff08;L1 Cache&#xff09;和二级缓存&#xff08;L2 Cache&#xff09;&#xff0c;旨在提高数据库查询的性能&#xff0c;减少数据库的访问次数。注意查询的顺序是先二级缓存&#xff0c;再一级缓存。…

C++入门(有C语言基础)

string类 string类初始化的方式大概有以下几种&#xff1a; string str1;string str2 "hello str2";string str3("hello str3");string str4(5, B);string str5[3] {"Xiaomi", "BYD", "XPeng"};string str6 str5[2];str…

主存储器——随机存取存储器RAM

静态RAM 双稳态触发器 一、工作特性 两种稳定状态&#xff1a; 双稳态触发器具有两个稳定的输出状态&#xff0c;通常表示为 0 和 1&#xff08;或低电平和高电平&#xff09;。这两个状态可以长期保持&#xff0c;即使在没有输入信号的情况下&#xff0c;也不会自发地改变。 例…

【分布式微服务云原生】消息队列全解析:原理、应用场景与主流MQ对比

消息队列全解析&#xff1a;原理、应用场景与主流MQ对比 摘要 在快速发展的软件架构中&#xff0c;消息队列&#xff08;MQ&#xff09;扮演着至关重要的角色。它不仅实现了系统间的异步通信&#xff0c;还提供了应用解耦、流量削峰等关键功能。本文将深入探讨消息队列的工作原…

初识TCP/IP协议

回顾上文 来回顾一下TCP协议的特性&#xff0c;有一道比较经典的题&#xff1a;如何使用UDP实现可靠传输&#xff0c;通过应用程序的代码&#xff0c;完成可靠传输的过程&#xff1f; 原则&#xff0c;TCO有啥就吹啥&#xff0c;引入滑动窗口&#xff0c;引入流量控制&#x…

面试金典题3.2

请设计一个栈&#xff0c;除了常规栈支持的pop与push函数以外&#xff0c;还支持min函数&#xff0c;该函数返回栈元素中的最小值。执行push、pop和min操作的时间复杂度必须为O(1)。 示例&#xff1a; MinStack minStack new MinStack(); minStack.push(-2); minStack.push(…

基于 Qwen2.5-0.5B 微调训练 Ner 命名实体识别任务

一、Qwen2.5 & 数据集 Qwen2.5 是 Qwen 大型语言模型的最新系列&#xff0c;参数范围从 0.5B 到 72B 不等。 对比 Qwen2 最新的 Qwen2.5 进行了以下改进&#xff1a; 知识明显增加&#xff0c;并且大大提高了编码和数学能力。在指令跟随、生成长文本&#xff08;超过 8K…