第 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) {	//完全加载了,再去获取 XML

alert(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);	//创建 xmlDom

var 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);  //序列化 XML

alert(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') {	//W3C

xmlDom = (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.mfbz.cn/a/886214.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在Linux系统安装Nginx

注意&#xff1a;Nginx端口号是80(云服务器要放行) 我的是基于yum源安装 安装yum源(下面这4步就好了) YUM源 1、将源文件备份 cd /etc/yum.repos.d/ && mkdir backup && mv *repo backup/ 2、下载阿里源文件 curl -o /etc/yum.repos.d/CentOS-Base.repo ht…

Adobe PR与AE的区别与联系(附网盘地址)

从事视频后期制作的小伙伴&#xff0c;对于PR&#xff08;Premiere&#xff09;和AE&#xff08;After Effects&#xff09;应该不会陌生。随着短视频的兴起&#xff0c;就连我们普通用户&#xff0c;拍摄完视频&#xff0c;都会去糟取精的剪辑一下&#xff0c;而PR正是一款功能…

【分布式微服务云原生】windows+docker+mysql5.7.44一主一从主从复制

目录 1. 主库设置2. 从库设置3. 验证主从复制内容汇总表格 摘要&#xff1a; 在Windows系统上通过Docker部署MySQL主从复制&#xff0c;以下是详细的步骤和命令&#xff0c;帮助你设置一主一从的MySQL复制环境。 1. 主库设置 步骤1&#xff1a;运行MySQL主库容器 docker run …

探索Python网络世界的利器:Requests-HTML库

文章目录 探索Python网络世界的利器&#xff1a;Requests-HTML库背景&#xff1a;为何选择Requests-HTML&#xff1f;什么是Requests-HTML&#xff1f;如何安装Requests-HTML&#xff1f;5个简单库函数的使用方法3个场景下库的使用示例常见Bug及解决方案总结 探索Python网络世界…

微服务nginx解析部署使用全流程

目录 1、nginx介绍 1、简介 2、反向代理 3、负载均衡 2、安装nginx 1、下载nginx 2、解压nginx安装包 3、安装nginx​编辑 1、执行configure命令 2、执行make命令 4、启动nginx 1、查找nginx位置并启动 2、常用命令 3、反向代理 1、介绍反向代理配置 1、基础配置…

【iOS】计算器的仿写

计算器 文章目录 计算器前言简单的四则运算UI界面事件的逻辑小结 前言 笔者应组内要求&#xff0c;简单实现了一个可以完成简单四则运算的计算器程序。UI界面则是通过最近学习的Masonry库来实现的&#xff0c;而简单的四则运算内容则是通过栈来实现一个简单的四则运算。 简单…

Halcon实用系列1-识别二维条码

在做项目时&#xff0c;之前使用的是某康的智能读码器&#xff0c;综合考虑成本&#xff0c;可通过相机拍照来读取图片的二维码&#xff0c;我这边用Halcon来实现。 Halcon代码如下&#xff1a; *创建模型 create_data_code_2d_model(Data Matrix ECC 200, [], [], DataCodeH…

5G NR物理信道简介

文章目录 NR 上行物理信道PRACHPUCCHPUSCH NR 下行物理信道PBCHPDCCHPDSCH NR 上行物理信道 PRACH PRACH&#xff08;Physical Random Access Channel)物理随机接入信道&#xff0c;用于传导preamble 序列。PRACH 由循环前缀CP、前导序列和保护间隔三部分组成。 PUCCH PUCCH…

【AI大模型】深入Transformer架构:编码器部分的实现与解析(上)

目录 &#x1f354; 编码器介绍 &#x1f354; 掩码张量 2.1 掩码张量介绍 2.2 掩码张量的作用 2.3 生成掩码张量的代码分析 2.4 掩码张量的可视化 2.5 掩码张量总结 &#x1f354; 注意力机制 3.1 注意力计算规则的代码分析 3.2 带有mask的输入参数&#xff1a; 3.…

FOCShield v2.0.4原理图

1.FOCShield v2.0.4原理图,开源原文件用AD制作。用 AD09可以打开。 主要部分为 1.电机驱动芯片部分 2.电流采样部分

Windows 环境下安装 Anaconda 并适配到 PowerShell 的保姆级教程

Anaconda Anaconda 是一个流行的 Python 数据科学和机器学习平台&#xff0c;它包括了 Conda 包管理器、Python 以及数百个用于科学计算的库和工具。Anaconda 旨在简化包和环境管理&#xff0c;使得安装、更新和管理软件包变得容易&#xff0c;同时也能够轻松创建和切换不同的P…

大数据毕业设计选题推荐-民族服饰数据分析系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【Linux】命令管道

一、命名管道的介绍 之前的管道博客中介绍的是匿名管道&#xff0c;这个管道的应用的一个限制就是只能在具有公共祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。 如果我们不想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件来做这项工作&#xff0c;他经常…

输入捕获模式测频率PWMI模式测频率占空比

前沿知识&#xff1a;TIM输入捕获-CSDN博客 输入捕获相关函数 // 初始化输入捕获单元 // ICInit是4个通道共用一个函数的&#xff0c;第二个结构体参数&#xff0c;可以用来配置具体是哪个通道。 void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);/…

【MAUI】CollectionView之 垂直网格

App主页或者导航页面中动态按钮的垂直网格布局 在 XAML 中,CollectionView 可以通过将其 ItemsLayout 属性设置为 VerticalGrid,在垂直网格中显示其项: <CollectionView ItemsSource="{Binding Monkeys}"ItemsLayout

TCP/UDP初识

TCP是面向连接的、可靠的、基于字节流的传输层协议。 面向连接&#xff1a;一定是一对一连接&#xff0c;不能像 UDP 协议可以一个主机同时向多个主机发送消息 可靠的&#xff1a;无论的网络链路中出现了怎样的链路变化&#xff0c;TCP 都可以保证一个报文一定能够到达接收端…

【YOLO学习】YOLOv2详解

文章目录 1. 概述2. Better2.1 Batch Normalization&#xff08;批归一化&#xff09;2.2 High Resolution Classifier&#xff08;高分辨率分类器&#xff09;2.3 Convolutional With Anchor Boxes&#xff08;带有Anchor Boxes的卷积&#xff09;2.4 Dimension Clusters&…

二分查找算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 二分查找算法的介绍 704. 二分查找 34. 在排序数组中查找元素的第一个和 最后一个位置 35. 搜索插入位置 69. x的平…

力扣题解 983

大家好&#xff0c;欢迎来到无限大的判断&#xff0c;祝大家国庆假期愉快 题目描述&#xff08;中等&#xff09; 最低票价 在一个火车旅行很受欢迎的国度&#xff0c;你提前一年计划了一些火车旅行。在接下来的一年里&#xff0c;你要旅行的日子将以一个名为 days 的数组给出…

Charles(青花瓷)抓取https请求

文章目录 前言Charles&#xff08;青花瓷&#xff09;抓取https请求 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&…