日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

C#发现之旅第二讲 C#-XSLT开发

發(fā)布時(shí)間:2024/1/17 C# 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#发现之旅第二讲 C#-XSLT开发 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
C#發(fā)現(xiàn)之旅第二講 C#-XSLT開(kāi)發(fā)

袁永福 2008-5-15

系列課程說(shuō)明

????為了讓大家更深入的了解和使用C#,我們開(kāi)始這一系列的主題為“C#發(fā)現(xiàn)之旅”的技術(shù)講座。考慮到各位大多是進(jìn)行WEB數(shù)據(jù)庫(kù)開(kāi)發(fā)的,而所謂發(fā)現(xiàn)就是發(fā)現(xiàn)我們所不熟悉的領(lǐng)域,因此本系列講座內(nèi)容將是C#在WEB數(shù)據(jù)庫(kù)開(kāi)發(fā)以外的應(yīng)用。目前規(guī)劃的主要內(nèi)容是圖形開(kāi)發(fā)和XML開(kāi)發(fā),并計(jì)劃編排了多個(gè)課程。在未來(lái)的C#發(fā)現(xiàn)之旅中,我們按照由淺入深,循序漸進(jìn)的步驟,一起探索和發(fā)現(xiàn)C#的其他未知的領(lǐng)域,更深入的理解和掌握使用C#進(jìn)行軟件開(kāi)發(fā),拓寬我們的視野,增強(qiáng)我們的軟件開(kāi)發(fā)綜合能力。

本系列課程配套的演示代碼下載地址為 http://files.cnblogs.com/xdesigner/cs_discovery.zip 。
本系列課程已發(fā)布的文章有
C#發(fā)現(xiàn)之旅第一講 C#-XML開(kāi)發(fā)
C#發(fā)現(xiàn)之旅第二講 C#-XSLT開(kāi)發(fā)
C#發(fā)現(xiàn)之旅第三講 使用C#開(kāi)發(fā)基于XSLT的代碼生成器
C#發(fā)現(xiàn)之旅第四講 Windows圖形開(kāi)發(fā)入門(mén)
C#發(fā)現(xiàn)之旅第五講 圖形開(kāi)發(fā)基礎(chǔ)篇
C#發(fā)現(xiàn)之旅第六講 C#圖形開(kāi)發(fā)中級(jí)篇
C#發(fā)現(xiàn)之旅第七講 C#圖形開(kāi)發(fā)高級(jí)篇
C#發(fā)現(xiàn)之旅第八講 ASP.NET圖形開(kāi)發(fā)帶超鏈接的餅圖
C#發(fā)現(xiàn)之旅第九講 ASP.NET驗(yàn)證碼技術(shù)
C#發(fā)現(xiàn)之旅第十講 文檔對(duì)象模型

本課程說(shuō)明

本課程介紹XPath和XSLT的基本概念,并介紹了如何在C#中使用這些技術(shù)。

XPath介紹

??? XPath是從XML基礎(chǔ)規(guī)范上派生的技術(shù),專(zhuān)門(mén)用于快速檢索和查詢(xún)XML文檔,使用方便,功能強(qiáng)大,XPath也是XSLT技術(shù)的基礎(chǔ)。

??? XPath是W3C國(guó)際標(biāo)準(zhǔn)組織定義的用于在單個(gè)XML文檔中快速檢索和定位XML文檔節(jié)點(diǎn)的規(guī)范,它也是跨平臺(tái)的,若一些軟件支持XPath,則必然是支持標(biāo)準(zhǔn)的XPath語(yǔ)法。因此無(wú)論是JAVA還是C#都是支持相同語(yǔ)法的XPath。

??? 我們理解XPath時(shí)可以參考文件目錄結(jié)構(gòu)FilePath,在Windows資源管理器左邊的文件目錄樹(shù)狀列表中,可以看到各種文件對(duì)象,包括磁盤(pán)根目錄,各級(jí)文件目錄等等,它們共同構(gòu)成了一個(gè)樹(shù)狀結(jié)構(gòu),我們選擇對(duì)象時(shí)既可以在這個(gè)樹(shù)狀結(jié)構(gòu)中一個(gè)個(gè)查找,也可以指定路徑名來(lái)進(jìn)行快速定位,文件系統(tǒng)的路徑名采用斜杠號(hào)來(lái)分隔各個(gè)目錄層次的目錄名。比如在這個(gè)示意圖中,我們選中的目錄,可以使用路徑名”c:\documents and settings\袁永福”來(lái)快速定位。

