随笔-86  评论-767  文章-3  trackbacks-3

(续前一篇)AJAX开发简略

在前一篇文章《AJAX开发简略》中,我们讲述了如何用AJAX来改进设计的用户体验。接下来,我们将讲述如何用AJAX来更新文档,以及处理服务器返回的XML文档。我们的最终目的是接收服务器的返回信息,修改当前文档的内容。是时候让重要人物--DOM粉墨登场了。

7.4、文档对象模型(DOM

文档对象模型(DOM)是表示文档(比如HTMLXML)和访问、操作构成文档的各种元素的应用程序接口(API)。一般的,支持Javascript的所有浏览器都支持DOM。本文所涉及的DOM,是指W3C定义的标准的文档对象模型,它以树形结构表示HTMLXML文档,定义了遍历这个树和检查、修改树的节点的方法和属性。

7.4.1DOM眼中的HTML文档:树

DOM眼中,HTMLXML一样是一种树形结构的文档,<html>是根(root)节点,<head><title><body><html>的子(children)节点,互相之间是兄弟(sibling)节点;<body>下面才是子节点<table><span><p>等等。如下图:
HTML文档结构.jpg
    这个是不是跟
XML的结构有点相似呢。不同的是,HTML文档的树形主要包含表示元素、标记的节点和表示文本串的节点。

7.4.2HTML文档的节点

DOM下,HTML文档各个节点被视为各种类型的Node对象。每个Node对象都有自己的属性和方法,利用这些属性和方法可以遍历整个文档树。由于HTML文档的复杂性,DOM定义了nodeType来表示节点的类型。这里列出Node常用的几种节点类型:

接口

nodeType常量

nodeType

备注

Element

Node.ELEMENT_NODE

1

元素节点

Text

Node.TEXT_NODE

3

文本节点

Document

Node.DOCUMENT_NODE

9

document

Comment

Node.COMMENT_NODE

8

注释的文本

DocumentFragment

Node.DOCUMENT_FRAGMENT_NODE

11

document片断

Attr

Node.ATTRIBUTE_NODE

2

节点属性

DOM树的根节点是个Document对象,该对象的documentElement属性引用表示文档根元素的Element对象(对于HTML文档,这个就是<html>标记)。Javascript操作HTML文档的时候,document即指向整个文档,<body><table>等节点类型即为ElementComment类型的节点则是指文档的注释。具体节点类型的含义,请参考《Javascript权威指南》,在此不赘述。

Document定义的方法大多数是生产型方法,主要用于创建可以插入文档中的各种类型的节点。常用的Document方法有:

方法

描述

createAttribute()

用指定的名字创建新的Attr节点。

createComment()

用指定的字符串创建新的Comment节点。

createElement()

用指定的标记名创建新的Element节点。

createTextNode()

用指定的文本创建新的TextNode节点。

getElementById()

返回文档中具有指定id属性的Element节点。

getElementsByTagName()

返回文档中具有指定标记名的所有Element节点。

对于Element节点,可以通过调用getAttribute()setAttribute()removeAttribute()方法来查询、设置或者删除一个Element节点的性质,比如<table>标记的border属性。下面列出Element常用的属性:

属性

描述

tagName

元素的标记名称,比如<p>元素为PHTML文档返回的tabName均为大写。

Element常用的方法:

方法

描述

getAttribute()

以字符串形式返回指定属性的值。

getAttributeNode()

Attr节点的形式返回指定属性的值。

getElementsByTabName()

返回一个Node数组,包含具有指定标记名的所有Element节点的子孙节点,其顺序为在文档中出现的顺序。

hasAttribute()

如果该元素具有指定名字的属性,则返回true

removeAttribute()

从元素中删除指定的属性。

removeAttributeNode()

从元素的属性列表中删除指定的Attr节点。

setAttribute()

把指定的属性设置为指定的字符串值,如果该属性不存在则添加一个新属性。

setAttributeNode()

把指定的Attr节点添加到该元素的属性列表中。

Attr对象代表文档元素的属性,有namevalue等属性,可以通过Node接口的attributes属性或者调用Element接口的getAttributeNode()方法来获取。不过,在大多数情况下,使用Element元素属性的最简单方法是getAttribute()setAttribute()两个方法,而不是Attr对象。

7.4.3、使用DOM操作HTML文档

Node对象定义了一系列属性和方法,来方便遍历整个文档。用parentNode属性和childNodes[]数组可以在文档树中上下移动;通过遍历childNodes[]数组或者使用firstChildnextSibling属性进行循环操作,也可以使用lastChildpreviousSibling进行逆向循环操作,也可以枚举指定节点的子节点。而调用appendChild()insertBefore()removeChild()replaceChild()方法可以改变一个节点的子节点从而改变文档树。

需要指出的是,childNodes[]的值实际上是一个NodeList对象。因此,可以通过遍历childNodes[]数组的每个元素,来枚举一个给定节点的所有子节点;通过递归,可以枚举树中的所有节点。下表列出了Node对象的一些常用属性和方法:

Node对象常用属性:

属性

描述

attributes

如果该节点是一个Element,则以NamedNodeMap形式返回该元素的属性。

childNodes

Node[]的形式存放当前节点的子节点。如果没有子节点,则返回空数组。

firstChild

Node的形式返回当前节点的第一个子节点。如果没有子节点,则为null

lastChild

Node的形式返回当前节点的最后一个子节点。如果没有子节点,则为null

nextSibling

Node的形式返回当前节点的兄弟下一个节点。如果没有这样的节点,则返回null

nodeName

节点的名字,Element节点则代表Element的标记名称。

nodeType

代表节点的类型。

parentNode

Node的形式返回当前节点的父节点。如果没有父节点,则为null

previousSibling

Node的形式返回紧挨当前节点、位于它之前的兄弟节点。如果没有这样的节点,则返回null

Node对象常用方法:

方法

描述

appendChild()

通过把一个节点增加到当前节点的childNodes[]组,给文档树增加节点。

cloneNode()

复制当前节点,或者复制当前节点以及它的所有子孙节点。

hasChildNodes()

如果当前节点拥有子节点,则将返回true

insertBefore()

给文档树插入一个节点,位置在当前节点的指定子节点之前。如果该节点已经存在,则删除之再插入到它的位置。

removeChild()

从文档树中删除并返回指定的子节点。

replaceChild()

从文档树中删除并返回指定的子节点,用另一个节点替换它。

接下来,让我们使用上述的DOM应用编程接口,来试着操作HTML文档。

A、遍历文档的节点

DOM把一个HTML文档视为树,因此,遍历整个树是应该是家常便饭。跟之前说过的一样,这里我们提供两个遍历树的例子。通过它,我们能够学会如何使用childNodes[]firstChilelastChildnextSiblingpreviousSibling遍历整棵树。

例子1-- sample3_1.htm

这个例子使用了childNodes[]和递归方式来遍历整个文档,统计文档中出现的Element元素总数,并把Element标记名全部打印出来。需要特别注意的是,在使用DOM时,必须等文档被装载完毕再执行遍历等行为操作文档。sample3_1.htm具体代码如下:

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

var elementName = ""; //全局变量,保存Element标记名,使用完毕要清空

function countTotalElement(node) { //参数node是一个Node对象

       var total = 0;

       if(node.nodeType == 1) { //检查node是否为Element对象

              total++;                 //如果是,计数器加1

              elementName = elementName + node.tagName + "\r\n"; //保存标记名

       }

       var childrens = node.childNodes;         //获取node的全部子节点

       for(var i=0;i<childrens.length;i++) {

              total += countTotalElement(childrens[i]); //在每个子节点上进行递归操作

       }

       return total;

}

</script>

</head>

<body>

<a href="javascript:void(0)"

onClick="alert('标记总数:' + countTotalElement(document) + '\r\n全部标记如下:\r\n' + elementName);elementName='';">开始统计</a>

</body>

</html>

运行效果如下:

遍历文档_1.jpg遍历文档_2.jpg               

例子2 – sample3_2.htm

接下来使用firstChilelastChildnextSiblingpreviousSibling遍历整个文档树。修改一下countTotalElement函数,其他跟sample3_1.htm一样:

function countTotalElement(node) { //参数node是一个Node对象

       var total = 0;

       if(node.nodeType == 1) { //检查node是否为Element对象

              total++;                 //如果是,计数器加1

              elementName = elementName + node.tagName + "\r\n"; //保存标记名

       }

       var childrens = node.childNodes;         //获取node的全部子节点

       for(var m=node.firstChild; m!=null;m=m.nextSibling) {

              total += countTotalElement(m); //在每个子节点上进行递归操作

       }

       return total;

}

B、搜索文档中特定的元素

在使用DOM的过程中,有时候需要定位到文档中的某个特定节点,或者具有特定类型的节点列表。这种情况下,可以调用Document对象的getElementsByTagName()getElementById()方法来实现。

document.getElementsByTagName()返回文档中具有指定标记名的全部Element节点数组(也是NodeList类型)。Element出现在数组中的顺序就是他们在文档中出现的顺序。传递给getElementsByTagName()的参数忽略大小写。比如,想定位到第一个<table>标记,可以这样写:document.getElementsByTagName(“table”)[0]。例外的,可以使用document.body定位到<body>标记,因为它是唯一的。

getElementsByTagName()返回的数组取决于文档。一旦文档改变,返回结果也立即改变。相比,getElementById()则比较灵活,可以随时定位到目标,只是要实现给目标元素一个唯一的id属性值。这个我们在《AJAX开发简略》的“级联菜单”例子中已经使用过了。

Element对象也支持getElementsByTagName()getElementById()。不同的是,搜索领域只针对调用者的子节点。

C、修改文档内容

遍历整棵文档树、搜索特定的节点,我们最终目的之一是要修改文档内容。接下来的三个例子将使用Node的几个常用方法,来演示如何修改文档内容。

例子3 -- sample4_1.htm

这个例子包含三个文本节点和一个按钮。点击按钮后,三个文本节点和按钮的顺序将被颠倒。程序使用了NodeappendChild()removeChild()方法。

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

       function reverseNode(node) { // 颠倒节点node的顺序

              var kids = node.childNodes; //获取子节点列表

              var kidsNum = kids.length; //统计子节点总数

              for(var i=kidsNum-1;i>=0;i--) { //逆向遍历子节点列表

                     var c = node.removeChild(kids[i]); //删除指定子节点,保存在c

                     node.appendChild(c); //c放在新位置上

              }

       }

</script>

</head>

<body>

<p>第一行</p>

<p>第二行</p>

<p>第三行</p>

<p><input type="button" name="reverseGo" value="颠倒"

onClick="reverseNode(document.body)"></p>

</body>

</html>

修改文档_1.jpg修改文档_2.jpg             

例子4-- sample4_2.htm

例子1通过直接操作body的子节点来修改文档。在HTML文档中,布局和定位常常通过表格<table>来实现。因此,例子4将演示操作表格内容,将表格的四个单元行顺序颠倒。如果没有使用<tbody>标签,则<table>把全部的<tr>当做是属于一个子节点<tbody>,所以我们采用数组缓存的方式,把行数据颠倒一下。这个例子同时也演示了如何使用DOM创建表格单元行。

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

function reverseTable() {

       var node = document.getElementsByTagName("table")[0]; //第一个表格

       var child = node.getElementsByTagName("tr"); //取得表格内的所有行

       var newChild = new Array(); //定义缓存数组,保存行内容

       for(var i=0;i<child.length;i++) {

              newChild[i] = child[i].firstChild.innerHTML;

       }

       node.removeChild(node.childNodes[0]); //删除全部单元行

       var header = node.createTHead(); //新建表格行头

       for(var i=0;i<newChild.length;i++) {

              var headerrow = header.insertRow(i); //插入一个单元行

              var cell = headerrow.insertCell(0); //在单元行中插入一个单元格

              //在单元格中创建TextNode节点

              cell.appendChild(document.createTextNode(newChild[newChild.length-i-1]));

       }

}

</script>

</head>

<body>

<table width="200" border="1" cellpadding="4" cellspacing="0">

    <tr>

        <td height="25">第一行</td>

    </tr>

    <tr>

        <td height="25">第二行</td>

    </tr>

    <tr>

        <td height="25">第三行</td>

    </tr>

    <tr>

        <td height="25">第四行</td>

    </tr>

</table>

<br>

<input type="button" name="reverse" value="开始颠倒" onClick="reverseTable()">

</body>

</html>

     修改文档_3.jpg修改文档_4.jpg

例子5 -- sample4_3.htm

正如我们在Node节点介绍部分所指出的那样,appendChild()replaceChild()removeChild()insertBefore()方法会立即改变文档的结构。下面的例子包含两个表格,我们试着把表格二的内容替换表格一的内容。

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

function replaceContent() {

       var table1 = document.getElementsByTagName("table")[0];

       var table2 = document.getElementsByTagName("table")[1];

       var kid1 = table1.firstChild.firstChild.firstChild; //定位到<td>节点

       var kid2 = table2.firstChild.firstChild.firstChild; //定位到<td>节点

       var repKid = kid2.firstChild; //定位到表格二<td>内含的TextNode节点

       try {

              //用表格二的单元格内容替换表格一的单元格内容,表格二变成没有单元格内容

              kid1.replaceChild(repKid,kid1.firstChild);

              //下面注释如果开放,将出现object error,因为表格二已经被改变

              //kid2.replaceChild(kid1.firstChild,kid2.firstChild);

       }catch(e){

              alert(e);

       }

}

</script>

</head>

<body>

<table width="200" border="1" cellspacing="0" cellpadding="0">

<tbody>

    <tr>

        <td>表格一</td>

    </tr>

</tbody>

</table>

<br>

<table width="200" border="1" cellspacing="0" cellpadding="0">

<tbody>

    <tr>

        <td>表格二</td>

    </tr>

</tbody>

</table>

<br>

<input type="button" name="replaceNode" value="替换" onClick="replaceContent()">

</body>

</html>

     修改文档_5.jpg修改文档_6.jpg

注意,当执行kid1.replaceChild(repKid,kid1.firstChild);的时候,table2的子节点已经被转移到table1了,table2已经没有子节点,不能再调用table2的子节点。看看代码的注释,试着运行一下,应该就知道文档是怎么改变的了。

D、往文档添加新内容

在学会遍历、搜索、修改文档之后,我们现在试着网文档添加新的内容。其实没有什么新意,只是利用我们上述提到的Node的属性和方法而已,还是操作<table>标记的内容。有新意的是,我们要实现一个留言簿。是的,留言簿,你可以往里面留言,只是不能刷新噢。

例子6 – sample5_1.htm

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

function insertStr() {

       var f = document.form1;

       var value = f.str.value;

       if(value!="") {

              // 从最终的TextNode节点开始,慢慢形成<tbody>结构

              var text = document.createTextNode(value); //新建一个TextNode节点

              var td = document.createElement("td"); //新建一个td类型的Element节点

              var tr = document.createElement("tr"); //新建一个tr类型的Element节点

              var tbody = document.createElement("tbody"); //新建一个tbody类型的Element节点

              td.appendChild(text); //将节点text加入td

              tr.appendChild(td); //将节点td加入tr

              tbody.appendChild(tr); //将节点tr加入tbody

              var parNode = document.getElementById("table1"); //定位到table

              parNode.insertBefore(tbody,parNode.firstChild); //将节点tbody插入到节点顶部

              //parNode.appendChild(tbody); //将节点tbody加入节点尾部

       }

}

</script>

</head>

<body>

<form name="form1" method="post" action="">

    <input name="str" type="text" id="str" value="">

    <input name="insert" type="button" id="insert" value="留言" onClick="insertStr()">

</form>

<table width="400" border="1" cellspacing="0" cellpadding="0" id="table1">

<tbody>

    <tr>

        <td height="25">网友留言列表:</td>

    </tr>

</tbody>

</table>

</body>

</html>

我们之前说过,<table>的子节点是<tbody><tbody>的子节点才是<tr><tr><td>的父节点,最后<td>内部的TextNode节点。所以,往<table>增加单元格行要逐级形成,就像往树里面添加一个枝桠一样,要有叶子有径。看看,这个留言簿是不是很简单啊。这个例子同时也演示了往<table>表格标记里面增加内容的另一种方法。

添加文档内容_1.jpg添加文档内容_2.jpg
E
、使用DOM操作XML文档

在数据表示方面,XML文档更加结构化。DOM在支持HTML的基础上提供了一系列的API,支持针对XML的访问和操作。利用这些API,我们可以从XML中提取信息,动态的创建这些信息的HTML呈现文档。处理XML文档,通常遵循“加载XML文档à提取信息à加工信息à创建HTML文档”的过程。下面的例子演示了如何加载并处理XML文档。

这个例子包含两个JS函数。loadXML()负责加载XML文档,其中既包含加载XML文档的2DOM代码,又有实现同样操作的Microsoft专有API代码。需要提醒注意的是,文档加载过程不是瞬间完成的,所以对loadXML()的调用将在加载文档完成之前返回。因此,需要传递给loadXML()一个引用,以便文档加载完成后调用。

例子中的另外一个函数makeTable(),则在XML文档加载完毕之后,使用最后前介绍过的DOM应用编程接口读取XML文档信息,并利用这些信息形成一个新的table表格。

例子7 -- sample6_1.htm

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

function loadXML(handler) {

       var url = "employees.xml";

       if(document.implementation&&document.implementation.createDocument) {

              var xmldoc = document.implementation.createDocument("", "", null);

              xmldoc.onload =  handler(xmldoc, url);

              xmldoc.load(url);

       }

       else if(window.ActiveXObject) {

              var xmldoc = new ActiveXObject("Microsoft.XMLDOM");

              xmldoc.onreadystatechange = function() {

                     if(xmldoc.readyState == 4) handler(xmldoc, url);

              }

              xmldoc.load(url);

       }

}

function makeTable(xmldoc, url) {

       var table = document.createElement("table");

       table.setAttribute("border","1");

       table.setAttribute("width","600");

       table.setAttribute("class","tab-content");

       document.body.appendChild(table);

       var caption = "Employee Data from " + url;

       table.createCaption().appendChild(document.createTextNode(caption));

       var header = table.createTHead();

       var headerrow = header.insertRow(0);

       headerrow.insertCell(0).appendChild(document.createTextNode("姓名"));

       headerrow.insertCell(1).appendChild(document.createTextNode("职业"));

       headerrow.insertCell(2).appendChild(document.createTextNode("工资"));

       var employees = xmldoc.getElementsByTagName("employee");

       for(var i=0;i<employees.length;i++) {

              var e = employees[i];

              var name = e.getAttribute("name");

              var job = e.getElementsByTagName("job")[0].firstChild.data;

              var salary = e.getElementsByTagName("salary")[0].firstChild.data;

              var row = table.insertRow(i+1);

              row.insertCell(0).appendChild(document.createTextNode(name));

              row.insertCell(1).appendChild(document.createTextNode(job));

              row.insertCell(2).appendChild(document.createTextNode(salary));

       }

}

</script>

<link href="css/style.css" rel="stylesheet" type="text/css">

</head>

 

<body onLoad="loadXML(makeTable)">

</body>

</html>

供读取调用的XML文档 – employees.xml

<?xml version="1.0" encoding="gb2312"?>

<employees>

       <employee name="J.Doe">

              <job>Programmer</job>

              <salary>32768</salary>

       </employee>

       <employee name="A.Baker">

              <job>Sales</job>

              <salary>70000</salary>

       </employee>

       <employee name="Big Cheese">

              <job>CEO</job>

              <salary>100000</salary>

       </employee>

</employees>

操作XML文档.jpg
7.5
、处理XML文档

脱离XML文档的AJAX是不完整的。在本部分未完成之前,有读者说AJAX改名叫AJAHH应该代表HTML吧)比较合适。应该承认,XML文档在数据的结构化表示以及接口对接上有先天的优势,但也不是所有的数据都应该用XML表示。有些时候单纯的文本表示可能会更合适。下面先举个AJAX处理返回XML文档的例子再讨论什么时候使用XML

