明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

XML說明系列(9)

[摘要]系列之十七:如何使用XSL和正則表達(dá)式來驗(yàn)證數(shù)據(jù)的有效性XSL現(xiàn)在正在逐漸的成為XML中的類似與SQL在數(shù)據(jù)庫設(shè)計(jì)中的地位。雖然Microsoft's XSL僅僅是實(shí)現(xiàn)了其中的某一些部分的功能但是你已經(jīng)能夠?qū)崿F(xiàn)非常復(fù)雜的查詢了雖然現(xiàn)在的XSL僅僅還只是一種基于純粹文本和字符串方式的查詢語言...
系列之十七:如何使用XSL和正則表達(dá)式來驗(yàn)證數(shù)據(jù)的有效性
XSL現(xiàn)在正在逐漸的成為XML中的類似與SQL在數(shù)據(jù)庫設(shè)計(jì)中的地位。
雖然Microsoft's XSL僅僅是實(shí)現(xiàn)了其中的某一些部分的功能
但是你已經(jīng)能夠?qū)崿F(xiàn)非常復(fù)雜的查詢了
雖然現(xiàn)在的XSL僅僅還只是一種基于純粹文本和字符串方式
的查詢語言
在下面介紹的例子中,將大量使用到文本內(nèi)的字符串方式的搜索,
你會發(fā)現(xiàn)在XML中對數(shù)據(jù)的處理很大一部分都是要使用到文本內(nèi)的查詢的。
這在XSL的編寫中是一件非常普及的功能。
正是因?yàn)檫@樣,你應(yīng)該了解一些正則表達(dá)式應(yīng)該如何來使用。

正則表達(dá)式的簡單介紹
正則表達(dá)式大部分都是來自與Unix世界的需要。
在Unix中許多編程語言幾乎整個(gè)都是圍繞著正則表達(dá)式進(jìn)行的(例如Perl, Python, Tcl)
但是令人感到奇怪的是正則表達(dá)式好象是最近才使用在Windows系列中的,
特別是大量的使用在腳本語言中,例如JavaScript和VBScript,
盡管你也可以將它們使用在Visual Basic或則Java中,但是顯然它們似乎在
腳本語言中更加有吸引力。也許是這個(gè)緣故把,大家平時(shí)似乎都很少使用正則表達(dá)式把。

使用正則表達(dá)式,你可以根據(jù)你想查詢的內(nèi)容建立一個(gè)匹配模板(英文叫pattern)
一旦你使用正則表達(dá)式建立了一個(gè)模板,你就可以使用它來測試你的字符串了,
使用它可以完成很多功能:
例如判斷一個(gè)字符串是否在另外一個(gè)字符串中(或則在另外一個(gè)字符串中的什么位置)
例如使用一個(gè)字符串來替換另外一個(gè)字符串
例如返回所有滿足模板條件的字符串列表
例如。。。等等等等

上面我介紹了有關(guān)正則表達(dá)式的基本概念,有關(guān)它的詳細(xì)說明和語法可以查閱MSDN和
JavaScript中的有關(guān)幫助。
在VB中如果你想引用正則表達(dá)式的話,你需要在項(xiàng)目中引用"Microsoft VBScript Regular Expressions"。但是如果你要是使用腳本的話就不必要了,因?yàn)樵谀_本里面這已經(jīng)是一個(gè)
內(nèi)在的對象供你引用了。
當(dāng)然你需要在你的機(jī)器上安裝IE4以上羅。
這個(gè)對象(在JavaScript中)叫RegExp
下面還是讓代碼來說明問題把,現(xiàn)在假設(shè)你想查看一個(gè)文擋里面是否包含一個(gè)特定的
字符串(例如"regular expressions")
代碼見下:
代碼使用VB寫成。
Public Function IsTermInDocument(filePath As String,_
expr As String) As Boolean
Dim fs As FileSystemObject
Dim ts As TextStream
Dim re As RegExp
Dim text As String

Set fs = New FileSystemObject
Set ts = fs.OpenTextFile(filePath, ForReading)
text = ts.ReadAll
Set re = New RegExp
re.Pattern = expr
IsTermInDocument = re.Test(text)
End Function