??? 而XML文檔中也是這種樹(shù)狀層次結(jié)構(gòu),因此我們也可以套用這種文件路徑名的概念到XML文檔中,于是形成了XPath路徑。我們處理XML文檔時(shí)可以一層層查找所需的XML節(jié)點(diǎn),也可以指定XPath路徑字符串來(lái)快速定位XML節(jié)點(diǎn)。在XPath路徑中,我們使用反斜杠符號(hào)來(lái)分隔各個(gè)層次的XML元素的名稱(chēng)。

??? 在文件目錄系統(tǒng)中,我們可以可以使用絕對(duì)路徑名,也可以使用相對(duì)路徑名,我們可以使用一個(gè)點(diǎn)號(hào)表示當(dāng)前目錄,使用兩個(gè)點(diǎn)表示父目錄。在XPath中我們也套用了類(lèi)似的概念,我們從XML文檔根節(jié)點(diǎn)出發(fā)而指定的XPath路徑為絕對(duì)路徑,從某個(gè)XML節(jié)點(diǎn)開(kāi)始轉(zhuǎn)到其它節(jié)點(diǎn)所經(jīng)過(guò)的路徑為相對(duì)路徑,我們也使用一個(gè)點(diǎn)表示當(dāng)前節(jié)點(diǎn),也使用兩個(gè)點(diǎn)來(lái)表示父節(jié)點(diǎn)。其實(shí)我們可以將絕對(duì)路徑看成從根節(jié)點(diǎn)出發(fā)的相對(duì)路徑。

??? 在這個(gè)示意圖中,第一個(gè)選中的節(jié)點(diǎn)可以使用XPath路徑“Table/Record/Country”來(lái)快速定位。

??? 在文件目錄系統(tǒng)中,同一個(gè)目錄下面不能有相同名稱(chēng)的對(duì)象,因此相對(duì)路徑名和絕對(duì)路徑名都能準(zhǔn)確的定位到一個(gè)目錄上,而在XML文檔中,同一個(gè)XML節(jié)點(diǎn)下可以存在多個(gè)具有相同名稱(chēng)的子節(jié)點(diǎn),因此XPath路徑可能無(wú)法唯一的確定一個(gè)XML節(jié)點(diǎn)。此時(shí)XPath采用了內(nèi)嵌條件判斷語(yǔ)句的方法來(lái)解決這個(gè)問(wèn)題。XPath路徑字符串中可以使用一對(duì)方括號(hào)來(lái)包含一個(gè)邏輯表達(dá)式,在這個(gè)表達(dá)式中可以使用字符串判斷,數(shù)學(xué)四則運(yùn)算,邏輯判斷和一些預(yù)定義函數(shù),而且XPath路徑中每個(gè)層次都能包含表格式,因此XPath的邏輯判斷的功能是非常強(qiáng)大的。

??? 在示意圖中,我們使用XPath路徑”Table/Record[CustomerID=’ANATR’]/Phone”來(lái)快速定位第二個(gè)節(jié)點(diǎn),此處使用了一段方括弧包含了一個(gè)邏輯表達(dá)式。表示查找某個(gè)節(jié)點(diǎn),該節(jié)點(diǎn)下的CustoemrID子節(jié)點(diǎn)的文本值等于 “ANATR”。

??? XPath是一種國(guó)際標(biāo)準(zhǔn),但在微軟的.NET框架當(dāng)然支持這個(gè)國(guó)際標(biāo)準(zhǔn)。我們可以使用.NET類(lèi)庫(kù)中的System.Xml.Xsl.XslTransform類(lèi)型來(lái)執(zhí)行XSLT轉(zhuǎn)換。這個(gè)類(lèi)型除了支持標(biāo)準(zhǔn)的XPath外,還進(jìn)行一些擴(kuò)展,主要是能擴(kuò)展使用開(kāi)發(fā)者自己定義的函數(shù)。

