310 likes | 462 Views
Ajax 编程技术 第五章 XML 要点. 5.1 XML 基础. 使用 XMLHttpRequest 对象向服务器提出请求后,服务器返回数据的格式有两种: 文本格式:是一种很容易添加到页面的字符,然而,在数据交换方面,文本格式非常有限。字符之间不存在元素、数据类型等区别。 XML 格式:是一种标记语言,它使用用户自定义标记,按照特定的方式组织数据。
E N D
5.1 XML基础 使用XMLHttpRequest对象向服务器提出请求后,服务器返回数据的格式有两种: • 文本格式:是一种很容易添加到页面的字符,然而,在数据交换方面,文本格式非常有限。字符之间不存在元素、数据类型等区别。 • XML格式:是一种标记语言,它使用用户自定义标记,按照特定的方式组织数据。 浏览器从响应Ajax请求的服务器中接收XML文档时,我们需要一种方法来提取XML数据并显示之。JavaScript可以使用节点、节点属性和DOM方法从XML文档中检索数据。一旦提取XML数据,就可以使用CSS或XSLT在页面显示该数据。 5-2
5.1 XML基础 • XML特点 • 允许数据分类; • 允许创建数据格式; • 将数据输出到各个地方; • 不是私有语言,不局限于特殊平台或设备。 5-3
5.1 XML基础 • 创建标记 我们来构建一个XML文档。其中我们将创建一组自定义的标记: 包含所有其他元素的根元素 <classes> <class> <classID>CS115</classID> <department>ComputerScience</department> <credits req="yes">3</credits> <instructor>Adams</instructor> <title>Programming</title> </class> </classes> <classes> Classes的子元素 <class> 元素的结束标记 元素的开始标记 </department> <department> ComputerScience 元素所包含的内容 5-4
5.1 XML基础 • XML语法 • XML文档的从XML申明开始: <?xml version=“1.0” ?> • XML有一个包含其他所有元素的根元素,如上例中的<classes>; • XML的标记必须有开始标记和结束标记,中间是元素内容: <title> Programming </title> • 空元素没有元素内容,也没有元素结束标记,但元素开始标记以“ />”封口; • 标记嵌套必须正确,不能交叉嵌套; • 标记内的属性值必须用引号界定。 5-5
5.1 XML基础 • 评价 使用XML进行数据交换的主要优势是XML文档可以包括关于该文档中数据的格式和类型的详细信息。方便验证XML文档是否接收正确。 5-6
5.1 XML基础 • 示例:请求服务器端的XML数据 • 创建一个主页,index.htm: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/> <title>Requesting XML</title> <script language="javascript"> function getDoc() { if (window.XMLHttpRequest) request = new XMLHttpRequest(); else if (window.ActiveXObject) request = new ActiveXObject("Microsoft.XMLHTTP"); if (request.overrideMimeType) request.overrideMimeType("text/xml"); if (request){ request.open("GET","classes.xml",true); request.onreadystatechange = function() { if(request.readyState == 4 && request.status == 200){ var xmlDocument = request.responseXML; alert('XML Document Retrieved'); } } request.send(null); } } </script> </head> <body> <h1>Requesting XML</h1> <form> <input type="button" id="reqDoc" value="Make request"> </form> <script type="text/javascript"> var myDoc = document.getElementById('reqDoc'); myDoc.onclick = getDoc; </script> </body> </html> 5-7
5.1 XML基础 • 创建服务器端的数据文件classes.xml,以utf-8格式保存: <?xml version="1.0"?> <?xml-stylesheet type="text/css" href="classes.css"?> <classes> <class> <classID>CS115</classID> <department>ComputerScience</department> <credits req="yes">3</credits> <instructor>Adams</instructor> <title>Programming</title> </class> <class> <classID isemester="fall">CS205</classID> <department>ComputerScience</department> <credits req="yes">3</credits> <instructor>Dykes</instructor> <title>Javascript</title> </class> <class> <classID isemester="fall">CS255</classID> <department>ComputerScience</department> <credits req="no">3</credits> <instructor>Brunner</instructor> <title>C++程序设计</title> </class> </classes> 5-8
5.1 XML基础 • 运行: 在右图所示界面中,点击“make request”按钮,出现警示框: 5-9
5.1 XML基础 • 如果将index.htm中红色字符显示的代码该成如下代码: alert(xmlDocument.xml); 则程序弹出的警示框为 右图所示的警示框: 本章后面将介绍如 何使用JavaScript从服 务器返回的XML文档中 提取数据。 5-10
5.2 使用JavaScript提取XML数据 一旦从服务器中获得XML文档,下一步要做的工作就是使用JavaScript从该文档中提取XML数据。我们可以使用节点、节点属性或DOM方法获取。除了使用XML元素的值之外,还可以提取XML属性的值。 5-11
5.2 使用JavaScript提取XML数据 • 使用节点 JavaScript包括内置节点属性,可以使用这些属性访问XML文档中的节点。也可以使用documentElement属性访问XML文档的根元素。其他节点属性包含的家族如下所示: • firstChild: 第一个子节点; • lastChild:最后一个子节点; • nextSibling:下一个同属(兄弟)节点; • previousSibling:前一个兄弟节点; • childNodes:子节点数组 • nodeName:节点名称 • nodeValue:节点值 • nodeType:节点类型,类型值见下表: 5-12
5.2 使用JavaScript提取XML数据 • 例1,要访问上例中classes.xml 文档中的根元素名称,可以将上例index.htm程序中红色字符代码改为: alert(xmlDocument.documentElement.nodeName); 则单击按钮后,屏幕弹出如下警示框,显示出classes.xml根元素的名称:classes: 5-14
5.2 使用JavaScript提取XML数据 • 例2,还可以利用已经得到的变量xmlDocument获得XMLHttpRequest对象的requestXML属性: var rootNode = xmlDocument.documentElement; 可以根据家族关系访问该文档中最后一个class元素的文本节点值, var classNode = rootNode.lastChild; //即class,classes最后一个子元素 var titleNode = classNode.lastChild; //class元素的最后一个子元素是title var titleText = titleNode.firstChild; //获得title的首个子元素,即它的文本节点 var titleValue = titleText.nodeValue; //获得title 的文本值 将index.htm中红色代码替换成上面的5行代码,则点击按钮后,程序弹出如下警示框: 5-15
5.2 使用JavaScript提取XML数据 • 例3,如果要访问上例中第一个class元素的文本节点值,可将上页的绿色代码改成如下代码: var classNode = rootNode.fristChild; 5-16
5.2 使用JavaScript提取XML数据 • 这些程序在IE下会很好地运行,但在Mozilla的浏览器中会出现错误。原因在于, Mozilla的浏览器将XML文档中的空格作为文本节点处理。那么,当访问基于Mozilla浏览器中的classes 元素的firstChild时,访问的是空格文本节点而不是首个class元素。修改的方法是,使用家族关系跳过这些空格节点。即将上面的红色代码 var classNode = rootNode.fristChild; 修改如下: var classNode = rootNode.firstChild.nextSibling; • 当然,最好的办法是变成删除XML中的所有空格。 5-17
5.2 使用JavaScript提取XML数据 • 根据名称访问XML元素 除了使用节点属性访问节点信息外,还可以使用getElementsByTagName方法根据XML元素的名称从XML文档中提取特定元素。 例如,classes.xml文档中有多个title元素,可以用: var titleNode = xmlDocument.getElementsByTagName(‘title’); 全部提取出来,结果形成titleNode数组。然后提取数组中的某个元素: var firstTitle = titleNode[0]; //获取第一个title元素 var firstTitleValue = firstTitle.firstChild.nodeValue;//获取该元素的文本节点值 5-18
5.2 使用JavaScript提取XML数据 如果要显示该文本节点值,可在页面上添加带有id值的div标记,然后在此div中显示出来: var myEl = document.createElement(‘p’); var newText = “第一个课程是:”+titleValue+”.”; var myTx = document.createTextNode(newText); myEl.appendChild(myTx); var course = document.getElementsByTagName(‘title’); course.appendChild(myEl); 完整的index.htm程序如下页所示: 5-19
5.2 使用JavaScript提取XML数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/> <title>Requesting XML</title> <script language="javascript"> function getDoc() { if (window.XMLHttpRequest) request = new XMLHttpRequest(); else if (window.ActiveXObject) request = new ActiveXObject("Microsoft.XMLHTTP"); if (request.overrideMimeType) request.overrideMimeType("text/xml"); if (request){ request.open("GET","classes.xml",true); request.onreadystatechange = function(){ if(request.readyState == 4 && request.status == 200) { var xmlDocument = request.responseXML; var rootNode = xmlDocument.documentElement; var classNode = rootNode.firstChild; var titleNode = classNode.lastChild; var titleText = titleNode.firstChild; var titleValue = titleText.nodeValue; var myEl = document.createElement('p'); var newText = "第一个课程是:"+titleValue+"."; var myTx = document.createTextNode(newText); myEl.appendChild(myTx); var course = document.getElementById('title'); course.appendChild(myEl); } } request.send(null); } } </script> </head> <body> <h1>Requesting XML</h1> <form> <input type="button" id="reqDoc" value="Make request"> </form> <div id='title'></div> <script type="text/javascript"> var myDoc = document.getElementById('reqDoc'); myDoc.onclick = getDoc; </script> </body> </html> 5-20
5.2 使用JavaScript提取XML数据 classes.xml: <?xml version="1.0"?> <?xml-stylesheet type="text/css" href="classes.css"?> <classes> <class> <classID>CS115</classID> <department>ComputerScience</department> <credits req="yes">3</credits> <instructor>Adams</instructor> <title>Programming</title> </class> <class> <classID isemester="fall">CS205</classID> <department>ComputerScience</department> <credits req="yes">3</credits> <instructor>Dykes</instructor> <title>Javascript</title> </class> <class> <classID isemester="fall">CS255</classID> <department>ComputerScience</department> <credits req="no">3</credits> <instructor>Brunner</instructor> <title>C++程序设计</title> </class> </classes> 5-21
5.2 使用JavaScript提取XML数据 程序运行如下左图;点击按钮后,显示出如下右图示的信息: 5-22
5.2 使用JavaScript提取XML数据 • 访问属性值 还可以使用JavaScript提取XML文档中的属性节点值。属性节点被包含在元素节点内。因此,需要首先访问你感兴趣的属性元素。例如classes.xml中creditd元素包括一个名位req的属性,可以使用getElementsByTagName提取credits元素: var creditStatus = xml.Document.getElementsByTagName(‘credits’); 然后可使用attributes属性访问该属性。因为有多个credits元素,所以creditStatus变量包含一个数组。我们这样访问文档中第三个credits元素的属性值: var creditAttr = creditStatus[2].attributes; getNamedItem方法允许使用属性获取req属性值: var reqAttr = creditAttr.getNamedItem(‘req’); 最后使用nodeValue获取req属性值: var reqVal = reqAttr.nodeValue; 5-23
5.2 使用JavaScript提取XML数据 • 示例,利用XMLHttpRequest对象从服务器下载classes.xml文档,然后读出文档中的元素和属性值: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>Checking Courses</title> <script language = "javascript"> function getDoc() { if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); } if (request.overrideMimeType) { request.overrideMimeType("text/xml"); } if(request) { request.open("GET", "classes.xml", true); request.onreadystatechange = function() { if ((request.readyState == 4) && (request.status == 200)) { var xmlDocument = request.responseXML; findClass(xmlDocument); } } request.send(null); } } //紧接下页代码 5-24
5.2 使用JavaScript提取XML数据 function findClass(doc) { var titleNode = doc.getElementsByTagName('title'); for (i=0; i<titleNode.length; i++) { var title = titleNode[i]; var titleValue = title.firstChild.nodeValue; var myEl = document.createElement('p'); var newText = titleValue + " 课程的"; var myTx = document.createTextNode(newText); myEl.appendChild(myTx); var course = document.getElementById('title'); if (i==0) { myEl.style.color='#ff0000';} else if (i==1) { myEl.style.color='green';} else { myEl.style.color='navy';} myEl.style.fontSize='12pt'; course.appendChild(myEl); var instructorNode = doc.getElementsByTagName('instructor'); var instructor = instructorNode[i]; var instructorValue = "教师是" + instructor.firstChild.nodeValue+","; var addTxt = document.createTextNode(instructorValue); myEl.appendChild(addTxt); var creditStatus = doc.getElementsByTagName('credits'); var creditAttr = creditStatus[i].attributes; var reqAttr = creditAttr.getNamedItem('req'); var reqVal = reqAttr.nodeValue; if (reqVal == 'yes') { var addlText = "这是必修课"; } else { var addlText = "这是选修课"; } var addlText2 = document.createTextNode(addlText); myEl.appendChild(addlText2); } } </script> </head> <body> <h1>Checking courses</h1> <form> <input type = "button" id="reqDoc" value = "Check courses"> </form> <script type="text/javascript"> var myDoc = document.getElementById('reqDoc'); myDoc.onclick = getDoc; </script> <div id="title"></div> </body> </html> 5-25
5.2 使用JavaScript提取XML数据 • 运行时,点击按钮,网页从下载的XML文档中显示提取的元素值: 5-26
5.3 使用CSS显示XML数据 • 让XML数据按照CSS式样表规定的格式显示 普通的XML文档不包 含显示格式信息。例如, 我们这里用到classes.xml 文档用浏览器打开后, 显示情况如右: 5-27
5.3 使用CSS显示XML数据 如果在第一行后面加上一条语句,可以将XML文档数据按照指定的CSS式样表显示: <?xml-stylesheet type="text/css" href="classes.css"?> 当然,我们要创建class.css文档,在其中规定XML显示格式: classID,title,credits{ display:block; color:maroon; font-size:10pt; font-family:Arial,宋体; font-weight:bold; } 再次用浏览器打开classes.xml,则显示为: 5-28
5.3 使用CSS显示XML数据 • 在Ajax中使用CSS Ajax部分更新页面时不用重新加载整个页面,部分更新时,可以使用JavaScript将CSS式样表应用到要加载的XML数据上。JavaScript的style和className属性可以担当此任务。 • style属性: JavaScript的style属性能够设置CSS式样值,格式如下: element.style.property = “value”; 5-29
5.3 使用CSS显示XML数据 例如,想将id值为’p1’的段落中的文本颜色设置为紫色,字号设置为10pt,程序代码如下: var myPara = document.getElementById(‘p1’); myPara.style.color = “purple”; myPara.style.fontSize = “10pt”; 5-30
5.3 使用CSS显示XML数据 • className属性 JavaScript的className属性提供一种快速转换CSS类的方法。例如,假定已定义两个CSS类选择器:.red和.blue,并且最初已赋予red类于一个段落,程序如下: <p id=“first” name=“first” class=“red”> 可以使用JavaScript改变该赋值: document.getElementById(‘first’).className=“blue”; className属性不受style属性的限制。可以不必直接使用JavaScript来改变style属性,而使用JavaScript改变应用于某个对象的CSS 类。 5-31