下载 jQuery-XML-parser-and-search.zip – 9.5 KB
介绍
这里所描述的过程将使你能够创建一个简单的基于jQuery / XML的解析器和搜索机制。此过程将通过一个AJAX请求检索XML,然后在jQuery中分析数据,为搜索机制做准备。该解决方案将基于不区分大小写的全部或部分关键字匹配地返回结果。来自于关键字搜索的返回结果设置将被格式化为一个直接链接到相应网站的超链接。jQuery搜索方法非常类似于Mike Endale的一个项目,不过增加了一个DOM解析器,正则表达式以及结果集分组。
背景
客户端需要一个简单的搜索工具来查找基于关键字搜索的本地内部网站。关键字搜索必须不区分大小写,并允许返回部分匹配的结果。归咎于客户端内容管理系统的架构,因此(SharePoint)只能执行客户端脚本。其解决方案的另一个障碍是,源数据将来自多个源。数据被存储在多个Excel电子表格,CSV文件和MS Access数据库内。这就对我们提出了这样的需要:开发具有一系列查询和一个宏的Access解决方案,充当可合并、擦洗,并最后格式化数据作为XML输出的伪ETL。对于这个解决方案的目的,我们将详细介绍JavaScript XML分析器的设计,而不是伪Access ETL宏工具的设计。
使用代码
该解决方案的做法是利用一个简单的基于JavaScript / XML的搜索来发送数据结果到HTML / JavaScript前端。前端将引用脚本:jQuery,XML和CSS文件。XML格式将因为它的可读性和它是数据交换行业标准格式之一的事实而被使用。 XML数据将通过使用AJAX的客户端jQuery解析,并通过Internet Explorer 11呈现。
解决方案将使用RegExp对象来处理关键字匹配,验证和特殊字符处理。RegExp对象字符串将检查危险语法从而提高解决方案的稳定性和整体可用性。
我们将默认使用JavaScript分组功能来返回匹配结果作为折叠的纪录集。折叠的记录集线项目将被URL链接到相关的Project Workspace网站。在扩展的组记录集下,结果将存在于相关的子记录中,当通过On Click事件展开的时候。
信息架构
解析器函数有一个复杂的带有节点和属性的层次XML树,并且将它转变成等价的JavaScript对象和属性。客户端基于JavaScript / XML的搜索需要经过以下步骤:
1.伪ETL工具准备数据到XML文件(本项目不包括这一步骤)
2.此XML文件加载到指定的位置(本项目不包括这一步骤)
3.在点击事件发生时,JavaScript解析器将使用AJAX方法加载XML数据
4.检查搜索中关键字的存在
如果没有关键字存在抛出错误消息“Please enter a search keyword”
5.如果有节点包含URL属性的字符串,那么节点加入到数组中。
6.RegExp对象关键字通过替代匹配特殊字符处理
7.RegExp对象关键字匹配转换为不区分大小写
8.循环数组匹配基于验证的RegExp对象
如果没有结果,那就抛出错误消息“No results were found!”
9.用斑马条纹的奇数和偶数行对顶级组构建结果集
10.用相关的Work Order构建组匹配PPID行作为子组
11.填充结果,然后将它们传递到最后呈现的集合
12.显示具有列和所有分组标题的结果集合
分组在默认情况下折叠
用户界面
用户界面是一个简单的基于HTML / JavaScript客户端搜索来返回关键字匹配结果——默认为折叠和分组的记录集合。以行项目显示的折叠纪录集合直接URL链接到相关项目的网站。在扩展组记录集合下,结果在On Click事件扩大时将保留相关的子记录。
内嵌页面引用
我们需要做的第一件事是引用我们的脚本:jQuery,XML和CSS文件。
< /div>
你会发现我们已经添加了xmlData属性到search.js引用。这是传递来自于HTML文件的XML文件位置的最佳方式。如果你有你有多个项目xml文件想要用作为数据源的话,那么这就很有帮助。
XML数据源
XML数据源可以以任何方式或任何大小来构造;但建议保持源XML文件小于1 MB,以便于保持适当的分析器响应时间。下面是XML源用于此项目的一个例子:
Archived
错误处理
对于这个项目,我们已经在两个关键领域使用过错误处理。如果没有关键字存在,那么错误消息“Please enter a search keyword”将出现。如果没有个结果生成,则抛出错误消息“No results were found!”。
//Check if a keyword existsif(keyword =='') { errMsg +='Please enter a search keyword'; }else{ searchThis(); }
if(i ==0) {pub+='< div>';pub+='No results were found!';pub+='< /div>';
使用jQuery AJAX请求
我们将通过预定义的能在页面级别启用的jQuery库通过异步JavaScript函数调用XML。 AJAX的全称是“异Asynchronous JavaScript and XML”,由Jesse James Garrett,Adaptive Path的创始人所杜撰。AJAX依赖于XMLHttpRequest,CSS,DOM和其他技术。AJAX的主要特点是它的“异步”性质,这意味着它可以从服务器而无需刷新页面来发送和接收数据。在异步模式中,客户端和服务器会独立地工作,以及独立地进行通信,从而允许用户持续与网页交互,不管服务器上发生了什么。
functionsearchThis(){ $.ajax({ type:"GET", url: XMLSource, dataType:"xml", success:function(xml){ loadPublication(xml) } });}
使用DOM解析和正则表达式
由于jQuery本身不能解析XML字符串;我们将充分利用浏览器的DOM解析方法——大多数浏览器以这种或那种形式支持。火狐,Chrome,Safari以及最新的
Internet
Explorer浏览器均支持这种方法,它们都具有DOMParser对象。较早的Internet Explorer浏览器(如IE 8)使用其专有的ActiveX对象。可以创建跨浏览器的解决方案,来检查是否缺少DOMParser,但这超出了这个项目的范围,但是可能以后在额外的跨浏览器支持中会添加。
知道JavaScript RegExp(正则表达式)功能和语法来处理任意特殊字符。同时通过定义正则表达式来忽略大小写,以便于在关键字搜索时更加友好。
functionloadPublication(xmlData){ i =0;varrow;varsearchExp ="";varppid ="P"; $(xmlData).find('PPID').each(function(){// Check if a site URL attr existsif($(this).find('url').attr('address').length) {//Set the search string Variablesvarrecord = $(this).find('record').attr('search');vararchive = $(this).find('Archive');//Escape characters in keyword expression and use global matchRegExp.escape =function(keyword){returnkeyword.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"); };//Keyword expression will be case agnosticvarexp =newRegExp(keyword,"i");//Use formated keyword as the default searchsearchExp = record.match(exp);//If the search expression is not nullif(searchExp !=null) {//Start building the resultif((i %2) ==0) { row ='even'; }else{ row ='odd'; }if($(this).attr('PID') != ppid) { ppid = $(this).attr('PID'); i++;
分组返回结果
用户界面是一个简单的基于HTML / JavaScript客户端搜索来返回关键字匹配结果默认为折叠又分组的记录集合。以行项目显示的折叠纪录集合直接URL链接到相关项目的网站。在扩展组记录集合下,结果在On Click事件扩大时将保留相关的子记录。
//Grouping of the resultsfunctionexpgroupby(e){docElts=document.all;numElts=docElts.length;images = e.getElementsByTagName("IMG");img=images[0];srcPath=img.src;index=srcPath.lastIndexOf("/");imgName=srcPath.slice(index+1);varb="auto";if(imgName=="plus.gif"){b="";img.src="/_layouts/images/minus.gif"}else{b="none";img.src="/_layouts/images/plus.gif"}oldName=img.name;img.name=img.alt;spanNode=img;while(spanNode!=null){spanNode=spanNode.parentNode;if(spanNode!=null&&spanNode.id!=null&&spanNode.id=="wrapper")break}while(spanNode.nextSibling!=null&&spanNode.nextSibling.id!="wrapper"){spanNode=spanNode.nextSibling;spanNode.style.display=b;}}
完整的源代码
下面是这个项目完整的源代码例子。
//Full source$(document).ready(function(){//Global VariablesvarXMLSource = $('#data').attr('xmlData');varkeyword ='';varpub ='';vari =0; $("#searchButton").click(function(){ keyword = $("input#term").val();//Reset any messagevarerrMsg =''; pub ='';//Check if a keyword existsif(keyword =='') { errMsg +='Please enter a search keyword'; }else{ searchThis(); }if(errMsg !='') { pub +='< div>'; pub += errMsg; pub +='< /div>'; }//Show error$('#result').html(pub); });//Use enter key to trigger the search query$("input#term").keypress(function(e){varkey = e.which;if(key ==13){ $("#searchButton").click();returnfalse;} });functionsearchThis(){ $.ajax({ type:"GET", url: XMLSource, dataType:"xml", success:function(xml){ loadPublication(xml) } }); }functionloadPublication(xmlData){ i =0;varrow;varsearchExp ="";varppid ="P"; $(xmlData).find('PPID').each(function(){// Check if a site URL attr existsif($(this).find('url').attr('address').length) {varrecord = $(this).find('record').attr('search');vararchive= $(this).find('Archive');//Escape characters in keyword expression and use global matchRegExp.escape =function(keyword){returnkeyword.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");};//Keyword expression will be case agnosticvarexp =newRegExp(keyword,"i");//Use formated keyword as the default searchsearchExp = record.match(exp);//If the search expression is not nullif(searchExp !=null) {//Start building the resultif((i %2) ==0) { row ='even'; }else{ row ='odd'; }if($(this).attr('PID') != ppid) { ppid = $(this).attr('PID'); i++;//Grouped header row with URL links from the xml attrpub +='< tr id="wrapper"code-string" style="margin: 0px; padding: 0px; border: 0px; color: rgb(128, 0, 128);">'">'
+ '< td colspan="8">'
+ '< a onclick="javascript:expgroupby(this);returnfalse;" href="javascript:">'
+ '< img name="collapse" alt="expand" src="/_layouts/images/plus.gif" border="0" />< /a>'
许可证
这篇文章以及任何相关的源代码和文件遵循 The Code Project Open License (CPOL)。