??? 使用XPath,我們可以很方便的搜索XML文檔中的任何部分,因此具有很好的數(shù)據(jù)檢索分析功能,近期業(yè)界興起的半結(jié)構(gòu)化文檔技術(shù)大多就是以XPath為基礎(chǔ)的。

??? 由于XPath技術(shù)是相當(dāng)強(qiáng)的,而且是國(guó)際標(biāo)準(zhǔn),跨平臺(tái)的,因此大家有時(shí)間好好學(xué)習(xí)使用它。對(duì)于XPath的詳細(xì)語(yǔ)法可訪問(wèn)網(wǎng)站 http://www.w3.org/TR/xpath ,若大家安裝了MSDN2003版,也可參考 MSDN Library/XML Web Services/XML核心/SDK 文檔/MSXML4.0 SDK/XPath Reference。這些電子文檔全是英文,大家也可以購(gòu)買(mǎi)一些專(zhuān)門(mén)講述XML技術(shù)的中文書(shū)籍看看。

?XSLT介紹

??? XSLT是一種將XML文檔轉(zhuǎn)換為其他文本文檔的語(yǔ)言,是建立在XML和XPath之上的國(guó)際標(biāo)準(zhǔn),內(nèi)容比較多,功能強(qiáng)大。

??? 對(duì)于編程人員來(lái)說(shuō),XSLT可以看作以前序遍歷的方式專(zhuān)門(mén)處理XML樹(shù)狀結(jié)構(gòu)的標(biāo)記語(yǔ)言。以前編程根據(jù)XML文檔輸出純文本數(shù)據(jù)時(shí)需要寫(xiě)代碼以前序遍歷方式的方式遍歷XML文檔對(duì)象組成的樹(shù)狀結(jié)構(gòu),對(duì)于每一個(gè)特定名稱(chēng)或特定層次的XML節(jié)點(diǎn)而輸出不同的內(nèi)容,這個(gè)過(guò)程比較復(fù)雜,代碼量大,需用進(jìn)行很多的狀態(tài)判斷。而XSLT則使用一種簡(jiǎn)潔明了的標(biāo)記語(yǔ)言實(shí)現(xiàn)了相同的邏輯。因此XSLT從程序邏輯的角度看類(lèi)似支持遞歸的編程語(yǔ)言,而且是專(zhuān)門(mén)處理XML文檔的。

??? XSLT轉(zhuǎn)換過(guò)程會(huì)涉及到三個(gè)文本文檔,一個(gè)是要處理的原始XML文檔,第二個(gè)就是XSLT樣式表文檔,該文檔包含了XSLT代碼,XSLT代碼本身就是XML格式,但使用了XML的名稱(chēng)空間。第三個(gè)就是XSLT處理輸出的文本文檔,注意,此處輸出的是純文本文檔,這個(gè)文檔具體是什么格式完全靠XSLT代碼來(lái)決定,可以是另外一個(gè)XML文檔,HTML文檔,SQL語(yǔ)句字符串或者其他任意格式的字符串?dāng)?shù)據(jù)等等,XSLT轉(zhuǎn)換只能輸出純文本文檔,此外就沒(méi)有限制輸出文檔的具體格式。


XSLT范例

??? 下面使用一個(gè)XSLT范例來(lái)說(shuō)明XSLT處理過(guò)程。

??? 在這個(gè)示意圖中有三個(gè)圖片,第一個(gè)是原始的包含數(shù)據(jù)的XML文檔,第二個(gè)是XSLT樣式表文檔的內(nèi)容,第三個(gè)就是轉(zhuǎn)換結(jié)果。XSLT代碼如下

<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
??? <xsl:output method='xml' />
??? <xsl:template match='/'>
??????? <html>
??????????? <body>
??????????????? <table border='1'>
??????????????????? <xsl:for-each select="Table/Record">
??????????????????????? <tr>
??????????????????????????? <xsl:for-each select="*">
??????????????????????????????? <td>
??????????????????????????????????? <xsl:value-of select="." />
??????????????????????????????? </td>
??????????????????????????? </xsl:for-each>
??????????????????????? </tr>
??????????????????? </xsl:for-each>
??????????????? </table>
??????????? </body>
??????? </html>
??? </xsl:template>
</xsl:stylesheet>