7.5.1、处理返回的XML

例子8 -- sample7_1.htm

在这个例子中,我们采用之前确定的AJAX开发框架,稍微修改一下body内容和processRequest的相应方式,将先前的employees.xml的内容读取出来并显示。

body的内容如下:

<input type="button" name="read"

 value="读取XML" onClick="send_request('employees.xml')">

processRequest()方法修改如下:

       // 处理返回信息的函数

    function processRequest() {

        if (http_request.readyState == 4) { // 判断对象状态

            if (http_request.status == 200) { // 信息已经成功返回,开始处理信息

                            var returnObj = http_request.responseXML;

                            var xmlobj = http_request.responseXML;

                            var employees = xmlobj.getElementsByTagName("employee");

                            var feedbackStr = "";

                            for(var i=0;i<employees.length;i++) { // 循环读取employees.xml的内容

                                   var employee = employees[i];

                                   feedbackStr += "员工:" + employee.getAttribute("name");

                                   feedbackStr +=

" 职位:" + employee.getElementsByTagName("job")[0].firstChild.data;

                                   feedbackStr +=

 " 工资:" + employee.getElementsByTagName("salary")[0].firstChild.data;

                                   feedbackStr +=  "\r\n";

                            }

                            alert(feedbackStr);

            } else { //页面不正常

                alert("您所请求的页面有异常。");

            }

        }

}

