动网论坛,站长建站首选,国内使用量最多的论坛软件 动网论坛官方技术讨论区 站长工具 申请属于您自己的免费论坛
首页 | 新闻资讯 | 网站运营 | 网络编程 | 数据库 | 服务器 | 网页设计 | 图像媒体 | 网络应用 | 搜索优化 | 资源下载 | 动网主机
    本站内  互联网 ASP论坛  ASP.Net论坛  PHP论坛
   Asp → 阅读文章

 如何使用XSL和正则表达式来验证数据的有效性(二)

作者:Batman(翻译) 来源:chinaasp 
阅读 5706 人次 , 2001-2-10 

现在继续我在上一系列中介绍的例子。我们将实现一个简单的搜索机制,
也许你的兴趣不是在获取书籍的标题而是在要获得整个书节点(note)上。
那么使用下面这个函数就能够满足你的要求了
Public Function GetFilteredElements(activeElement As Variant, RegExpfilter As String, _
Optional queryString As String = "",optional IsGlobal as Boolean=True, _
optional IgnoreCase as Boolean = True) As IXMLDOMNodeList
Dim re As RegExp
Dim filterDoc As DOMDocument
Dim nodelist As IXMLDOMNodeList
Dim filterList As IXMLDOMNodeList
Dim node As IXMLDOMElement
Dim baseNode As IXMLDOMElement
Set re = New RegExp
On Error GoTo ErrorHandler
Select Case TypeName(activeElement)
Case "IXMLDOMElement"
Set baseNode = activeElement
Case "DOMDocument"
Set baseNode = activeElement.documentElement
Case Else
Error 1001
Set GetFilteredElements = Nothing
End Select
re.Pattern = RegExpfilter
re.Global=IsGlobal
re.IgnoreCase=IgnoreCase
If queryString = "" Then
Set filterList = baseNode.selectNodes(".[textnode()]|.//*[textnode()]")
Else
Set filterList = baseNode.selectNodes(queryString)
End If
For Each node In filterList
If re.Test(node.Text) Then
node.setAttribute "filter:filteredElementFound", "true"
End If
Next
Set filterList = baseNode.selectNodes(".[@filter:filteredElementFound]|.//*[@filter:filteredElementFound]")
For Each node In filterList
node.removeAttribute "filter:filteredElementFound"
Next
Set GetFilteredElements = filterList
Exit Function
ErrorHandler:
If Err.Number = 1001 Then
MsgBox "Document must be an XML document, or a document element."
Else
Error Err.Number
End If
End Function

下面是对这个方法的简单描述:
GetFilteredElements主要是用来获取一个XML的文档或则一个文档里面的节点,并且
按照我们的需要转换它(包括所有的该节点的子节点),将转换后的节点放到一个
列表类型IXMLDOMNodeList中.
这个过滤器程序按次序对每个节点进行运用,如果一个节点的文本满足了表达式的话,
那么这个节点就被做上一个临时属性的标记为filter:filteredElementFound
(当然为了不和你自己的XML文档里已经存在的标志发生冲突,你可以把这个属性
改成你需要的东西).
一旦所有的节点都被检查完毕后,一个新的列表对象(仅仅只包含那些满足表达式的
节点)被创建了。这些临时的属性会被删除掉,然后返回那些节点。

如果你没有给这个函数输入查询参数的话,
那么将获得整个文档的所有叶子节点(就是那些没有子元素的节点)
如果你给这个函数输入查询参数的话,
那么这个函数将返回满足条件的节点或则子节点
例如,下面的代码将返回第一本书的标题和描述的节点和第四本书的
描述节点
Dim bookXML=new DOMDocument
bookXML.load("bookCatalog.xml")
Set nodelist=GetfilteredElements(bookXML,"xml")
而下面的代码将返回第一和第四本书的节点,然后你可以根据这些节点获取它们的
子节点的属性。
Set nodelist=GetfilteredElements(bookXML,"xml","//book")
通常,你应该尽可能的定义一个XSL的查询过滤器(filter)
因为它会只返回你需要的节点,会大大减少你需要处理的数据量。

这个函数是XML "数据库"的一个运用实例,因为很多SQL的开发者用熟悉了的
参数(例如LIKE)在XML中是没有等效的方法的,但是只要你在XML中能够熟练使用
正则表达式,你会发现它能够实现很多LIKE语句能够实现的功能。