??? 數(shù)據(jù)XML文檔是一個(gè)很簡(jiǎn)單的XML文檔,此處不加說(shuō)明了。重點(diǎn)說(shuō)說(shuō)XSLT樣式表文檔,可以看到XSLT樣式表文檔本身一個(gè)XML文檔。它采用XML的樹(shù)狀結(jié)構(gòu)來(lái)描述遞歸處理過(guò)程,也比較好理解。

??? 在樣式表文檔中,根元素為 xsl:stylesheet ,里面定義了一個(gè)名為xsl的名稱(chēng)空間,這個(gè)根節(jié)點(diǎn)及其屬性值都是固定的。

xsl:output 元素是可選的,它的method屬性用于指定輸出文檔的格式,可以設(shè)置為xml,html或text值。此處使用xml輸出樣式,說(shuō)明輸出的文檔是XML格式的,XSLT轉(zhuǎn)換會(huì)盡量生成XML文檔,但不作保證,因此仍然有可能生成不合格的XML文檔。

??? xsl:template 用于定義一個(gè)XSLT模板,模板類(lèi)似編程語(yǔ)言中的函數(shù),可實(shí)現(xiàn)XSLT代碼的重用。模板可以使用name屬性定義名稱(chēng),也可以使用match屬性定義匹配的XPath路徑,這個(gè)模板使用了match屬性來(lái)匹配XML文檔本身。

??? 然后是 html 元素,由于html元素沒(méi)有使用xsl的前綴,因此不屬于xslt代碼,因此將原樣輸出,跟著后面的body,table元素也是一樣的。

??? xsl:for-each 元素類(lèi)似C#中的foreach 語(yǔ)法結(jié)果,表示循環(huán)遍歷元素,它使用select屬性指定一個(gè)XPath相對(duì)路徑,XSLT使用這個(gè)相對(duì)路徑查詢(xún)所有要遍歷的XML節(jié)點(diǎn),此時(shí)當(dāng)前節(jié)點(diǎn)就是XML文檔本身,因此XSLT處理器會(huì)調(diào)用XmlDocument的SelectNodes 函數(shù)來(lái)獲得要遍歷的XML節(jié)點(diǎn),函數(shù)的參數(shù)就是Table/Record。于是我們開(kāi)始循環(huán)遍歷所有的Record元素了。

??? 在循環(huán)遍歷Record元素時(shí),對(duì)每一個(gè)Record元素都要輸出xsl:for-each的子節(jié)點(diǎn),首先是 tr 元素,這不是XSLT元素,因此原樣輸出。這里還套嵌定義了另外一個(gè)for-each元素,于是我們又開(kāi)始了一個(gè)新的循環(huán)遍歷了,新的循環(huán)指定的相對(duì)XPath路徑是一個(gè)星號(hào),表示匹配所有名稱(chēng)的子元素,這類(lèi)似DOS命令Dir中使用星號(hào)匹配所有文件。此處表示循環(huán)遍歷Record元素下面所有的字段元素。

??? 對(duì)每一個(gè)字段元素,首先輸出td 元素,然后處理xsl:value-of 元素,xsl:value-of 表示輸出指定相對(duì)路徑的節(jié)點(diǎn)的值,這里指定的XPath是一個(gè)點(diǎn)號(hào),表示當(dāng)前節(jié)點(diǎn)本身,由于當(dāng)前節(jié)點(diǎn)是XML元素,因此也就輸出元素的文本內(nèi)容,相當(dāng)于輸出XmlElement的InnerText 屬性值。

??? 為了讓大家更清楚的了解XSLT執(zhí)行過(guò)程,我寫(xiě)了一段C#代碼來(lái)模擬實(shí)現(xiàn)這個(gè)XSLT轉(zhuǎn)換過(guò)程,代碼在演示程序的 codexslt.aspx 中。代碼如下