运行一下,看来效果还不错:
处理返回的xml.jpg

7.5.2、选择合适的XML生成方式

现在的web应用程序往往采用了MVC三层剥离的设计方式。XML作为一种数据保存、呈现、交互的文档,其数据往往是动态生成的,通常由JavaBean转换过来。由JavaBean转换成XML文档的方式有好几种,选择合适的转换方式往往能达到事半功倍的效果。下面介绍两种常用的方式,以便需要的时候根据情况取舍。

A、类自行序列化成XML

类自行序列化成XML即每个类都实现自己的toXML()方法,选择合适的API、适当的XML结构、尽量便捷的生成逻辑快速生成相应的XML文档。显然,这种方式必须要求每个类编写专门的XML生成代码,每个类只能调用自己的toXML()方法。应用诸如JDOM等一些现成的API,可以减少不少开发投入。例子9是一个利用JDOMAPI形成的toXML()方法。

例子9 -- toXml() JDOM 实现 -- Employ类的toXml()方法:

public Element toXml() { 

       Element employee = new Element(“employee”);

       Employee.setAttribute(“name”,name);

       Element jobE = new Element(“job”).addContent(job);

       employee.setContent(jobE);

       Element salaryE = new Element(“salary”).addContent(salary);

       employee.setContent(salaryE);

       return employee;

}

