第18章 JavaScript与XML
浏览器对XML DOM的支持
DOM2级核心
document.implementation.createDocument():创建一个空白的XML文档
DOMParser类型
- 将XML解析为DOM文档,首先必须创建一个DOMParser的实例,然后再调用parseFromString()方法,返回值是一个document实例
- DOMParser只能解析XML,不能讲HTML解析为HTML文档
1
2
3
4
5
6
7
8
9
10var parser = new DOMParser();
var xmldom = parser.parseFromString("<root><child/></root>", "text/xml");
alert(xmldom.documentElement.tagName); //root
alert(xmldom.documentElement.firstChild.tagName); //child
var anotherChild=xmldom.createElement("child");
xmldom.documentElement.appendChild(anotherChild);
var children=xmldom.getElementsByTagName("child");
alert(children.length); //2
XMLSerializer类型
- 将DOM文档序列化为XML文档,使用XMLSerializer类型
- XMLSerializer类型可以序列化XML和HTML
IE8及之前版本中的XML
- 通过ActivrX对象实现对XML的支持
- 创建XML文档:使用ActiveXObject构造函数并为其传入一个表示XML文档版本的字符串
- 解析XML:loadXML()方法
- 序列化:每个DOM节点都有一个xml属性,xmldom.xml
- 加载XML文件:确定加载XML方式,调用load()启动下载过程
跨浏览器处理XML
解析XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function parseXml(xml){
var xmldom = null;
if (typeof DOMParser != "undefined"){
xmldom = (new DOMParser()).parseFromString(xml, "text/xml");
var errors = xmldom.getElementsByTagName("parsererror");
if (errors.length){
throw new Error("XML parsing 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
1
2
3
4
5
6
7
8
9function 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的支持
- XPath是设计用来在DOM文档中查找节点的一种手段,因而对XML处理也很重要
DOM3级XPath
- XPathEvaluator:用于在特定的上下文中对XPath表达式求值
- 处理命名空间有两种方法:
1.createNSResolver()创建XPathNSResolver对象
2.定义一个函数,让它接收一个命名空间前缀
IE中的XPath
- 在IE8及之前的浏览器,XPath是采用内置基于ActiveX的XML DOM文档对象实现的。在每一个节点上提供了两个方法:selectSingleNode()和selectNodes()。
- 处理命名空间的方法:setProperty()
跨浏览器使用XPath
- 要在其它使用DOM3级XPath对象的浏览器中,重新创建selectSingleNode()和selectNodes()方法。
1 | function selectSingleNode(context, expression, namespaces) { |
浏览器对XSLT的支持
- XSLT:它利用XPath将文档从一种表现形式转换成另一种表现形式
IE中的XSLT
简单的XSLT转换:使用XSLT样式表
1
2
3xmldom.load("employees.xml");
xstldom.load("employees.xstl");
var result = xmldom.transformNodes(xstldom);复杂的XSLT转换:使用XSL模板和XSL处理器
第一步: 先要把XSTL样式表加载到一个线程安全的XML文档中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function createThreadSafeDocument() {
if (typeof arguments.callee.activeXString != "string") {
var versions = ["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]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) {
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}第二步:将创建并加载了自由线程的DOM文档指定给一个XSL模板,这也是一个ActiveX对象,模板用来创建XSL处理器对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function createXSTLTemplate() {
if (typeof arguments.callee.activeXString != "string") {
var versions = ["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]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) {
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}使用示例
1
2
3
4
5
6
7
8
9
10
11var xsltdom = createThreadSafeDocument();
xstldom.async = false;
xsltdom.load("employees.xslt");
var template = createXSTLTemplate();
template.stylesheet = xstldom;
var processor = tempalte.createProcessor();
processor.input = xmldom;
processor.transform();
var result = processor.output;
XSLTProcessor类型
- XSLTProcessor:是通过JS进行XSLT转换的事实标准
1
2var processor = new XSLTProcessor();
processor.importStylesheet(xsltdom);
跨浏览器使用XSLT
- 接收两个参数: 要执行转换的上下文节点和XSLT文档对象。 返回序列化之后的字符串。
1
2
3
4
5
6
7
8
9
10
11
12function 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 caontext.transformNode(xslt);
} else {
throw new Error("No XSLT processor available.");
}
}