// 此處代碼動(dòng)態(tài)構(gòu)造 xml 文檔對(duì)象結(jié)構(gòu)來(lái)輸出XML文檔
System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
-------------- 查詢(xún)數(shù)據(jù)庫(kù),填充XmlDoc --------------------------
// 保存輸出結(jié)果的緩沖區(qū)
System.IO.StringWriter myResult = new System.IO.StringWriter();
myResult.WriteLine("<html>");
myResult.WriteLine("??? <body>");
myResult.WriteLine("??????? <table border='1'>");
// 模擬 <xsl:for-each select="Table/Record">
foreach( System.Xml.XmlNode node in XmlDoc.SelectNodes("Table/Record"))
{
??? myResult.WriteLine("??????? <tr>");
??? // 模擬 <xsl:for-each select="*">
??? foreach( System.Xml.XmlNode node2 in node.SelectNodes("*"))
??? {
??????? myResult.Write("??????????? <td>");
??????? // 模擬 <xsl:value-of select="." />
??? ??? myResult.Write( node2.InnerText );
??????? myResult.WriteLine("</td>");
??? }
??? myResult.WriteLine("??????? </tr>");
}
myResult.WriteLine("??????? </table>");
myResult.WriteLine("??? </body>");
myResult.WriteLine("</html>");
myResult.Close();

??? 代碼很簡(jiǎn)單,這里我就不詳細(xì)說(shuō)明了。

??? 這里只是展示了一個(gè)非常簡(jiǎn)單的XSLT轉(zhuǎn)換過(guò)程,XSLT和XPath語(yǔ)法不少,但花點(diǎn)時(shí)間是可以記下來(lái)的,編寫(xiě)XSLT模板是很有技巧性的。一般的我們要設(shè)計(jì)XSLT模板,首先獲得要轉(zhuǎn)換的XML文檔樣本以及所需轉(zhuǎn)換結(jié)果的樣本,這兩個(gè)樣本可能相差非常大,所有的差別都需要依靠XSLT轉(zhuǎn)換模板來(lái)彌補(bǔ),此時(shí)XSLT模板的編寫(xiě)不只是XSLT元素和函數(shù)的堆砌,而是需要同時(shí)兼顧輸入和輸出,還需要使用面向過(guò)程的編程思想。有時(shí)還需要編程對(duì)XSLT轉(zhuǎn)換器進(jìn)行擴(kuò)展。

XML/XSLTWEB開(kāi)發(fā)中的應(yīng)用

??? XML/XSLT技術(shù)在WEB開(kāi)發(fā)中可以發(fā)揮很大的應(yīng)用,可以為WEB開(kāi)發(fā)提供一種新的HTML頁(yè)面生成方式。

??? 一般的在WEB開(kāi)發(fā)中使用XML/XSLT技術(shù)主要有兩種模式,一個(gè)是在服務(wù)器端執(zhí)行XSLT轉(zhuǎn)換,另一個(gè)是在客戶(hù)端執(zhí)行XSLT轉(zhuǎn)換。

??? 在服務(wù)器端執(zhí)行XSLT轉(zhuǎn)換時(shí),應(yīng)用系統(tǒng)的業(yè)務(wù)模塊生成包含要顯示的數(shù)據(jù)的XML文檔,然后調(diào)用事先寫(xiě)好的XSLT模板文檔,執(zhí)行XSLT轉(zhuǎn)換,轉(zhuǎn)換結(jié)果一般是HTML文檔,當(dāng)然也可以是其他類(lèi)型的文本文檔,此時(shí)客戶(hù)端就可以將生成的HTML文檔直接作為頁(yè)面響發(fā)送到客戶(hù)端瀏覽器中。客戶(hù)端瀏覽器接受HTML文檔并顯示出來(lái)。在這個(gè)過(guò)程中,服務(wù)器端生成的XML文檔,XSLT轉(zhuǎn)換生成的HTML文檔都是臨時(shí)生成的文檔,都可以存留在內(nèi)存中,用完即可清除掉,不需要寫(xiě)到磁盤(pán)文件中。

??? 在客戶(hù)端執(zhí)行XSLT轉(zhuǎn)換時(shí),應(yīng)用系統(tǒng)的業(yè)務(wù)模塊生成包含要顯示的數(shù)據(jù)的XML文檔,加上XSLT轉(zhuǎn)換信息標(biāo)記,直接發(fā)送到客戶(hù)端瀏覽器,客戶(hù)端瀏覽器獲得這個(gè)XML文檔,根據(jù)其中的XSLT轉(zhuǎn)換信息標(biāo)記,從服務(wù)器上下載指定名稱(chēng)的XSLT文檔。然后調(diào)用自己的XSLT轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換,在內(nèi)存中生成了HTML文檔并顯示出來(lái)。此時(shí)顯示的HTML頁(yè)面不會(huì)出現(xiàn)在瀏覽器的緩沖文件夾中,也看不到HTML源代碼,只能看到XML的源代碼。