JDOM提供了现成的API,使得序列化成XML的工作更加简单,我们只需要把toXML()外面包装一个Document,然后使用XMLOutputter把文档写入servlet就可以了。toXml()允许递归调用其子类的toXML()方法,以便生成包含子图的XML文档。

       使用类自行序列化成XML的方式,要每个类都实现自己的toXML()方法,而且存在数据模型与视图耦合的问题,即要么为每个可能的视图编写独立的toXML()方法,要么心甘情愿接收冗余的数据,一旦数据结构或者文档发生改变,toXML()就要做必要的修改。

B、页面模板生成XML方式

一般的,可以采用通用的页面模板技术来生成XML文档,这个XML文档可以符合任何需要的数据模型,供AJAX灵活的调用。另外,模板可以采用任何标记语言编写,提高工作效率。下面是一个采用Struts标签库编写的XML文档,输出之前提到的employees.xml

Sample8_2.jsp

<%@ page contentType="application/xml; charset=gb2312" import="Employee"%>

<%@ page import="java.util.Collection,java.util.ArrayList"%>

<?xml version="1.0"?>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>

<%

Employee em1 = new Employee();

em1.setName("J.Doe");

em1.setJob("Programmer");

em1.setSalary("32768");

Employee em2 = new Employee();

em2.setName("A.Baker");

em2.setJob("Sales");

em2.setSalary("70000");

Employee em3 = new Employee();

em3.setName("Big Cheese");

em3.setJob("CEO");

em3.setSalary("100000");

Collection employees = new ArrayList();

employees.add(em1);

employees.add(em2);

employees.add(em3);

pageContext.setAttribute("employees",employees);

%>

<employees>

<logic:iterate name="employees" id="employee">

       <employee name="<bean:write name='employee' property='name'/>">

              <job><bean:write name="employee" property="job"/></job>

              <salary><bean:write name="employee" property="salary"/></salary>

       </employee>

</logic:iterate>

</employees>

页面模板生成XML.jpg
采用页面模板生成
XML方式,需要为每个需要的的数据模型建立一个对立的JSP文件,用来生成符合规范的XML文档,而不能仅仅在类的toXML()方法中组织对象图来实现。不过,倒是可以更加方便的确保标记匹配、元素和属性的顺序正确以及XML实体正确转义。

参考资料中Philip McCarthy的文章还描述了一种Javascript对象标注的生成方式,本文在此不赘述。有兴趣的读者可以自行查看了解。

7.5.3、如何在使用XML还是普通文本间权衡

