版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、探讨Ajax获取表单值向Servlet传递的设计方案 现在JavaWeb领域,MVC框架越来越多,比较出名的有Struts、Struts2、SpringMVC、WebWork等。而Ajax,作为一种与特定的动态Web编程语言(如Java、C#、PHP)无关的技术,也已经被引入到了Java MVC框架的各家各户。而这些MVC框架,归根到底,都是对Servlet技术的封装。同时,支持Ajax的JavaScript框架(or类库)也越来越多,出名的如Jquery、Ext、Prototype、DWR等,而它们实现异步传输功能还是离不开JavaScript中的XMLHttpRequest这个对象。好,转
2、入正题吧。Ajax通过XMLHttpRequest对象实现异步传输,那我们首先要获取这个对象。由于浏览器的差异,为了兼容各种常用的浏览器,先写一个初始化XMLHttpRequest对象的方法,代码如下: Js代码 /* * Get方式向服务器端异步发送数据 * param url 服务器端的路径,数据发送的目的地 * param data 发送的数据,格式如: key1=value1&key2=value2 * param callback 回调函数, */ function doGet(url, data, callback) var url = url; if(url.indexOf(?)
3、 = -1) url = url + ? + data; else url = url + & + data; initXmlHttp(); xmlHttp.onreadystatechange = callback; /注册回调函数 xmlHttp.open(GET, url, true); /设置连接信息 xmlHttp.send(null); /* * Post方式向服务器端异步发送数据 * param url 服务器端的路径,数据发送的目的地 * param data 发送的数据,格式如: key1=value1&key2=value2 * param callback 回调函数 *
4、return */ function doPost(url, data, callback) initXmlHttp(); /初始化 xmlHttp.onreadystatechange = callback; /注册回调函数 xmlHttp.open(POST, url, true); xmlHttp.setRequestHeader(Content-Type, application/x-www-form-urlencoded); xmlHttp.send(data); /* * 默认回调函数 * 只在测试时使用,在doGet和doPost函数中的第三个参数callback,可由用户自定义
5、回调函数, * 若不设定,则调用默认的回调函数 */ function callback() /判断对象的状态是否交互完成 if(xmlHttp.readyState = 4) /判断http的交互是否成功 if(xmlHttp.status = 200) /获取服务器返回的纯文本数据 var responseText = xmlHttp.responseText; /获取服务器返回的XML格式数据 /var responseXml = xmlHttp.responseXML; /Alert从服务器端返回的信息 window.alert(responseText); 对上面的代码,在这里解析一
6、下:XMLHttpRequest对象的请求状态(readyState)有0、1、2、3、4,其中,0表示未初始化,1表示open方法成功调用,2表示服务器应答客户端请求,3表示交互中,HTTP头信息已经收到,但响应数据还没有接收,4表示数据接收完成。我们通过“xmlHttp.onreadystatechange = callback;”来设置如果XMLHttpRequest对象的请求状态发生改变了,则会执行回调函数callback。我们可以看到,在callback方法体中,我们只关心readyState=4(交互完成)的情况,再获取从服务器端返回的状态码status,常见的状态码有:200表示
7、交互成功,404表示页面没找到,500表示服务器处理错误等。接着,通过XMLHttpRequest的responseText属性得到从服务器端返回的文本数据,或者通过responseXML属性获得XML格式的数据。在上面的代码中,doGet方法和doPost方法都有参数”data”,它由XMLHttpRequest负责从客户端传送到服务器端,对于Get方法,附在URL尾部,例如:member.jsp?name=xxx&sex=male。对于Post方式,可调用XMLHttpRequest的send方法发送。data的数据形式比较灵活,可以是普通的参数格式、XML格式,JSON格式或者是其他格式
8、,只要你能发送过去,服务器端就有办法将你解析出来。在这里,我们降低难度,就用最简单的参数格式,即key1=value1 & key2=value2 & key3=value3 & 我们都知道,HTTP协议的Get方式传输数据,是通过把这些key-value串附到URL后面的,也就是我们只要点表单的提交按钮,就可以看到地址栏后面会多了一串key-value,代表表单里各输入框的名和值。然后,我们要做异步发送数据,就不能用表单的自动提交了,也就是说,得自己一个一个获取到各输入框的数据,然后再一个一个拼成上面的key-value串再发送。有没有一种简单的办法来组织这些数据呢?大家看到key-valu
9、e是否会想到Java中的什么类?请看下面代码,我用JavaScript写了一个Map类(JavaScript中的“function”可以看作是方法,也可以看作是面向对象的“类”),就是类似于Java中我们常用的Map接口。 Java代码 /* * Map类 * 实现了类似于Java语言中的Map接口的常用方法 */ function Map() /key集 this.keys = new Array(); /value集 this.values = new Array(); /添加key-value进Map this.put = function(key, value) if(key = nu
10、ll | key = undefined) return; var length = this.size(); for(var i = 0 ; i length ; i + ) /如果keys数组中有相同的记录,则不覆盖原记录的值 if(this.keysi = key) this.valuesi = value; this.keys.push(key); this.values.push(value); ; /获取指定key的value this.get = function(key) var length = this.size(); for(var i = 0 ; i length ;
11、i + ) if(this.keysi = key) return this.valuesi; else continue; return null; ; /移除指定key所对应的map this.remove = function(key) var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) while(i length - 1) this.keysi = this.keysi+1; this.valuesi = this.valuesi+1; i + ; /处理最后一个元素 this
12、.keys.pop(); this.values.pop(); break; ; /是否包含指定的key this.containsKey = function(key) var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) return true; return false; ; /是否包含指定的value this.containsValue = function(value) var length = this.size(); for(var i = 0 ; i length ; i
13、 + ) if(this.valuesi = value) return true; return false; ; /包含记录总数 this.size = function() return this.keys.length; ; /是否为空 this.isEmpty = function() return this.size() = 0 ? true : false; ; /清空Map this.clear = function() this.keys = new Array(); this.values = new Array(); ; /将map转成字符串,格式:key1=value1
14、,key2=value2 this.toString = function() var length = this.size(); var str = ; for(var i = 0 ; i length ; i + ) str = str + this.keysi + = + this.valuesi; if(i != length-1) str += ,; return str; ; 代码比较长,有些方法在本例中可能用不到,但也写出来了,或者在其他地方可能有用吧。当我们使用这个Map类来存储HTTP的参数时,发觉有几个不妥的地方:一是put方法,在Java的Map接口中,是不允许有重复的k
15、ey存在的,而在JavaScript中作为传输参数的载体时,很多时候会出现多个同名的key的,例如处理表单的checkbox时,同一个name的有几个checkbox,构成一个复选框组,组织参数时就形如“key=value1&key=value2”,故put方法必须改。也是由于这个原因,get方法和remove方法也要改。二是toString方法,key=value对,不是用“,”号隔开的,而是用“&”号,故toString方法也须改。而有时候想想,如果把Map类改了,如果其他地方要用到的话,是不是还是改回来,与其改来改去的,不如继承它,重写put、get、remove和toString方法。
16、好主意,代码如下:Js代码 /* * ParamMap类,用于存储HTTP请求中的Get方法或者Post方法所传递的参数 * 继承于Map类,但改写一些方法,以适合HTTP请求中的参数格式 * 与Map不同之处有:ParamMap允许多个同名的key存在, * toString方法返回的key=value对以&号连接,而不是,号,等等。 */ function ParamMap() /继承Map类 Map.call(this); /重写put方法,允许多个同名key存在 this.put = function(key, value) if(key = null | key = undefine
17、d) return; this.keys.push(key); this.values.push(value); ; /重写get方法,返回values数组 this.get = function(key) var results = new Array(); var length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) results.push(this.valuesi); return results; ; /重写remove方法 this.remove = function(key) var
18、 length = this.size(); for(var i = 0 ; i length ; i + ) if(this.keysi = key) while(i length - 1) this.keysi = this.keysi+1; this.valuesi = this.valuesi+1; i + ; /处理最后一个元素 this.keys.pop(); this.values.pop(); ; /重写toString方法, 转成XMLHttpRequest.send(ajaxString)方法的参数格式的字符串, /形如:key1=value1&key2=value2 th
19、is.toString = function() var length = this.size(); var str = ; for(var i = 0 ; i length ; i + ) str = str + this.keysi + = + this.valuesi; if(i != length-1) str += &; return str; ; 怎么使用这个ParamMap类呢,且看下面的示例代码:Js代码 var username = document.getElementById(username).value; var password = document.getElem
20、entById(password).value; var sex = document.getElementById(sex).value; var map = new ParamMap(); map.put(username, username); map.put(password, password); map.put(sex, sex); doGet(test/register, map.toString(), callback); doPost(test/register, map.toString(), callback); Js代码 在JavaScript中,用来获取HTML结点的
21、方法,常用的有如下方法:Js代码 Node document.getElementById(username) /根据标签的id NodeList document.getElementsByName(“username”) /根据标签的name NodeList document.getElementsByTagName(input) /根据标签的标签名 我们注意到在除了getElementById是返回Node对象外,其他两个方法都是返回NodeList对象,相当于Node数组。在Ajax应用中,根据ID来获取节点,很多时候十分方便,如获取text、password、hidden、text
22、area类型的值,但有时候并不那么方便,如处理checkbox、radio(不允许多个同名的id)。况且有许多情况下,开发者是由“非Ajax”转成Ajax应用的。在还没有引进Ajax的时候,表单传值都是根据输入域的name的值来区分的,不管是Get方式还是Post方式,在服务器端(这里指Java Servlet)获取数据的代码如下:Java代码 String HttpServletRequest.getParameter(keyName); /用于单值表单域 String HttpServletRequest.getParameterValues(keyName); /用于多值表单域 所谓的“
23、单值表单域”就是上面提到过的type为text、password、hidden的input或者textarea等,而“多值表单域”是指checkbox。其实,也不尽然,如单值表单域有时候也可以是多值表单域,如我们注册时有时会要求填多个邮箱,这个就可以重复多行用同一个name,它在Servlet端获取值方式跟checkbox一样处理。鉴于各种原因,我们在JavaScript获取HTML Form表单域方法,决定采用getElementsByName方法,这样,我们是不是每取一个表单元素,就得将NodeList类型的返回结果遍历一遍,获取Node,再从Node获取值呢?既然选择了这样做,当然少不了
24、这样的工作,不过,我们可以写一个可重用的方法,让它处理一下NodeList对象。且看代码: Js代码 /* * 获取nodeList的值集 * param nodeList Node数组,可通过getElementsByName或者getElementsByTagName等方法获得 * return 值数组 */ function nodeList2ValuesArray(nodeList) /结果值数组,形如:aaa,bbb,ccc var values = new Array(); var length = nodeList.length; var nodeName = nodeList.
25、item(0).nodeName; /对的处理 if(nodeName = INPUT) var type = nodeList.item(0).getAttribute(type); if(type = text | type = password | type = hidden) for(var i = 0 ; i length ; i + ) values.push(nodeList.item(i).value); else if(type = checkbox | type = radio) for(var i = 0 ; i length ; i + ) var node = nod
26、eList.item(i); if(node.checked) values.push(node.value); /对xxx的处理 else if(nodeName = TEXTAREA) for(var i = 0 ; i length ; i + ) values.push(nodeList.item(i).value); /对的处理 else if (nodeName = SELECT) var subNodeList = nodeList.item(0).getElementsByTagName(option); return nodeList2ValuesArray(subNodeL
27、ist); /对的子元素xxx的处理 else if (nodeName = OPTION) for(var i = 0 ; i length ; i + ) var node = nodeList.item(i); if(node.selected) values.push(node.value); return values; 上面代码将NodeList转成了值数组,而且让使用者忽略表单域类型的差异,专心于值的获取和使用。美中不足的是,上面的方法返回的是数组,我们还是一个一个遍历再拼成key=value字符串。接下来的方法不但解决了这一点,而且还大大简化我们的表单取值,且看: Js代码 /
28、* * 解析表单的数据,转成ParamMap的形式 * param 任意个参数,代表表单子元素的name值 * return ParamMap结果集 */ function parseForm2ParamMap() var map = new ParamMap(); /参数的长度,注意:方法定义的括号中虽然没有定义参数,但却可以设任意多个参数 var length = arguments.length; for(var i = 0 ; i length ; i + ) var nodeList = document.getElementsByName(argumentsi); var valu
29、es = nodeList2ValuesArray(nodeList); for(var j = 0 ; j values.length ; j + ) map.put(argumentsi, valuesj); return map; 这个方法返回值的类型是ParamMap,也就是我们刚才定义的用来传递参数的类,这个类中有一个toString的方法,不就是返回“key1=value1&key2=value2”形式的字符串吗?OK,下面的测试例子,将涉及到表单的各种元素域,其中引进了ajax.js文件,其内容即是我们上面所写的JS函数和类,在附件中可下载到,在此就不重复贴出来了。且看HTML代
30、码: Html代码 测试Ajax与Servlet之间的数据传递 window.onload = function() var submit = document.getElementById(submit); submit.onclick = function() var map = parseForm2ParamMap(username, email, password, userid, sex, framework, salary, dream); /doPost(input, map.toString(), callback); /默认Alert出信息 doPost(input, map
31、.toString(), function() if(xmlHttp.readyState = 4) if(xmlHttp.status = 200) var returnMsg = document.getElementById(returnMsg); returnMsg.innerHTML = xmlHttp.responseText; ); ; ; 测试Ajax与Servlet之间的数据传递(Step1:从Client-Server) 你的姓名: 你的电子邮件(可填两个): 邮件地址1: 邮件地址2: 你的密码: 你的性别 : 男 女 你掌握的开源框架 : Struts Spring H
32、ibernate iBatis WebWork 你的薪水范围 : 2000以下 20003000 30004000 40005000 5000以上 你的职业梦想: 服务器端的代码如下:Java代码 package simple.rongxh.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServle
33、tRequest; import javax.servlet.http.HttpServletResponse; /* * RongXinHua心梦帆影 * site1: * site2: /rongxh7 * author rongxinhua * */ public class Input extends HttpServlet private static final long serialVersionUID = 1L; private void process(HttpServletRequest request, HttpServletResponse response) thro
34、ws ServletException, IOException /获取数据 request.setCharacterEncoding(UTF-8); String username = request.getParameter(username); String emails = request.getParameterValues(email); String password = request.getParameter(password); String userid = request.getParameter(userid); String sex = request.getPar
35、ameter(sex); String framework = request.getParameterValues(framework); String salary = request.getParameter(salary); String dream = request.getParameter(dream); /响应给客户端 response.setContentType(text/html;charset=UTF-8); PrintWriter out = response.getWriter(); out.append(恭喜你,保存成功,你的基本信息如下:); out.appen
36、d(姓名: + username + ); for(int i = 0 ; i emails.length ; i + ) out.append(邮箱 + (i+1) + : + emailsi + ); out.append(密码: + password + ); out.append(编号: + userid + ); out.append(性别: + sex + ); out.append(框架:); for(int i = 0 ; framework != null & i framework.length ; i + ) out.append(frameworki + ); out.
37、append(); out.append(薪水: + salary + ); out.append(梦想: + dream + ); out.println(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException process(request, response); protected void doPost(HttpServletRequest request, HttpServletResponse resp
38、onse) throws ServletException, IOException process(request, response); 运行结果截图如下:附录资料:从 XML 生成可与 Ajax 共同使用的 JSON时下,非常流行使用 JavaScript 代码为数据驱动的 Web 应用程序添加互动性。若能将数据编码成 JavaScript Object Notation(JSON)的格式,您就可以更轻松地通过 JavaScript 语言使用它。通过本文,发掘使用 XSLT V2 从 XML 数据生成 JSON 的几种不同方法。几年前,许多开发人员很看好 XML、XSLT、Extensi
39、ble HTML (XHTML)和其他一些基于标记的语言。现在,Asynchronous JavaScript and XML(AJAX)成了新的热点,人们又将目光转向了使用 JavaScript 代码的数据驱动的富 Internet 应用程序。但是开发人员是否已经消除了 XML 和这一新技术之间的鸿沟呢?当然,您可以在 Web 客户机中使用 XML 解析器来读取数据,但这种做法会带来两个问题。第一,出于安全方面的原因,XML 数据只能从与此页面相同的那个域中读取。这虽然不是什么大的限制因素,但它的确会引起部署方面的问题,还会阻碍 DHTML 小部件的创建。第二,读取和解析 XML 会非常慢。
40、另一种做法是让服务器执行 XML 的解析工作,方法是设置服务器,使之向浏览器发送以 JavaScript 代码或时下流行的 JavaScript Object Notation(JSON)编码的数据。本文将展示如下三种使用 XSLT V2 语言和 Saxon XSLT V2 处理器从 XML 数据生成 JSON 的技巧: 简单编码 通过函数调用加载数据 编码对象 JSON 简介要学习如何将数据编码成 JSON(它只是 JavaScript 的一个子集),最好的方法是从数据开始。清单 1 显示了书籍列表的一个示例 XML 数据集。清单 1. 基本的图形化图书馆 Code Generation i
41、n Action JackHerrington Manning PHP Hacks JackHerrington OReilly Podcasting Hacks JackHerrington OReilly 这个数据集很简单,只包含三本书,每本书都具有惟一的 ID、书名、作者姓名及出版商的名字。(没错,我只选择了我自己的书作为数据集,但能怨我吗?这些书实在是不可多得的节日和生日礼物。)清单 2 显示了这些数据在 JSON 中的效果。清单 2. JSON 中的示例数据集 id: 1, title: Code Generation in Action, first: Jack, last: He
42、rrington, publisher: Manning , . 方括号 () 表明这是一个数组。大括号 () 则表明这是一个散列表,该散列表由一组名称和值对组成。在本例中,我创建了一个散列表的数组 用来存储这类结构式数据的一种常见方法。另外一点值得注意的是字符串是通过单引号或双引号被编码的。所以,如果我想用单引号编码 OReilly,我就必须使用反斜杠对它进行转义:OReilly。 这让我编写的这个 XSLT 样式表更为有趣了一些。我并未在本例中放上任何日期,但您也可以通过如下两种方法来编码日期。第一种方法是将日期作为字符串,该字符串必须在后面被解析。第二种方法是将日期作为一个对象,比如:p
43、ublishdate: new Date( 2006, 6, 16, 17, 45, 0 )这段代码将 publishdate 的值设置为6/16/2006 5:45:00 p.m.。简单编码接下来我将陆续介绍 JSON 编码的几种技巧。第一种也是其中最简单的一种,此样式表如 清单 3 所示。清单 3. simple.xsl 样式表 var g_books = 1, id: ,name: ,first: ,last: ,publisher: ;要理解此样式表,不妨先来看一下 清单 4 所示的输出。清单 4. simple.xsl 的输出var g_books = id: 1,name: Cod
44、e Generation in Action,first: Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: Herrington,publisher: OReilly;这里,我将名为 g_books 的变量设置为一个包含三个散列表的数组,每个散列表包含关于该书的信息。再回过头来看看 清单 3,您会发现第一个模板匹配 / 路径,
45、它也是首先应用到输入数据集的模板,该模板使用 for-each 循环来遍历每本书。之后,它使用 标记来将文本从该数据输出到 JavaScript 输出代码。对于字符串,我使用名为 js:escape() 的定制函数,它在模板之前定义。该函数使用一个正则表达式将一个单引号标记更改为带有反斜杠的单引号标记。最后一个重要的元素是 标记,它告知处理器要输出的是文本而不是 XML。要检验此过程是否可以正常工作,我加入了一个 simple .html 文件,该文件引用我在 simple.js 保存的 XSL 样式表的输出。这个 HTML 文件如 清单 5 所示。清单 5. simple.html 文件Si
46、mple JS loaderdocument.write( Found +g_books.length+ books );.html 文件使用 标记简单地加载已编码了的 JavaScript 代码。之后,第二个 标记将数组的长度写出到浏览器页面,如 图 1 所示。图 1. simple.html 的输出好了!数据文件包含三本书,相应的 JavaScript 文件也包含三本书。它真的可以工作!通过函数加载上述第一个示例很简单,而且在大多数情况下可以发挥其作用,但它存在一些问题。第一个问题是对于数据何时被加载没有任何提示。如果数据是像页面那样被静态加载的,这不成问题。但是如果页面动态创建了一个 标
47、记来按需加载数据,那么就很有必要知道 标记是何时完成的。实现此功能的最好的方法是让编码了的数据调用一个 JavaScript 函数,而不是只设置数据。这个概念很重要,所以我将花一些时间来介绍一下为什么您必须要通过动态生成的 标记来加载数据。页面加载后,从服务器获得数据是 Web 2.0 的核心功能。一种方法是使用 AJAX 机制通过到服务器的调用来加载 XML。然而,出于安全性的原因,AJAX 机制只限于从单一域获取数据。这在大多数情况下都没有问题,但有时,您可能需要 JavaScript 代码运行在他人的页面上(例如,Google Maps)。在这种情况下从服务器获得数据的惟一方法是通过动态
48、加载 标记。获悉 标记何时加载的最好的方法是让 标记返回的脚本调用函数而不是简单地加载数据。清单 6 显示了在函数调用中编码的数据。清单 6. Function1.jsAddBooks( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: H
49、errington,publisher: OReilly );清单 7 给出了相应的 .html 文件。清单 7. Function1.htmlFunction 1 JS loadervar g_books = ;function AddBooks( books ) g_books = books; drawbooks( g_books );稍后将详细介绍 drawbooks 函数。这里重要的是了解一下页面如何定义 AddBooks 函数,该函数随后会由 function1.js 文件中的脚本调用。该 AddBooks 函数负责处理数据。而且被调用的 AddBooks 函数会向页面指示 标记被
50、正确加载,并已加载完成。要创建 function1.js 文件,我只对样式表稍微做了一点修改,如 清单 8 所示。清单 8. function1.xsl 样式表AddBooks( 1, id: ,name: ,first: ,last: ,publisher: );这里,我调用了一个函数,而不是简单地设置一个变量。这就是我所做的惟一更改。回到页面,我使用了 drawbooks 函数来构建书的表格,这样我就能够确认数据被正确编码和正确显示。此函数是在 drawbooks.js 内定义的,如 清单 9 所示。清单 9. Drawbooks.jsfunction drawbooks( books )
51、 var elTable = document.createElement( table ); for( var b in books ) var elTR = elTable.insertRow( -1 ); var elTD1 = elTR.insertCell( -1 ); elTD1.appendChild( document.createTextNode( booksb.id ) ); var elTD2 = elTR.insertCell( -1 ); elTD2.appendChild( document.createTextNode( ) ); var
52、elTD3 = elTR.insertCell( -1 ); elTD3.appendChild( document.createTextNode( booksb.first ) ); var elTD4 = elTR.insertCell( -1 ); elTD4.appendChild( document.createTextNode( booksb.last ) ); var elTD5 = elTR.insertCell( -1 ); elTD5.appendChild( document.createTextNode( booksb.publisher ) ); document.b
53、ody.appendChild( elTable );这个简单函数创建了一个表格节点,然后循环访问书的列表并为每本书创建一行,为每个数据元素分配一个单元格。此页面上的代码的结果如 图 2 所示。图 2. function1.html 的结果现在我就可以查看一下此页面的输出并确认来自原始 .xml 文件的一切均已被正确转换成 JavaScript 代码,且数据被发送到 AddData 函数并被正确添加到页面。细化函数调用技术我很喜欢函数调用这一技术,但我并不赞同将所有图书数据都放入一个块中。另一种方式是为每条记录采用一个调用,如 清单 10 所示。清单 10. Function2.jsAddBo
54、ok( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning );AddBook( id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly );.对 .html 页面只需做少许修改,如 清单 11 所示。清单 11. Function2.html.var g_books = ;function AddBook( book ) g_books.push( book ); .这里更改了 XSLT,以
55、使函数调用驻留在 for-each 循环体内。清单 12 显示了更新后的样式表。清单 12. function2.xsl.AddBook( id: ,name: ,first: ,last: ,publisher: );.对这个给定示例来说,这种更改看起来有些随意。但如果原始的 XML 数据集有多种数据类型,要为每种类型分配一个单独的函数调用会使 XSL 和页面上的 JavaScript 代码更为简单、更易于维护。编码对象对小的页面来讲,使用 JavaScript 函数没有问题。但对于大型项目,就需要使用 JavaScript 语言的一些面向对象特性。是的,JavaScript 语言可以处理对象而且可以处理得很好。清单 13 显示了如何创建带有数据的对象。清单 13. Object1.jsg_books.push( new Book( id: 1,name: Code Generation in Action,fir
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年五金建材加盟协议
- 2025年分期家庭教育合同
- 《小岛失踪之谜》课件
- 2025年度绿色环保木材进口与销售合作合同范本大全4篇
- 二零二五年度冷链物流仓单质押贷款服务协议2篇
- 二零二五年度竞业禁止协议法律风险防控及合规咨询合同
- 二零二五年度商业地产地下车位销售及品牌推广协议
- 二零二五年度股份有限公司私下股份分配与公司战略协议书
- 二零二五版铝单板幕墙材料采购专项合同4篇
- 二零二五年度离婚协议中两个子女教育支持合同
- 玩具活动方案设计
- Q∕GDW 516-2010 500kV~1000kV 输电线路劣化悬式绝缘子检测规程
- 辽宁省抚顺五十中学2024届中考化学全真模拟试卷含解析
- 2024年湖南汽车工程职业学院单招职业技能测试题库及答案解析
- 家长心理健康教育知识讲座
- GB/T 292-2023滚动轴承角接触球轴承外形尺寸
- 2024年九省联考高考数学卷试题真题答案详解(精校打印)
- 军人结婚函调报告表
- 民用无人驾驶航空器实名制登记管理规定
- 北京地铁6号线
- 航空油料计量统计员(初级)理论考试复习题库大全-上(单选题汇总)
评论
0/150
提交评论