??? 由于XSLT轉(zhuǎn)換是國(guó)際標(biāo)準(zhǔn),在服務(wù)器端的轉(zhuǎn)換結(jié)果和在客戶(hù)端的轉(zhuǎn)換結(jié)果是一樣的。因此兩種模式下瀏覽器中顯示的頁(yè)面內(nèi)容是一樣的。

??? 在傳統(tǒng)的WEB開(kāi)發(fā)中,我們都是直接使用業(yè)務(wù)系統(tǒng)拼湊出HTML字符串來(lái)生成要顯示的HTML頁(yè)面。雖然在ASP.NET中大量使用Web控件來(lái)簡(jiǎn)化開(kāi)發(fā),但web控件內(nèi)部還是拼湊HTML字符串的。使用程序代碼來(lái)拼湊HTML字符串會(huì)影響程序代碼的可讀性,很容易使得程序代碼雜亂無(wú)章,而且生成的HTML可讀性差。

??? 若使用XML/XSLT技術(shù)則可以有效的改善這種情況,由于XML文檔格式檢查非常嚴(yán)格,因此這就使得程序代碼生成XML文檔過(guò)程準(zhǔn)確,不得出現(xiàn)錯(cuò)誤,在這個(gè)環(huán)境下迫使程序員注意保持程序代碼質(zhì)量。而且生成的XML文檔不只用于生成HTML頁(yè)面,還能方便的向其他程序模塊提供數(shù)據(jù),并可充當(dāng)WebService。

??? 考察WEB應(yīng)用中生成的HTML代碼,可以發(fā)現(xiàn),大量的HTML頁(yè)面中用于實(shí)現(xiàn)頁(yè)面各種動(dòng)態(tài)效果和頁(yè)面格式的HTML代碼多于直接顯示數(shù)據(jù)的HTML代碼,而且HTML代碼普遍重復(fù)。這使得HTML頁(yè)面代碼臃腫,文件大,這會(huì)使得客戶(hù)端瀏覽器下載頁(yè)面緩慢。當(dāng)采用XML/XSLT技術(shù)并在客戶(hù)端執(zhí)行XSLT轉(zhuǎn)換時(shí),由于服務(wù)器端發(fā)送的XML文檔非常簡(jiǎn)潔,只包含純粹的數(shù)據(jù),并沒(méi)有其他冗余的代碼,因此文檔小,下載快。與之配套的XSLT模板也是經(jīng)過(guò)分析處理的,代碼重復(fù)少,因此XSLT文件也小,這樣客戶(hù)端瀏覽器以前要下載一個(gè)很大的HTML文檔,而現(xiàn)在只要下載兩個(gè)較小的文檔,這縮短了瀏覽器下載數(shù)據(jù)的時(shí)間。

??? 除了改善數(shù)據(jù)傳輸過(guò)程,瀏覽器自己執(zhí)行XSLT轉(zhuǎn)換,這樣能將一部分的工作量從服務(wù)器端轉(zhuǎn)移到客戶(hù)端,此時(shí)服務(wù)器端只要快速生成包含數(shù)據(jù)的XML文檔即完成工作。由于XSLT是廣泛采用的國(guó)際標(biāo)準(zhǔn),此時(shí)WEB系統(tǒng)能可靠的使用客戶(hù)端的運(yùn)算能力,從而減少服務(wù)器端運(yùn)算壓力,而利用客戶(hù)端長(zhǎng)期閑置的運(yùn)算能力。

??? 雖然XML/XSLT技術(shù)具有很大的優(yōu)勢(shì),但在實(shí)際開(kāi)發(fā)中仍然存在不小的問(wèn)題,其中最大的問(wèn)題就是編制XSLT模板文件成本高。我們?cè)陂_(kāi)發(fā)WEB系統(tǒng)中使用了很多開(kāi)發(fā)工具,包括VS.NET的WEB窗體設(shè)計(jì)器,美工人員使用的FrontPage,Dreamwave等等,都是用于生成HTML文檔的,而HTML文檔要求不嚴(yán)格,很多內(nèi)容還不符合XML規(guī)范,因此需要使用各種方法將這些HTML文檔轉(zhuǎn)換為標(biāo)準(zhǔn)的XML文檔,然后還需要分析頁(yè)面結(jié)構(gòu),將這些XML文檔加工成XSLT文檔。在目前的技術(shù)條件下,這個(gè)過(guò)程成本比較大,使得XML/XSLT技術(shù)難于推廣和普及。在此建議大家多多思考,如何低成本的將HTML文檔轉(zhuǎn)換為XSLT文檔。