使用XML文档确实有其方便之处。不过XML文档的某些问题倒是要考虑一下,比如说延迟,即服务器不能立即解析XML文档成为DOM模型。这个问题在一定程度上会影响AJAX要求的快速反应能力。另外,某些情况下我们并不需要使用XML来表示数据,比如说数据足够简单成只有一个字符串而已。就好像我们之前提到的数据校验和级联菜单的例子一样。所以,个人认为在下面这些情况下可以考虑使用XML来作为数据表示的介质:

l         数据比较复杂,需要用XML的结构化方式来表示

l         不用考虑带宽和处理效率支出

l         与系统其他API或者其他系统交互,作为一种数据中转中介

l         需要特定各式的输出视图而文本无法表示的

总之,要认真评估两种表示方式的表示成本和效率,选择合适的合理的表示方式。

在关于AJAX的系列文章的下一篇,我们将综合使用DOMXML,来实现一个可以持久化的简单留言簿。另外,还将试着模拟MSN Space的部分功能,来体会AJAX的魅力。

参考文章:

作者:

Philip McCarthy

标题:

面向Java开发人员的Ajax:构建动态的Java应用程序

网址:

http://kb.csdn.net/java/Articles/200510/bed0423e-5297-49c9-9464-0e3eb733c8b5.html

作者:

Philip McCarthy

标题:

面向Java开发人员的Ajax:AjaxJava对象序列化

网址:

http://kb.csdn.net/java/Articles/200510/a5b630cf-a2c2-46f1-8e3b-eadde723e734.html

作者:

David Flanagan

书名:

Javascript权威指南》

网址:

 

作者:

 

标题:

 

网址:

http://www.bstek.com/product.asp

 

posted on 2005-11-07 13:47 eamoi 阅读(10726) 评论(71)  编辑  收藏 所属分类: AJAX

评论:
# 我补充一下吧 2005-11-08 13:34 | emu
7.5.3、如何在使用XML还是普通文本间权衡

>> 数据比较复杂,需要用XML的结构化方式来表示
数据结构复杂的时候xml当然适用,但是自己设计的专用的文本表达方式很容易做的比它还更有针对性,更高效。我们推荐适用xml来表现,是因为它更通用,在各种场合下都更容易获得支持,而不只是因为他的表达能力更强。

>>不用靠拢带宽和处理效率支出。
这是不可以泛泛而论的。不知eamoi为何认为xml更占用带宽和cpu呢。其实有分析过它占了多少吗,在哪些情形下xml会成为瓶颈呢?

>>与系统其他API或者其他系统交互,作为一种数据中转中介。
如果没记错的话我们是在讲ajax吧,或者eamoi在讲的是ajax+soap 或 ajax+xmlrpc?

>>需要特定各式的输出视图而文本无法表示的
呵呵,xml也是文本啊,没有什么东西是xml能表现二其他文本形式无法表现的。如果要进行针对性的设计的话很容易为不同的应用场合量身定做一套更好用更高效的文本表达形式,缺点在于不通用。

在我看来eamoi并不很明白xml的优势所在。

我认为xml被广泛的用来作为各种系统之间的标准借口,是因为它是一种简洁的自描述的标记语言,能够用纯文本流的形式来表现各种复杂的数据和他们之间的层次关系,并且在各种平台下都很容易构造和分析。我推行真正的AJAX而不是AJAH,是因为这样前后台可以在XML这样一个标准上面很容易的建立借口,沟通数据,提高开发效率。同时xml很容易被检验,我们也提高了可测试性因而提高了开发质量;规范的xml数据源很容易被重用,我们往往也可以提高代码重用度;而且xml数据可以被浏览器非常好的cache,在重用xml数据源的时候我们也可以有效的降低带宽上的代价。这些在我最近的AJAX开发实践中都得到了很好的体现。