使用XSL转换验证数据
正则表达式使用在XSL的转换中是一个强有力的验证数据有效的工具。
例如,你想根据XML的数据生成一个显示书籍标题和描述的table
当你使用基于DOM版本(就是使用微软的那个模型XDOM)的时候,XSL已经能够实现非常复杂的转换XML为
HTML的功能了。
在XSL的这个节点中<xsl:script>,允许你使用脚本语言。
你可以在输出流中插入文本(但是目前你就不能够把一个DOM节点输出到输出流中).
XSL中默认的脚本语言是JavaScript,
在使用的过程中你需要注意的是,由于"/"在JavaScript中是特殊字符,你需要使用
"//"将其转意。
代码如下:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:script language="JavaScript"><![CDATA][
IsValidBookTopic=/xml/
]]></xsl:script>
<xsl:template match="/">
<xsl:apply-templates select="//book" />
</xsl:template>
<xsl:template match="book">
<xsl:if expr="IsValidBookTopic.test(this.text)">
<h1><xsl:value-of select="title"/></h1>
<h2><xsl:value-of select="author"/></h2>
<p><xsl:value-of select="description"/></p>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当然,你也可以改变你的XSL中的查询参数(例如上面例子中使用的参数是xml)
一个直接的方法是生成一个参数实体"entities"
例如下面的代码,你需要使用"%"字符来说明一个字符是参数。
Function SetXSLParameter(XslDoc as DOMDocument ,ParamName as _
String,ParamValue as Variant) as DOMDocument
Dim XslDoc as DOMDocument
Dim ScriptNode as IXMLDOMElement
Dim re as RegExp

Set re=new RegExp
Re.global=True
Re.IgnoreCase=True
Re.pattern="%"+ParamName
For each ScriptNode in xslDoc.selectNodes("xsl:script")
ScriptNode.text=Re.replace(ScriptNode.text,cstr(ParamValue))
Next
Return XslDoc
End Function

SetXSLParameter用来给XSL文档设置参数。
当然你也可以不使用上面这个函数,直接在XSL的脚本里面修改这个参数,
但是如果你使用了上面这个函数的话,可以让你的代码的可扩展性能更好。
注意的是,XSL的代码将被上面这个函数所修改
所以如果你想对相同的XSL对象使用不同的过滤器(就是不同的查询条件的话)
需要使用XSL对象的clone(就是制作一个XSL的副本)方法。
下面就是一个完整的例子
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:script language="JavaScript"><![CDATA][
IsValidBookTopic=/%searchStr/
]]></xsl:script>
<xsl:template match="/">
<xsl:apply-templates select="//book" />
</xsl:template>
<xsl:template match="book">
<xsl:if expr="IsValidBookTopic.test(this.text)">
<h1><xsl:value-of select="title"/></h1>
<h2><xsl:value-of select="author"/></h2>
<p><xsl:value-of select="description"/></p>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

然后你就可以使用下面这段代码来修改这个参数了
呵呵,我是搞asp的,下面这段代码就是写在你的asp的程序中的。

Set xmlDoc=new DomDocument
Set xslDoc=new DOMDocument
XmlDoc.load "catalog.xml"
XslDoc.load "catalog.xsl"
SetXSLParameter xslDoc, "searchStr", "pair-o-dice"
Response.write xmlDoc.transformNode(xslDoc)

同样,使用上面的方法,你就可以设置其他的参数了,例如浏览器的类型呀
ASP的查询参数呀,或则一个基于Web的组件呀。

使用正则表达式给XSL带来了强大的功能。
虽然,使用这种通用性很强的方法在目前也许你不会看到能够给你带来很
大的优势(主要是很少有人写XML的程序的说),但是在未来的编程过程中,
你将会体会到它的强大威力了。
  

 本文Tags正则表达式  
 收藏本文  打印本文  论坛讨论  关闭窗口
· 上一篇:在ASP中用“正则表达式对象”来校验数据的合法性
· 下一篇:正则表达式regular expression详述(二)
· 一个使用多选框的小智力题,传教士与野人
· 域名专题 - Windows2000的目录服务(摘自ms win2000站点)
· 两个ASP的性能优化实用方法
· 将数据访问页绑定到断开连接的记录集
· 在JSP、ASP和PHP网站网页中使用XHTML


关于本站 | 联系我们 | 业务合作 | 客户案例 | 诚聘英才 | 广告合作 | 收藏本站
海口动网先锋网络科技有限公司版权所有
Copyright © 2000 - 2006 Cndw.Com
中华人民共和国电信与信息服务业务经营许可证编号 琼 ICP 020077