??? 而且XML/XSLT技術(shù)調(diào)試比較困難,對(duì)開(kāi)發(fā)者要求很高,這也加大了這個(gè)技術(shù)的應(yīng)用成本。而且目前的web系統(tǒng)中大量使用的WEB控件沒(méi)有考慮到XML/XSLT技術(shù),這也阻礙了這種新技術(shù)的應(yīng)用。

使用C#執(zhí)行XSLT轉(zhuǎn)換

??? 在演示程序中,其中有些代碼就是使用C#來(lái)執(zhí)行XSLT轉(zhuǎn)換的。

record.aspx

??? 演示程序中record.aspx演示了在服務(wù)器端執(zhí)行XSLT轉(zhuǎn)換,打開(kāi)這個(gè)頁(yè)面的C#代碼中,在Page_Load函數(shù)中,首先是查詢(xún)數(shù)據(jù)庫(kù)并生成一個(gè)包含數(shù)據(jù)的XML文檔。然后我們使用了一個(gè)名為xsl的頁(yè)面參數(shù),這個(gè)參數(shù)就指定了使用XSLT模板文件。若用戶(hù)指定了該參數(shù),我們開(kāi)始執(zhí)行XSLT轉(zhuǎn)換。

??? 首先是創(chuàng)建一個(gè)XslTransform對(duì)象,調(diào)用它的Load函數(shù)來(lái)加載用戶(hù)指定的XSLT模板文件,然后調(diào)用它的Transform函數(shù),這個(gè)函數(shù)有四個(gè)參數(shù),第一個(gè)就是包含數(shù)據(jù)的XML文檔對(duì)象,第二個(gè)是XSLT轉(zhuǎn)換參數(shù)的列表,此處未用,第三個(gè)就使輸出轉(zhuǎn)換結(jié)果的流對(duì)象,我們就使用頁(yè)面輸出流,最后一個(gè)是XML文檔解析對(duì)象,此處未用。

string strXSLRef = this.Request.QueryString["xsl"] ;
if( strXSLRef != null && strXSLRef.Length > 0 )
{
??? // 根據(jù)頁(yè)面參數(shù)指定的XSLT樣式表名稱(chēng)執(zhí)行XSLT轉(zhuǎn)換
??? strXSLRef = this.Server.MapPath( strXSLRef );
??? System.Xml.Xsl.XslTransform transform = new System.Xml.Xsl.XslTransform();
??? transform.Load( strXSLRef );
??? transform.Transform( XmlDoc , null , this.Response.Output , null );
}

??? 可以看到在C#中執(zhí)行XSLT轉(zhuǎn)換是非常簡(jiǎn)單的,只要?jiǎng)?chuàng)建一個(gè)XslTransform對(duì)象,使用Load函數(shù)加載XSLT模板,使用Transform函數(shù)來(lái)執(zhí)行XSLT轉(zhuǎn)換即可。

recordxml.aspx

??? 演示程序中的recordxml.aspx演示了在客戶(hù)端執(zhí)行XSLT轉(zhuǎn)換,打開(kāi)這個(gè)頁(yè)面的C#代碼,在Page_Load函數(shù)中,可以看到是查詢(xún)數(shù)據(jù)庫(kù)并使用XmlTextWriter輸出包含數(shù)據(jù)的XML文檔。其中有這么一段代碼,首先判斷一個(gè)名為xsl的頁(yè)面參數(shù)是否存在,若存在則調(diào)用xmlwriter的WriteProcessingInstruction方法輸出一段名為 xml-stylesheet的XML指令,這個(gè)指令的 href 屬性值就使頁(yè)面參數(shù)指定的XSLT模板文件名。