用dom形式解析使用xml数据的一个难点在于跨浏览器的实现(http://sourceforge.net/projects/goog-ajaxslt/ 可能是google对此一个响亮的回答呵呵),我认为跨浏览器是gmail使用AJAH的一个主要考虑,但是不幸的是gmail居然成为了AJAX的经典案例,大家也就以为AJAX本来就应该用AJAH的形式来体现了。
  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-08 14:41 | eamoi
谢谢emu的补充。

对于如何在文本和XML之前权衡,我对第一点有比较深的体会和认同。
在目前情况下,带宽和效率已经不是太大的问题,所以会慢慢忽略。只是AJAX对于XML文档的解析是在客户端完成的,所以还是要兼顾一下。

目前的案例经验没能让我将XML与其他做特别大的效果对比,所以这方面emu可以多补充一点。

随着大家的反馈,我也会对文章进行相应的改善;也会把大家的意见整合进稍后的文章中。

希望大家一起探讨,一起进步。  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-08 15:27 | emu
我的问题在于,我做的AJAX应用还不够好,甚至无法跨浏览器。在AJAH如此倍受推崇的今天要跳出来卖自己唱反调,是要有点额外的底气的。如果手里的项目到时有时间可以重构的话,我看看能不能用google-ajaxslt重做一次表现层。
  回复  更多评论
  
# 【原创】AJAX开发简略续一 [TrackBack] 2005-11-16 14:06 | bjbs_270
(续前一篇)AJAX开发简略

在前一篇文章《AJAX开发简略》中,我们讲述了如何用AJAX来改进设计的用户体验。接下来,我们将讲述如何用AJAX来更新文档,以及处理服务器返回的XML文档。我们的最终目的是接收服务器的返回信息,修改当前文档的内容。是时候让重要人物--DOM粉墨登场了。

7.4、文档对象模型(DOM)

文档对象模型(DOM)是表示文档(比如HTML和XML)和访问、操作构成文档的各种元素的应用程序接口(API)。一般的,支持Javascript的所有浏览器都支持DOM。本文所涉及的DOM,是指W3C定义的标准的文档对象模型,它以树形结构表示HTML和XML文档,定义了遍历这个树和检查、修改树的节点的方法和属性。...
[引用提示]bjbs_270引用了该文章, 地址: http://blog.csdn.net/bjbs_270/archive/2005/11/16/530736.aspx  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-22 10:00 | llinzzi
追随ajax到你这里,追随你到了你发表帖子的任何地方,好.两片简略让我学会了太多东西,不知道简略二什么时候出?  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-22 10:55 | eamoi
续二已经排在计划中,但是没有确切的时间期限。
什么时候心中的想法足够整理成文,自然会写出来。目前正在进行相应的准备。  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-22 19:43 | llinzzi
每天上来等待你的续篇  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-23 18:10 | llinzzi
提供的例子我都试验了,以为我是用的一直是asp,所有就把服务器端的用asp改写了,但我经过xmlhttp返回去的汉字都变成了乱码,而英文没有问题,不知道为什么jsp没有乱麻,想起来以前和xmlhttp技术相关的asp小偷程序,都是用
Function BytesToBstr(body,Cset)
dim objstream

set objstream = Server.CreateObject("adodb.stream")

objstream.Type = 1

objstream.Mode = 3

objstream.Open

objstream.Write body

objstream.Position = 0

objstream.Type = 2

objstream.Charset = Cset

BytesToBstr = objstream.ReadText

objstream.Close

set objstream = nothing
End Function
这个函数将字符转化成gb2312的,以前都是在服务器端运行的,在客户端该怎么改呢?而且还要改成js,搞了一下午也没搞出来,麻烦给看看,为什么asp要这么麻烦,而jsp就不用呢?郁闷  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-11-23 18:14 | llinzzi
我对ajax技术非常的不了解,看了你的两篇文章才让我如了门,今天结合了你的例子写了点东西.
2.asp
<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<title>无标题文档</title>

<script language="javascript">

function loadwait() { // 等待数据中的显示
var fchild = document.body.firstChild; //定位
var text1 = document.createTextNode("Loading......");
document.body.replaceChild(text1,fchild);

}

function loadready(html) { // 数据准备好后开始的操作
var fchild = document.body.firstChild; //定位
var text2 = document.createTextNode(html);
var fe = document.createElement("font"); //新建一个font类型的Element节点
fe.appendChild(text2); //将节点text加入td中
fe.setAttribute("color","red");
fe.setAttribute("size","15 pix");
document.body.replaceChild(fe,fchild);


}

var http_request = false;
function send_request(url) {//初始化、指定处理函数、发送请求的函数
http_request = false;
//开始初始化XMLHttpRequest对象
if(window.XMLHttpRequest) { //Mozilla 浏览器
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {//设置MiME类别
http_request.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject) { // IE浏览器
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) { // 异常,创建对象实例失败
window.alert("不能创建XMLHttpRequest对象实例.");
return false;
}
http_request.onreadystatechange = processRequest;
// 确定发送请求的方式和URL以及是否同步执行下段代码
http_request.open("GET", url, true);
http_request.send(null);
}
// 处理返回信息的函数
function processRequest() {
if (http_request.readyState == 4) { // 判断对象状态
if (http_request.status == 200) {
loadbody=http_request.responseText;
// 信息已经成功返回,开始处理信息
loadready(loadbody);
} else { //页面不正常
alert("您所请求的页面有异常。");
}
}
else
{
loadwait();
}
}

</script>

</head>

<body>

<p>&nbsp;</p>
<script>send_request("3.asp")</script>
</body>

</html>

3.asp
<% lintext="Hello" %>
<% response.Write(lintext) %>  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-12-02 09:11 | firmy
http_request.responseText 这里的中文会得到乱码?我在网上查了一下,都遇到这种问题,也不知道你是怎么解决的?  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-12-02 10:13 | eamoi
通过responseText返回的普通文本,我测试的过程中没有出现乱码的情况。我采用的是JSP,文件头部加注<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>。

但是通过responseXML返回的文档,中文会出现乱码。这个现在我也不知道如何解决。不知道采用UTF-8编码会不会有改善。  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-12-05 09:38 | llinzzi
这个问题,都是用一个函数转化了编码,不过这个函数是在服务端运行的,asp代码,不知道在客户端怎么修改,用这个函数可以解决text和xml的乱麻问题,eamoi可以帮忙看一下如何修改成客户端代码么?函数如下
Function BytesToBstr(body,Cset)
dim objstream

set objstream = Server.CreateObject("adodb.stream")

objstream.Type = 1

objstream.Mode = 3

objstream.Open

objstream.Write body

objstream.Position = 0

objstream.Type = 2

objstream.Charset = Cset

BytesToBstr = objstream.ReadText

objstream.Close

set objstream = nothing
End Function
  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2005-12-05 10:47 | eamoi
上周试验AJax控制下的form提交功能,提交后后台获取数据出现乱码。查了相关资料,结论是form提交过程中经过了application/x-www-form-urlencoded编码。现在准备试验一下如何解码。好像Java是可以做到的。加紧动作中......

另外,针对乱码问题,我开个topic吧,集中到这个topic讨论吧,大家看看有没有什么比较好的解决方法。有各网友发邮件说已经解决了,我正在等待他的回复。  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-01-12 09:35 | ff
很好的简略。。我转到ajax.net.cn了。谢谢!  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-05-25 10:26 | sa
不错,3ku  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-06-05 22:09 | 香乡
您好!我也是跟着您的书来到这里。
我一直在想一个问题。。。。
AJAX是结合多种技术于一体的平台,可以用它实现很多功能。能不能把它和POWERBUILDER等(如VB,DELPHI)工具也有很好的结合呢?  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-06-05 22:25 | 香乡
不好意思,没说完帖子自动提交了,呵呵。。。我继续说吧!

我用PB这个工具很多年了,呵呵,从1998年的PB4.0到PB10.0。
我知道PB有一个PBSITE的,(我个人认为与TOMCATE)也差不多。PB是专门用于C/S结构程序设计的工具,而且是客户端开发工具,作品直接在客户端运行,不需要给服务器端安装特别工具(除非产品比较特殊)。后来它拓展了B/S方面技术,包括可以将EAS集成,并可以用做C/S的方式去做网页(做HTML非常快)。 它还可以直接把数据转换成XML或者HTML格式(直接用SAVEAS函数就可以了),可以构建在IE下直接弹出自定义的WINDOWS类窗口等。可以把企业很复杂的应用快速的搬到IE上实现。

同时,我也发现了它做的B/S产品的局限性:它需要在IE浏览端安装自己的驱动引擎,类似联众、QQ游戏那样,需要先安装,才能运行。同时,我估计可能对OS的适应性也不是很好。我还发现,用它做的工具,似乎是把一个打开窗口分成了--IE解释命令--找到MIMA驱动并转载--根据PB的驱动,执行我设计的具体业务。这种方式似乎把一个简单的操作在网络上转了好几圈才在应用服务器上被执行。我想AJAX应该能相对好些是么?可惜我刚刚开始学习B/S方面的程序设计,很多东西都不太懂。

我也是在看了您的ALAX后,得到启发,察看了相关的文件才发现的。刚刚开始学习,还有很多不懂的地方,但是很感谢您,让我学了不少。
  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-06-05 22:58 | 香乡
我一直很羡慕QQ版本里有一个功能,可以通过双方验证后,我能看到朋友的机器界面,并能直接操作他的机器。但是我不知道这个工作到底是怎么实现的,所以想请教您。
我的联系方式QQ:53542888。  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2006-06-06 09:18 | eamoi
我对PB不熟悉,故关于PB与Ajax的关系问题无法给予,请见谅。不过到是没想到Ajax怎么与PB结合。
至于类似QQ的共享桌面功能,好像不应该是Web程序能做到的。  回复  更多评论
  
# re: [重要新功能]留言簿 2007-05-22 14:37 | 加林
[url=http://www.kamson.cn]超声波清洗机[/url]
[url=http://www.88qy.com/]北京翻译公司[/url]
[url=http://www.freegou.com]货架[/url]
[url=http://www.adwords.org.cn]虚拟主机[/url]
[url=http://www.cntyj.com]投影机[/url]
[url=http://www.tingjiao.com]上海翻译公司[/url]
[url=http://www.upspower.net.cn]ups电源[/url]
[url=http://a8cq.com]振动筛[/url]
[url=http://www.shuxiang.com.cn]移民[/url]
[url=http://www.cnsd.com.cn]服务器[/url]
[url=http://www.98825.com]数据恢复[/url]
[url=http://www.chaoshengbo.net.cn]超声波[/url]
[url=http://www.jiajuworld.com]医药招商[/url]
[url=http://www.china-csb.com]超声波[/url]
[url=http://www.projector9.com]投影机[/url]
[url=http://www.projector8.cn]投影机[/url]
[url=http://www.topcod.com.cn]干燥剂[/url]
[url=http://www.a8woool.com/]净化工程[/url]
[url=http://www.ji-xie.com]皮革机械[/url]
[url=http://www.tiaoau.com]浴缸[/url]
[url=http://www.ledshow.com.cn]led显示屏[/url]
[url=http://www.freecq.com]记录仪[/url]
[url=http://www.customsdata.net]海关数据[/url]
[url=http://www.fsst.cn/google_ranking_service.htm]google推广[/url]  回复  更多评论
  
# re: 【原创】AJAX开发简略续一[未登录] 2007-12-21 09:13 | 随风
We offer WoW Power Leveling and World of Warcraft powerleveling,Final Fantasy XI Gil,Maple Story and Lord fo Ring Online Powerleveling.WoW Powerleveling service and cheap wow Powerleveling,World of Warcraft Power leveling sale for you. WOW Power leveling,Cheap WOW Powerleveling 1-60 and Cheap WOW Powerleveling 1 - 70.All service is faster,safer,and cheaper.WOW Powerleveling 1 - 60,WOW Powerleveling 1 - 70.Lord fo Ring Online Power Leveling 1-50 .We Please remember,we are your online game helper.
http://www.pvpsale.com/World-of-Warcraft-US.asp
http://www.pvpsale.com/World-of-Warcraft-US-Powerleveling.asp  回复  更多评论
  
# re: 【原创】AJAX开发简略续一[未登录] 2007-12-22 10:02 | 随风

We offer WoW Power Leveling and World of Warcraft powerleveling,Final Fantasy XI Gil,Maple Story and Lord fo Ring Online Powerleveling.WoW Powerleveling service and cheap wow Powerleveling,World of Warcraft Power leveling sale for you. WOW Power leveling,Cheap WOW Powerleveling 1-60 and Cheap WOW Powerleveling 1 - 70.All service is faster,safer,and cheaper.WOW Powerleveling 1 - 60,WOW Powerleveling 1 - 70.Lord fo Ring Online Power Leveling 1-50 .We Please remember,we are your online game helper.
www.pvpsale.com
www.pvpsale.com/powerleveling.asp  回复  更多评论
  
# re: 【原创】AJAX开发简略续一[未登录] 2007-12-23 21:04 | 随风
We offer WoW Power Leveling and World of Warcraft powerleveling,Final Fantasy XI Gil,Maple Story and Lord fo Ring Online Powerleveling.WoW Powerleveling service and cheap wow Powerleveling,World of Warcraft Power leveling sale for you. WOW Power leveling,Cheap WOW Powerleveling 1-60 and Cheap WOW Powerleveling 1 - 70.All service is faster,safer,and cheaper.WOW Powerleveling 1 - 60,WOW Powerleveling 1 - 70.Lord fo Ring Online Power Leveling 1-50 .We Please remember,we are your online game helper.
www.pvpsale.com
www.pvpsale.com/powerleveling.asp  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2008-03-19 22:56 | xzbvfx
我对PB不熟悉,故关于PB与Ajax的关系问题无法给予,请见谅。不过到是没想
至于类似QQ的共享桌面功能,好像不应该是Web程序能做到的  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-07-02 09:53 | business loans
Cars and houses are expensive and not every person is able to buy it. But, business loans was invented to aid people in such situations.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-07-18 16:30 | article critique writing
I opine that you know how complicated can the research paper accomplishing be. Nevertheless, you shouldn’t be disappointed, simply because the research paper writing services present the custom essay and there’s not a big problem to buy research paper and be totally satisfied.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-07-18 18:53 | write my paper
You will choose to get information about cheap writing services if you don’t want to spoil your grades.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-08-17 22:31 | custom essay
Evidently, lots of university students in the whole world order custom essay every minute. So, I state that the papers writing service will be really popular in students' society.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-08-19 09:00 | buy essay online
Various students are chatting about essays developing. Nevertheless, less of them realize what does writing mean. Hence, hundreds of them spoil their careers. We advice to find essay writing services to avoid that!   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-08-19 09:09 | essays
Fantabulous topic around life! Really effective to be honest! If you're worry, feel free to meet our term paper writing company that can help you with superb custom essays. Good luck!  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-10-08 17:55 | SEO Company
Very nice post even i would say that whole blog is awesome. I keep learning new things every day from post like these. Good stuff!
  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-10-22 13:05 | loans
I think that to get the business loans from creditors you must have a great motivation. However, one time I have received a collateral loan, just because I was willing to buy a house.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2011-12-21 18:42 | Buy facebook likes
www.fanbullet.com sells very real facebook fans and likes that will certainly like your products and are most likely to be turned as your customers. Traffic in this way will be huge, as many of those who are connected with your facebook fans will also visit your site.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-01-02 09:19 | do my essay
Be wice and buy papers online to rid of your corse paper writing pain.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-03-12 09:58 | philosophy essays paper
Thare’s not another easy way to receive A+ than to accomplish the college essays and it is, likewise, simple to buy the literature essays paper from the online essay writing service.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-03-25 18:42 | blog commenting services
My website is really important for me. Thus, it ought to be ranked high. I ought to determine if that is worth to utilize blog commenting options at blog commenting services. I do not know if that can help my site. Could somebody give some information just about blog posting services? Thanx!   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-03-30 13:51 | Reaction paper writing
Education seems to be important for university students. Nevertheless, some students do not have good writing skills. It should not be a thing to worry about. It is real to turn to Professional Custom Writing Services.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-04-12 08:28 | buy an essay
Hot knowledge about this post. I use the essays writers and buy an essay and buy a research paper about this topic.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-04-25 15:21 | Cheap SSL
I was looking in google for someting else, but I have found You and I must say your website is really amazing   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-06-27 14:48 | sinhala news
I would like to say that this blog really convinced me, you give me best information! Thanks, very good post.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-15 09:19 | Write My Paper for me
To buy an essay, contact Essays professors company "essaysprofessors.com". Find best academic writing services from a trusted writing center.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-15 09:41 | term paper essays
That is no matter what is your academic paper's topic just because professional custom papers writing companies advice to get sample term papers essayslab.com of great academic standards.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-17 12:13 | I need an essay written
I do not want that my fellow group members tease me because of my poor writing abilities, and hence I buy term paper written "essayswriters.com" by skilled staff.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-17 12:15 | custom research writing service
Go to this Web page if you need to buy an essay of perfect quality. I assure you that you will be given help from custom essay writing service.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-17 13:11 | dissertation writing
That should be not so simple to accomplish the best thesis research about this topic by your own! My suggestion is to find the trustworthy dissertation service or you have an opportunity to buy a thesis paper in thesis writing service "primethesis.com".   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-17 13:13 | buy thesis
A lot of times some men wanted to purchase significant essay thesis referring to this topic in the dissertations writing services. Can you please suggest the trustworthy buy thesis primethesis.com services? Thank you.   回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-08-17 22:13 | plagiarism checking
Very good information. Thanks because it is the interesting.If you want to grab a great paper about this post you can use plagiarism checker, and i'll recommend you to check it in http://www.plagiarismsearch.com ! unlike other services, they give excellent grade guaranty that your work is dump of plagiarism. You like to order custom written essay at the plagiarism detection. They will give you an accurate plagiarism detection reporting without any delay.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-09-02 20:27 | buy a college paper
Here is one of the most reputed firms that proposes to buy essay writing services at low rates all year around.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2012-09-02 20:30 | pay someone to write my essay
Your authors are highly skilled and did my writing assignments masterfully, and showed clearly that your service is the great place to buy an essay "bestcustompapers.com" from.  回复  更多评论
  
# viagra 2012-09-19 20:04 | viagra
# re: 【原创】AJAX开发简略续一 2013-03-19 12:16 | here
You don’t need to ponder over which company to choose for buying resume from now on. Best resume writers are at a hand’s reach. Contact Prime-Resume company (prime-resume.com) so you can go over CV templates or buy resume. Be positive that you will obtain customized and professional resume writing service.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-04 16:53 | Buy CV
You don’t need to mull over where to buy resume paper from now on. Professional resume writers are at a hand’s reach. Check out Resumes leader company (resumesleader.com) to check resume writing samples or buy CV. Be sure that you will acquire excellent resume writing services.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-04 17:15 | resume writing services
Are you hunting where to buy resume paper or where to obtain CV templates and help with resume writing? Or you just would like to order resume from expert resume writers? Only get in touch with Resume company exclusiveresume.com.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-08 15:50 | link
Are you searching which service to choose for buying resume or where to obtain CV sample and help with resume writing? Or you just would like to order resume from best resume writers? Only get in touch with Resume company.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-08 15:52 | this Web site
You are looking for resume templates or where to buy resume paper? Or you wish to receive professional resume writing service? Visit Perfect Resume firm and you will learn all useful information and also a reputable writing centre from which you can order resume written by expert resume writers.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-08 15:58 | PrimeEssays rewiew
These days, many sophomores are searching for excellent quality custom made essays. EssaysExperts rewiew "best-writing-services.com" will help learners to find the most trustful paper writing service from which they can order first-rate research papers composed from point zero.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-08-08 16:00 | SuperiorPapers.com rewiew
Here is the piece of advice for students who cannot find out what paper writing services to go for so that buy essays. Look over paper writing service reviews "best-writing-services.com" reachable on the Internet and opt for the company which pretends to be the most fair.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-12-21 04:44 | Click here
This company gives first-rate resume services. Hence, if you haven’t got a clue how to write a resume, would like to buy resume from best resume writers or merely to see resume templates, contact Prime Resume company "prime-resume.com".  回复  更多评论
  
# re: 【原创】AJAX开发简略续一 2013-12-21 05:06 | Web site
In case if you do not know where to order resume, visit Resumesexpert company resumesexpert.com and find out that buying resume is easier than you thought. Professional resume writers provide expert CV writing, our CV sample can also assist you to write a resume by yourself.  回复  更多评论
  
# re: 【原创】AJAX开发简略续一earn online 2014-08-26 18:36 | nurseonline231@yahoo.com
Thanks for your post . I was searching for this . This post helped me lot .Thanks once again for publishing this information . Good luck   回复  更多评论
  
# re: 【原创】AJAX开发简略续一earn online 2014-08-26 18:42 | http://www.earnonlinee.com
I was searching for this html . You provided the information i was searching for . This post is very useful for me .   回复  更多评论
  
# re: 【原创】AJAX开发简略续一monty 2014-08-26 18:45 | <a href="http://www.earnonlinee.com/"
I was searching for this html .I get lot of useful information from this post . Thanks a lot for publishing this post .   回复  更多评论
  
# re: 【原创】AJAX开发简略续一monty 2014-08-26 18:47 | [URL=http://www.earnonlinee.com]earn online[/URL]
useful info  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: