javascript和XML
一,浏览器对XML DOM的支持
1,DOM2级核心
var xmldom = document.implementation.createDocument("","root",null);(命名空间,元素标签,文档类型)
var child = xmldom.createElement("child");
xmldom.documentElement.appendChild(child);
检测浏览器支持情况
var hasXmlDom = document.implementation.hasFeature("XML","2.0")
2,DOMParser类型
解析XML之前,创建一个DOMParser类型,调用parserFormString(要解析的XML字符串,内容类型text/xml)方法
解析发生错误时,parseFromString()返回一个document对象,这个对象的文档元素是<parsererror>
var parser = new DOMParser(),xmldom,errors;
try{
xmldom = parser.parseFormString("<root>","text/xml");
errors = xmldom.getElementsByTagName("parsererror");
if(errors.length > 0){
throw new Error("Parsing errot!");
}
}catch(ex){
alert("Parsing error!");
}
3,XMLSerializer类型
XMLSerializer类型,将DOM文档序列化为XML字符串
首先创建一个XMLSerializer实例,然后将文档传人其serializerToString()方法
var serializer = new XMLSerializer();
var xml = serializer.serializerToString(xmldom);
4,IE8及之前版本中的XML、
IE是第一个支持XML的浏览器,通过ActiveX对象实现
为了便于桌面应用程序开发人员处理XML,微软创建了MSXML库
ActiveXObject类型,可以通过它创建ActiveX对象的实例,要创建一个XML文档的类型,要使用ActiveXObject构造函数,传人一个表示XML文档版本的字符串
有六种不同的XML文档版本可以供选择
Microsoft.XmlDom:最初随同IE发布,不建议使用
MSXML2.DOMDocument:为方便脚本处理更新的版本,建议在特殊情况下作为后备版本
MSXML2.DOMDocument.3.0:在Javascript中使用,是最低的建议版本
MSXML2.DOMDocument.4.0:通过脚本处理时不可靠,可能导致安全警告
MSXML2.DOMDocument.5.0:通过脚本处理时不可靠,可能导致安全警告
MSXML2.DOMDocument.6.0:通过脚本能够可靠处理的最新版本
function createDocument(){
if(typeof argument.callee.activeXString != "String"){
var versions = ["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument"],i,len;
for(i=0,len=versions.length;i<len;i++){
try{
new ActiveXObject(versions[i]);
argument.callee.activeXString = versions[i];
}catch(ex){
//跳过
}
}
}
return new ActiveXObject(argument.callee.activeXString);
}
要解析XML字符串,首先创建一个DOM文档,然后调用loadXML()方法,新创建的XML文档为空,不能操作,
为loadXML()方法传人XML字符串解析之后会被填充到DOM文档中,
var xmldom = createDocument();
xmldom.loadXML("<root><child /></root>");
如果解析过程出错,在parseError属性中找到错误消息,属性本身包含多个属性对象,如下
errorCode:错误类型的数值编码,没有错误时为0,值可以为正负
filePos:文件中导致错误发生的位置
line:发生错误的行
linepos:发生错误的行中的字符
reason:对错误的文本解释
srcText:导致错误的代码
url:导致错误的文件的URL
parseError的valueOf()返回errorCode的值
在调用loadXML()之后,查询XML文档之前,检测是否发生了错误
1,序列化XML
每个DOM节点都有一个xml属性,保存着表示该节点的XML字符串
2,加载XML文件
IE中的XML文档对象也可以加载来自服务器的文件,指定加载文档的方式,asyns属性,true表示异步加载,false表示同步加载
var xmldom = createDocument();
xmldom.async = false;
加载了XML文档之后,调用load()可以启动下载过程,接收一个参数即要加载的XML文件的URL,同步方式下,调用load后立即检测解析错误并执行相关XML处理
var xmldoe = createDocument();
xmldom.async = false;
xmldom.load("example.xml");
if(xmldom.parseError != 0){
//处理错误
}else{
//处理xml外部文档
}
异步加载XML文件情况下,为XML DOM文档的onreadystatechange事件指定处理程序,4个就绪状态
1,DOM正在加载数据,2DOM已经加载完数据,3DOM可以使用,但某些部分还无法访问,4DOM完全可以使用
var xmldom = createDocument();
xmldom.asyns = true;
xmldom.onreadystatechange = function(){
if(xmldom.readyState == 4){
if(xmldom.parseError != 0 ){
//处理xmldom文档中错误
}else{
//处理xmldom文档
}
}
};
xmldom.onload("example.xml");
5,跨浏览器处理XML
解析XML而言
function parseXml(xml){
var xmldom = null;
if(typeof DOMParser != "undefined"){
xmldom = (new DOMParser()).parseFormString(xml,"text/xml");
var errors = xmldom.getElementsByTagName("parsererror");
if(errors.length){
throw new Error("XML parseing error:" + errors[0].textContent);
}
}else if(typeof ActiveXObject != "undefined"){
xmldom = createDocument();
xmldom.loadXML(xml);
if(xmldom.parseError !=0 ){
throw new Error("XML parsing error:" + xmldom.parseError.reason);
}
}else{
throw new Error("No xml parser available");
}
return xmldom;
}
使用函数解析XML字符串时,放在try-catch语句中,以防发生错误
var xmldom = null;
try{
xmldom = parseXML("<root><child/></root>");
}catch(ex){
alert(ex.message);
}
对于序列化XML而言,
function serializeXML(xmldom){
if(typeof XMLSerializer != "undefined"){
return (new XMLSerializer()).serializeToString(xmldom);
}else if(typeof xmldom.xml != "undefined"){
return xmldom.xml;
}else{
throw new Error("Could not serialize XML DOM.");
}
}
二,浏览器对XPath的支持
1,DOM3级XPath
XPath是设计用来在DOM文档中查找节点的一种手段
DOM3定义了在DOM中对XPath表达式求值的接口
var supportsXPath = document.implementation.hasFeature("XPath","3.0");
XPathEvaluator类型,用于特定的上下文中对XPath表达式求值,有3个方法
createExpression(expression,nsresolver)将XPath表达式及相应的命名空间信息转换成一个XPathExpression,多次使用同一个查询时有用
createNSResolver(node),根据node的命名空间信息创建一个新的XPathNSResolver对象,基于使用命名空间XML文档求值时,需要使用 XPathNSResolver对象
evaluate(expression,context,nsresolver,type,result),给定的上下文中,基于特定的命名空间信息对XPath表达式求值,剩下的参数指定如何返回结果
expression为XPath表达式,contenxt为上下文节点,nsresolver为命名空间求解器只在XML代码中使用了XML命名空间时有必要指定,没有命名空间 时指定为null,type为结果类型取值如下
XPathResult.ANY_TYPE:返回与XPath表达式匹配的数据类型
XPathResult.NUMBER_TYPE:返回数值
XPathResult.STRING_TYPE:返回字符串值
XPathResult.BOOLEAN_TYPE:返回布尔值
XPathResult.UNORDERED_NODE_ITERATOR_TYPE:返回匹配的节点集合,但集合中节点的次序不一定与文档中一致
XPathResult.ORDERED_NODE_ITERATOR_TYPE:返回匹配的节点集合,次序与文档中一致
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,在文档外部捕获节点,对文档的后续操作不会影响这个节点集合, 集合的节点次序与文档中不一定一致
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,次序一致,其余同上
XPathResult.ANY_UNORDERED_NODE_TYPE:返回匹配的节点集合,集合节点中的次序不一定与他们在文档中一致
XPathResult.FIRST_ORDERED_NODE_TYPE:返回只包含一个节点的节点集合,包含的这个节点就是文档中第一个匹配的节点
var result = xmldom.evaluate("employee/name",xmldom.documentELement,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
if(result != null){
var node = result.iterateNext();
while(node){
alert(node.tagName);
node = node.iterateNext();
}
}
返回结果为XPathResult.ORDERED_NODE_ITERATOR_TYPE,是常用的返回类型,没有节点匹配XPath表达式,返回null,否则返回XPathResult对象
返回的XPathResult对象带有属性和方法,如果节点时节点迭代器与次序无关,要使用iterateNext()从节点中取得匹配的节点,没有更多的匹配节点时,返回null
如果指定的快照结果类型,使用snapshotItem()方法(快照中给定位置的节点)和snapshotLength属性(快照中节点的数量)
var result = xmldom.evaluate("employee/name",xmldom.documentElement,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE.null);
if(result != null){
for(var i=0,len=result.snapshotLength;i<len;i++){
alert(result.snapshotItem(i).tagName);
}
}
1)单节点结果
指定常量XPathResult.FIRST_ORDERED_NODE_TYPE:返回匹配的第一个节点
通过singleNodeValue属性来访问该节点
var result = xmldom.evaluate("employee/name",xmldom.documentElement,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
if(result != null){
alert(result.singliNodeValue.tagName);
}
2)简单类型结果
通过XPathResult的布尔值,数值,和字符串值可以取得简单的非节点的数据类型
对于XPathResult.BOOLEAN_TYPE,有返回值为true,无返回值为false
对于XPathResult.NUMBER_TYPE,必须在XPath表达式参数的位置上指定一个能够返回数值的XPath函数,没有匹配返回NaN
var Result = xmldom.evaluate("count(employee/name)",xmldom.documentElement,null,XPathResult.NUMBER_TYPE,null);
对于字符串类型,查找与XPath表达式匹配的第一个节点,返回第一个子节点的值,没有匹配返回空字符串
3)默认类型结果
使用XPathResult.ANY_TYPE会自动返回结果的类型,确定返回的是什么结果,通过检测resultType属性
4)命名空间支持
对于利用了命名空间的XML,XPathEvaluator必须知道命名空间的信息
处理命名空间的一种方法是通过createNSResolver()创建XPathNSResolver对象,接收一个参数就是包含命名空间定义的节点,传人到evaluate方法中
处理命名空间的另一种方法是定义一个函数,让它接收一个命名空间前缀,返回关联的URL
var nsresolver = function(prefix){
switch(prefix){
case "wrox":return "http://www.wrox.com/"
}
};
传人evaluate方法中
2,IE中的XPath
IE对XPath的支持是内置在基于ActiveX的XMLDOM文档对象中的,没有使用DOMParser返回的DOM对象
使用XPath必须基于ActiveX的实现,这个接口在每个节点上额外定义了两个方法
selectSingleNode(),接受一个XPath模式,在找到匹配节点时返回第一个匹配的节点,没有匹配返回null
selectNodes(),接受一个XPath模式,返回与模式匹配的所有节点的NodeList,没有匹配,返回包含零项的NodeList
IE中处理包含命名空间的XPath表达式,必须知道自己使用的命名空间,按照下列格式创建一个字符串
"xmlns:prefix1='uri1' xmlns='uri2' xmlns='uri3'"
将这个字符串传人到XMLDOM文档对象的特殊方法setProperty(属性名,属性值)中,属性名为SelectionNamespaces,属性值就是按照前面格式创建的字符串
xmldom.setProperty("SelectionNamespaces","xmlns:wrox='http://www.wrox.com/'");
var result = xmldom.documentElement.selectNodes("wrox:book/www:author");
3,跨浏览器使用XPath
selectSingleNode(上下文节点,XPath表达式,命名空间对象)
function selectSingNode(context,expression,namespaces){
var doc = (context.nodeType != 9 ?context.ownerDocument:context);
if(typeof doc.evaluate != "undefined"){
var nsresolver = null;
if(namespaces instanceof Object){
nsresolver = function(prefix){
return namespaces[prefix];
};
}
var result = doc.evaluate(expression,context,nsresolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
return(result != null?result.singleNodeValue : null);
}else if(typeof context.selectSingleNode != "undefined"){
if(namespaces instanceof Object){
var ns = '';
for(var prefix in namespaces){
if(namespaces.hasOwnerProperty(prefix)){
ns += "xmlns:" + prefix + "= '" + namespaces[prefix] + "' ";
}
}
doc.serProperty("SelectionNamespaces",ns);
}
return context.selectSingleNode(expression);
}else{
throw new Error("No XPath engine found.");
}
}
selectNodes()函数,
function selectNodes(context,expression,namespaces){
var doc = (context.nodeType != 9? context.ownerDocument: context)
if(typeof doc.evaluate != "undefined"){
var nsresolver = null;
if(namespaces instanceof Object){
nsresolver = function(prefix){
return namespaces[prefix];
};
}
var result = doc.evaluate(expression,context,nsresolver,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var nodes = new Array();
if(result !== null){
for(var i=0,len=result.snapshotLength;i<len;i++){
nodes.push(result.snapshotItem(i));
}
}
return nodes;
}else if(typeof context.selectNodes != "undefined"){
if(namespaces instanceof Object){
var ns = "";
for(var prefix in namespace){
if(namespace.hasOwnProperty(prefix)){
ns += "xmlns:" + prefix + "=' + namespaces[prefix] + '" ";
}
}
doc.serProperty("SelectionNamespaces",ns);
}
var result = context.selectNodes(expression);
var nodes = new Array();
for(var i=0,len=result.length;i<len;i++){
nodes.push(result[i]);
}
return nodes;
}else{
throw new Error("no Xpath engine found.");
}
}
三,浏览器对XSLT的支持
1,IE中的XSLT
1)简单的XSLT转换
使用XSLT样式表转化XML文档的最简单的方法,是将他们分别放在一个DOM文档中,然后使用transformNode()方法
这个方法存在于所有节点中,接收一个参数,包含XSLT样式表的文档,返回一个包含转换信息的字符串
xmldom.load("employees.xml");
xsltdom.load("employees.xslt");
var result = xmldom.transformNode(xsltdom);
可以在文档的任何级别上进行转换
2)复杂的XSLT转换
使用XSL模板和XML处理器,第一步是把XSLT样式表加载到一个线程安全的XML文档中,通过使用ActiveX对象MSXML2.FreeThreadedDOMDocument来做
创建线程安全的XML DOM,即ActiveX对象,与常规的DOM支持相同的接口
function createThreadSafeDocument(){
if(typeof argument.callee.activeXString != "string"){
var verions = ["MSXML2.FreeThreadedDOMDocument.6.0","MSXML2.FreeThreadedDOMDocument.3.0","MSXML2.FreeThreadedDOMDocument"],i,len;
for(i=0,len=versions.length;i<len;i++){
try{
new ActiveXObject(versions[i]);
argument.callee.activeXString = versions[i];
break;
}catch(ex){
//跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
var xsltdom = createThreadSafeDocument();
xsltdom.async = false;
xsltdom.load("employee.xslt");
创建并加载了自由线程的DOM之后,必须将它指定给一个XSL模板,这也是一个ActiveX对象,这个模板用来创建XSL处理对象的,后者用来转换XML文档
function createXSLTemplate(){
if(typeof argument.callee.activeXString != "string"){
var versions = ["MSXML2.XSLTemplate.6.0","MSXML2.XSLTemplate.3.0","MSXML2.XSLTemplate"],i,len;
for(i=0,len=versions.length;i<len;i++){
try{
new ActiveXObject(versions[i]);
argument.callee.activeXString = version[i];
break;
}catch(ex){
//跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
var template = createXSLTemplate();
template.stylesheet = xsltdom;
var proccessor = template.createProcessor();
processor.input = xmldom;
processor.transform();
var result = processor.output;
transform方法可执行转换并将结果作为字符串保存在output属性中
XSLT样式表可以接受传人的参数,并将其用作局部变量
processor.input = xmldom.documentElement;
processor.addParameter("message","hello");
processor.transform();
XSL处理器能够设置一种操作模式,可是使用mode特性为模板定义一种模式,
processor.input = xmldom;
processor.addParameter("message","hellp");
processor.setStartMode("title-first");
processor.transform();
如果打算使用同一样式表进行多次转换,可以在转换之后重置处理器,调用reset()方法
会清除原先的输入和输出属性,启动模式以及其他指定的参数,
2,XSLTProcessor类型
可以通过XSLTProcessor类型,使用XSLT转换XML文档
与IE类似,第一步加载两个DOM文档,一个基于XML,一个基于XSLT,然后创建XSLTProcessor对象,
指定importStyleSheet()方法为其指定一个XSLT,
var processor = new XSLTProcessor();
processpr.importStyleSheet(xsltdom);
最后一步执行转换,想返回完整的DOM文档,使用transformToDocument(),想返回一个文档对象片段,使用transformToFragment(),将返回的结果添加 到另一个DOM文档中
XSLT样式表在输出格式为XML或HTML时,没有问题,当格式为text时,浏览器支持情况不同,这时使用transformToFragment()
var fragment = processpr.transformToFragment(xmldom,document);
var text = fragment.firstChild.nodeValue;
alert(text);
1)使用参数
XSLTProcessor类型通过serParameter()设置XSLT的参数,命名空间URL,参数内部名称,要设置的值
要在调用transformToDocument(),transformToFragment()之前调用
var processor = new XSLTProcessor();
processor.importStyleSheet(xsltdom);
processor.setParameter(null,"message",null);
var result = processor.transformToDocument(xmldom);
getParameter()取得当前参数的值,(命名空间(一般为null),参数的名称)
removeParameter()移除当前参数的值(命名空间(一般为null),参数的名称)
2)重置处理器
processor.reset()
移除所有参数和样式,可以再次调用importStyleSheet()
3,跨浏览器使用XSLT
function transform(context,xslt){
if(typeof XSLTProcessor != "undefined"){
var processor = new XSLTProcessor();
processor.importStylesheet(xslt);
var result = processor.transformToDocument(context);
return (new XMLSerializer()).serializeToString(result);
}else if(typeof context.transformNode != "undefined"){
return context.transformNode(xslt);
}else{
throw new Error("No XSLT processor available");
}
}
var result = transform(xmldom,xsltdom);
javascript和XML的更多相关文章
- ajax-异步JavaScript和XML
什么是ajax? ajax是异步的javascript和XML ( Asynchronous Javascript And XML ) 优点:节省用户操作时间,提高用户体验.减少数据请求次数. 什么是 ...
- JavaScript操作XML
JavaScript操作XML (一) JavaScript操作XML是通过XML DOM来完成的.那么什么是XML DOM呢?XML DOM 是: 用于 XML 的标准对象模型 用于 XML 的标准 ...
- 18. javacript高级程序设计-JavaScript与XML
1. JavaScript与XML IE采取了下列方式: l 通过ActiveX对象来支持处理XML,而相同的对象也可以用来构建桌面应用程序 l Windows携带了MSXML库,JavaScript ...
- JavaScript实现XML与JSON互转代码(转载)
下面来分享一个关于JavaScript实现XML与JSON互转例子,这里面介绍了国外的三款xml转json的例子,希望这些例子能给你带来帮助. 最近在开发在线XML编辑器,打算使用JSON做为中间格式 ...
- 用javascript操作xml
用javascript操作xml 可以使用标准DOM操作. IE创建XML MSXML2.0DOMDocument function createXMLDOM(){ var version = [ ' ...
- 第一百二十五节,JavaScript,XML
JavaScript,XML 学习要点: 1.IE中的XML 2.DOM2中的XML 3.跨浏览器处理XML 随着互联网的发展,Web应用程序的丰富,开发人员越来越希望能够使用客户端来操作XML技术. ...
- javascript与XML
曾几何时,XML一度成为存储和通过因特网传输结构化数据的标准,之前,浏览器无法解析XML数据时,开发人员都要手动编写自己的XML解析器.而自从DOM出现后,所有浏览器都内置了对XML的原生支持(XML ...
- C#将XML转换成JSON 使用 JavaScript 将 XML 转成 JSON
如何在ASP.NET中用C#将XML转换成JSON [JavaScript]代码 // Changes XML to JSON function xmlToJson(xml) { // Create ...
- javascript读取xml文件读取节点数据的例子
分享下用javascript读取xml文件读取节点数据方法. 读取的节点数据,还有一种情况是读取节点属性数据. <head> <title></title> < ...
- How to make an HTTP request 异步 JavaScript 和 XML
https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started In order to make an HTTP request to th ...
随机推荐
- Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶
多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...
- JVM有哪些垃圾回收器
JVM 的垃圾回收器 目录 JVM 的垃圾回收器 经典垃圾收集器 Serial 收集器 ParNew 收集器 Parallel Scavenge 收集器 Serial Old 收集器 Parallel ...
- 【Android初级】如何实现一个“模拟后台下载”的加载效果(附源码)
在Android里面,后台的任务下载功能是非常常用的,比如在APP Store里面下载应用,下载应用时,需要跟用户进行交互,告诉用户当前正在下载以及下载完成等. 今天我将通过使用Android的原生控 ...
- 前端面试之JavaScript中的闭包!
前端面试之JavaScript中的闭包! 闭包 闭包( closure )指有权访问另一个函数作用域中变量的函数. ----- JavaScript 高级程序设计 闭包其实可以理解为是一个函数 简单理 ...
- Avoid catching exceptions inside atomic! You may need to manually revert model state when rolling back a transaction. 避免异常程序不抛错误 回滚 导致 自增id不连续。
https://docs.djangoproject.com/en/3.0/topics/db/transactions/ You may need to manually revert model ...
- C# 防止程序多开(重复开启)
Mutex(mutual exclusion,互斥)是 .Net Framework 中提供跨多个线程同步访问的一个类.它非常类似了 Monitor 类,因为他们都只有一个线程能拥有锁定.而操作系统能 ...
- (数据科学学习手札105)Python+Dash快速web应用开发——回调交互篇(中)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- 通过 JFR 与日志深入探索 JVM - TLAB 原理详解
全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇 什么是 TLAB? TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配 ...
- 透明小电视上线——GitHub 热点速览 v.21.05
作者:HelloGitHub-小鱼干 这周的 GitHub Trending 真是棒极了.小鱼干喜欢的科技博主又开源了他的硬件玩具,一个透明的小电视机,HG 的小伙伴看完项目,再买个电路板和分光棱镜, ...
- Linux环境mysql快速备份及迁移
在项目实施的过程中,经常会面临数据库迁移,导出和导出数据,如果用普通的mysql客户端备份,时间较长且容易出错.那么mysql快速备份及迁移,就成为数据库迁移的重中之重. 下面介绍我在项目实现过程中用 ...