Debug.print IsTermInDocument("c:\bin\myPage.htm",_
"regular expression")
上面的那個(gè)函數(shù)將根據(jù)文擋里面是否有滿足條件的字符串返回True/False.
注意我加粗的部分:
第一句是建立一個(gè)正則表達(dá)式的對象
第二句是指定該正則表達(dá)式的模板
第三句就是根據(jù)模板執(zhí)行查詢了
呵呵,如果正則表達(dá)式的功能僅僅是這么簡單的話,也許你會說
VB中的instr()不就能夠代替了嗎?

但是,在進(jìn)行XML的數(shù)據(jù)格式化的時(shí)候,對字符串的處理遠(yuǎn)比這個(gè)復(fù)雜得多。
例如:假設(shè)你要確保你要驗(yàn)證的字段中是否包含一個(gè)well-formed的zip編碼
(well-formed意味著它是一個(gè)有效的編碼,
也許它對于某個(gè)給定的地方或則區(qū)域或則國家又是無效的
這種界于well-formed和valid的表達(dá)式將是本文里面討論的重點(diǎn))
如果你要是使用VB來進(jìn)行這種判斷的話將非常的難看
你需要判斷是否表達(dá)式有5位或則10位數(shù)字,或則是否為字母,
然后第6位字母又必須得是一個(gè)破則號
但是如果是使用正則表達(dá)式的話,將會是這樣的簡單:

Set IsZipCode = New RegExp
IsZipCode.Pattern = "^\d{5}(-\d{4})?$"
if IsZipCode.test("32545-2198") then

下面將簡單解釋一下其中模板的含義:
^ 說明在這個(gè)表達(dá)式之前沒有任何其它的字符串,
意味著要驗(yàn)證的表達(dá)式不是某個(gè)字符串中間的一部分,而是它的開頭
\d 表示下一個(gè)字符必須是0-9中的一個(gè)數(shù)字
\d{5} 并且必須是連著的5個(gè)數(shù)字
-\d{4} 4個(gè)數(shù)字必須出現(xiàn)在字符"-"的后面
(-\d{4})? 這4個(gè)數(shù)字是可選的,即可有也可以沒有
$ 這個(gè)表達(dá)式后面應(yīng)該不會再有其它的什么東西了

最有意思的是一旦你定義好了這么一個(gè)模板,你就可以將它使用在
任何其它的正則表達(dá)式對象中,而不需要再重新建立一個(gè)正則表達(dá)式對象了了。
使用這個(gè)辦法,你甚至可以把一個(gè)近2000行代碼的JavaScript程序
減少到只有幾百行,設(shè)置當(dāng)你把一些模板組合在一起的時(shí)候,就能夠完成
正則表達(dá)式本來不可能完成的東東了。

下面我再舉一個(gè)用來驗(yàn)證數(shù)據(jù)有效性的例子:
例如你現(xiàn)在想驗(yàn)證一個(gè)電話號碼數(shù)據(jù)是否有效
對于通用一個(gè)電話號碼一般下面這幾種寫法都是有效的:
(800)555-1212
1(800) 555-1212
1-800-555-1212
1.800.555.1212
等等.

如果你使用腳本來寫一段滿足上面所有要求的代碼將非常的復(fù)雜。
但是如果你使用正則表達(dá)式的話,將非常的簡單,只有下面這兩句代碼:
Set IsPhoneNumber=new RegExp
IsPhoneNumber.pattern="^[01]?\s*[\(\.-]?(\d{3})[\)\.-]?\s*(\d{3})[\.-](\d{4})$"

你可以仔細(xì)體會上面這個(gè)代碼的意義。
首先它驗(yàn)證第一個(gè)字符是否為0或則是否為1或則根本就沒有。
然后再進(jìn)行下面的驗(yàn)證,大家可以自己琢磨其它部分的意思把,呵呵。

查詢和替換數(shù)據(jù)
當(dāng)然,驗(yàn)證數(shù)據(jù)的有效性僅僅是它能夠做的一件小事而已,
但是更有用的是:如果你能夠把上面那么多種電話號碼的表達(dá)方式轉(zhuǎn)換
成一種統(tǒng)一的方式顯示出來。
例如我要把上面的電話號碼格式化成XML中的一個(gè)片段如下:

<phoneNumber>
<areacode>123</areacode>
<exchange>456</exchange>
<local>7890</local>
</phoneNumber>

這時(shí)的電話號碼的模板分成三個(gè)部分:
(\d{3}), (\d{3}), (\d{4}), 分別表示area code, exchange, 和local number
. 在正則表達(dá)式中,正則解釋器會自動
將匹配的字符賦值給變量 $1, $2, $3,等.
這樣你使用下面的代碼就能夠?qū)崿F(xiàn)

re.Replace("1(352)351-4159", "<phoneNumber><areacode>$1</areacode><exchange>$2</exchange><local>$3</local></phoneNumber>")

如果你覺得這個(gè)Replace使用起來很不舒服的話,下面將給出一個(gè)
類似與VB中的Replace并且擴(kuò)展了它的函數(shù)

Public Function Replacex(sourceStr as String, oldStr as _
String, newStr as String, optional ignoreCase as _
Boolean = False,optional isGlobal as Boolean = True)
Dim re As New RegExp
re.Pattern = oldStr
re.Global = isGlobal
re.IgnoreCase = ignoreCase
Replacex = re.Replace(sourceStr, newStr)
End Function

下面給出使用它的一些例子:
Debug.Print Replacex("This is a test","is","at")
--> "That at a test"
最精彩的還是使用正則表達(dá)式了
Debug.Print Replacex("This is a test","\ws","at")
--> "That at a tatt"
甚至還可以這樣
Debug.Print Replacex("This is a test","(\ws)","at$1")
--> "Thatis atis a tatist"

正則表達(dá)式的replace方法還有兩個(gè)參數(shù)。
在默認(rèn)的情況時(shí)正則表達(dá)式在找到了一個(gè)滿足條件的時(shí)候就會停下來
但是如果你要是將isGlobal參數(shù)設(shè)置為True的話,它就會全文替換
在默認(rèn)的情況下正則表達(dá)式是區(qū)分大小寫的
但是如果你將ignoreCase設(shè)置為False的話,它將不區(qū)分大小寫

獲得XML的節(jié)點(diǎn)
現(xiàn)在,我們將一起來看看正則表達(dá)式在XML中是如何運(yùn)用的。
首先,在Microsoft's XML 2.0解釋器里面有兩大難題:
第一, 這個(gè)XML解釋器在裝載XML文擋的時(shí)候必須要保證入口
滿足定義在DTD的范圍之內(nèi)。這是一個(gè)大麻煩,因?yàn)榫湍壳暗那闆r來看,
XML更改頻繁,不時(shí)會多出一些標(biāo)準(zhǔn),不時(shí)又會產(chǎn)生新的標(biāo)志。
第二,如果使用XSL的話不能夠操縱DTD,甚至當(dāng)你使用腳本語言也是一件很費(fèi)力的事情。
經(jīng)常要做的是你需要在XSL使用XSL的結(jié)構(gòu)表達(dá)式中設(shè)置一些變量,例如
瀏覽器的類型或則ASP的參數(shù)呀
這時(shí)你可以使用正則表達(dá)式來解決這些問題。
當(dāng)你想獲取一個(gè)XML元素的時(shí)候,也許這個(gè)對象有可能并不是你想要的東東。
例如:假設(shè)一個(gè)很簡單的XML結(jié)構(gòu),一個(gè)圖書目錄.
XML的代碼如下:
<catalog>
<book>
<title>XML for Beginners</title>
<author>Fred Fnord</author>
<description>A book on XML for programming neophytes.</description>
</book>
<book>
<title>Pair-O-Dice Lost</title>
<author>U. Wajer</author>
<description>Techniques for throwing the game.</description>
</book>
<book>
<title>The Fields of Oberon</title>
<author>Alan Landis</author>
<description>The wee folk are back, and they aren't happy.</description>
</book>
<book>
<title>Distributed Computing on a Budget</title>
<author>Fred Fnord</author>
<description>Using XML and related techniques for managing distributed applications.</description>
</book>
</catalog>





標(biāo)簽:XML介紹系列(9)