// 輸出XSLT樣式表信息頭
string strXSLRef = this.Request.QueryString["xsl"] ;
if( strXSLRef != null && strXSLRef.Length > 0 )
{
??? xmlwriter.WriteProcessingInstruction(
??????? "xml-stylesheet" ,
??????? "type='text/xsl' href='" + strXSLRef + "'");
}

??? 客戶(hù)端瀏覽器解析下載的XML文檔,若遇到這個(gè)這段XML指令根據(jù)其中的href屬性下載XSLT模板文件,然后執(zhí)行XSLT轉(zhuǎn)換,將生成的轉(zhuǎn)化結(jié)果再作為HTML文檔顯示出來(lái)。

??? 在這個(gè)頁(yè)面中,服務(wù)器端只負(fù)責(zé)輸出數(shù)據(jù)XML文檔,并提供XSLT模板文件下載,而XSLT轉(zhuǎn)換就給客戶(hù)端瀏覽器處理,這樣就能減少服務(wù)器端的工作量并利用客戶(hù)端的運(yùn)算能力。

??? 注意這里的xml-stylesheet指令只對(duì)瀏覽器有效,一般其他的程序處理XML文檔時(shí)會(huì)忽略掉這個(gè)XML指令。即使我們?cè)诜?wù)器端使用XslTransform對(duì)象執(zhí)行XSLT轉(zhuǎn)換,這個(gè)XML指令也是毫無(wú)作用的,就像不存在一樣。

使用C#執(zhí)行XPath查詢(xún)

??? 演示程序中的recordxpath.aspx就演示了使用C#執(zhí)行XPath查詢(xún)。打開(kāi)這個(gè)頁(yè)面的界面設(shè)計(jì),可以看到其界面是比較簡(jiǎn)單地,其中一個(gè)單行文本框用于輸入XPath字符串,一個(gè)大的多行文本框用于顯示查詢(xún)結(jié)果,還有一個(gè)按鈕用于點(diǎn)擊執(zhí)行操作。頁(yè)面代碼主要在這個(gè)按鈕的點(diǎn)擊事件處理中。

??? 雙擊這個(gè)按鈕,可以看到該按鈕的點(diǎn)擊事件處理代碼。在該處理中,首先調(diào)用CreateRecordXMLDocument函數(shù)來(lái)獲得包含數(shù)據(jù)的XML文檔對(duì)象,生成XML文檔的過(guò)程可以參考record.aspx的說(shuō)明。

??? 程序生成包含數(shù)據(jù)的XML文檔后,在從單行的文本輸入框獲得用戶(hù)輸入的XPath字符串,若用戶(hù)輸入的內(nèi)容,則對(duì)XML文檔的根節(jié)點(diǎn)調(diào)用SelectNodes方法,執(zhí)行XPath查詢(xún),SelectNodes函數(shù)返回一個(gè)XmlNodeList列表,該列表中的元素類(lèi)型是XmlNode。我們遍歷這個(gè)列表,對(duì)其中每一個(gè)XML節(jié)點(diǎn)對(duì)象獲得它的XML字符串,然后進(jìn)行輸出。

??? 若用戶(hù)沒(méi)有輸入XPath字符串,則直接輸出XML文檔根節(jié)點(diǎn)的內(nèi)容。

??? 在這里我們定義了GetXMLString 函數(shù),這個(gè)函數(shù)主要是返回指定的XML節(jié)點(diǎn)對(duì)象的帶縮進(jìn)的XML字符串。用于取代Xml節(jié)點(diǎn)的OuterXml屬性。

小結(jié)

??? 在本課程中,我們了解了XPath,XML/XSLT的基礎(chǔ)知識(shí)。并演示使用C#使用XPath和XML/XSLT技術(shù)。

??? XML及其派生的技術(shù)都是很重要的國(guó)際標(biāo)準(zhǔn)技術(shù),對(duì)現(xiàn)代WEB開(kāi)發(fā)具有很大的影響力,XML技術(shù)是一種優(yōu)質(zhì)的軟件開(kāi)發(fā)技術(shù),因此大家要花點(diǎn)時(shí)間好好學(xué)習(xí),熟練掌握XML及其派生技術(shù)將大大提高大家的軟件開(kāi)發(fā)能力。

轉(zhuǎn)載于:https://www.cnblogs.com/xdesigner/archive/2008/05/19/1202313.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的C#发现之旅第二讲 C#-XSLT开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。