熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#發現之旅第二講

2013-11-13 10:13:05  來源: .NET編程 

  為了讓大家更深入的了解和使用C#我們開始這一系列的主題為C#發現之旅的技術講座考慮到各位大多是進行WEB數據庫開發的而所謂發現就是發現我們所不熟悉的領域因此本系列講座內容將是C#在WEB數據庫開發以外的應用目前規劃的主要內容是圖形開發和XML開發並計劃編排了多個課程在未來的C#發現之旅中我們按照由淺入深循序漸進的步驟一起探索和發現C#的其他未知的領域更深入的理解和掌握使用C#進行軟件開發拓寬我們的視野增強我們的軟件開發綜合能力

  本系列課程配套的演示代碼下載地址為 _discoveryzip

  本課程說明

  本課程介紹XPath和XSLT的基本概念並介紹了如何在C#中使用這些技術

  XPath介紹

  XPath是從XML基礎規范上派生的技術專門用於快速檢索和查詢XML文檔使用方便功能強大XPath也是XSLT技術的基礎

  XPath是WC國際標准組織定義的用於在單個XML文檔中快速檢索和定位XML文檔節點的規范它也是跨平台的若一些軟件支持XPath則必然是支持標准的XPath語法因此無論是JAVA還是C#都是支持相同語法的XPath

  我們理解XPath時可以參考文件目錄結構FilePath在Windows資源管理器左邊的文件目錄樹狀列表中可以看到各種文件對象包括磁盤根目錄各級文件目錄等等它們共同構成了一個樹狀結構我們選擇對象時既可以在這個樹狀結構中一個個查找也可以指定路徑名來進行快速定位文件系統的路徑名采用斜槓號來分隔各個目錄層次的目錄名比如在這個示意圖中我們選中的目錄可以使用路徑名c:\documents and settings\袁永福來快速定位

  而XML文檔中也是這種樹狀層次結構因此我們也可以套用這種文件路徑名的概念到XML文檔中於是形成了XPath路徑我們處理XML文檔時可以一層層查找所需的XML節點也可以指定XPath路徑字符串來快速定位XML節點在XPath路徑中我們使用反斜槓符號來分隔各個層次的XML元素的名稱

  在文件目錄系統中我們可以可以使用絕對路徑名也可以使用相對路徑名我們可以使用一個點號表示當前目錄使用兩個點表示父目錄在XPath中我們也套用了類似的概念我們從XML文檔根節點出發而指定的XPath路徑為絕對路徑從某個XML節點開始轉到其它節點所經過的路徑為相對路徑我們也使用一個點表示當前節點也使用兩個點來表示父節點其實我們可以將絕對路徑看成從根節點出發的相對路徑

  在這個示意圖中第一個選中的節點可以使用XPath路徑Table/Record/Country來快速定位

  在文件目錄系統中同一個目錄下面不能有相同名稱的對象因此相對路徑名和絕對路徑名都能准確的定位到一個目錄上而在XML文檔中同一個XML節點下可以存在多個具有相同名稱的子節點因此XPath路徑可能無法唯一的確定一個XML節點此時XPath采用了內嵌條件判斷語句的方法來解決這個問題XPath路徑字符串中可以使用一對方括號來包含一個邏輯表達式在這個表達式中可以使用字符串判斷數學四則運算邏輯判斷和一些預定義函數而且XPath路徑中每個層次都能包含表格式因此XPath的邏輯判斷的功能是非常強大的

  在示意圖中我們使用XPath路徑Table/Record[CustomerID=ANATR]/Phone來快速定位第二個節點此處使用了一段方括弧包含了一個邏輯表達式表示查找某個節點該節點下的CustoemrID子節點的文本值等於 ANATR

  XPath是一種國際標准但在微軟的NET框架當然支持這個國際標准我們可以使用NET類庫中的SystemXmlXslXslTransform類型來執行XSLT轉換這個類型除了支持標准的XPath外還進行一些擴展主要是能擴展使用開發者自己定義的函數

  使用XPath我們可以很方便的搜索XML文檔中的任何部分因此具有很好的數據檢索分析功能近期業界興起的半結構化文檔技術大多就是以XPath為基礎的

  由於XPath技術是相當強的而且是國際標准跨平台的因此大家有時間好好學習使用它對於XPath的詳細語法可訪問網站 若大家安裝了MSDN也可參考 MSDN Library/XML Web Services/XML核心/SDK 文檔/MSXML SDK/XPath Reference這些電子文檔全是英文大家也可以購買一些專門講述XML技術的中文書籍看看

  [NextPage]

  XSLT介紹

  XSLT是一種將XML文檔轉換為其他文本文檔的語言是建立在XML和XPath之上的國際標准內容比較多功能強大

  對於編程人員來說XSLT可以看作以前序遍歷的方式專門處理XML樹狀結構的標記語言以前編程根據XML文檔輸出純文本數據時需要寫代碼以前序遍歷方式的方式遍歷XML文檔對象組成的樹狀結構對於每一個特定名稱或特定層次的XML節點而輸出不同的內容這個過程比較復雜代碼量大需用進行很多的狀態判斷而XSLT則使用一種簡潔明了的標記語言實現了相同的邏輯因此XSLT從程序邏輯的角度看類似支持遞歸的編程語言而且是專門處理XML文檔的

  XSLT轉換過程會涉及到三個文本文檔一個是要處理的原始XML文檔第二個就是XSLT樣式表文檔該文檔包含了XSLT代碼XSLT代碼本身就是XML格式但使用了XML的名稱空間第三個就是XSLT處理輸出的文本文檔注意此處輸出的是純文本文檔這個文檔具體是什麼格式完全靠XSLT代碼來決定可以是另外一個XML文檔HTML文檔SQL語句字符串或者其他任意格式的字符串數據等等XSLT轉換只能輸出純文本文檔此外就沒有限制輸出文檔的具體格式


XSLT范例

  下面使用一個XSLT范例來說明XSLT處理過程

  在這個示意圖中有三個圖片第一個是原始的包含數據的XML文檔第二個是XSLT樣式表文檔的內容第三個就是轉換結果XSLT代碼如下

   <xsl:stylesheet version= xmlns:xsl=>
    <xsl:output method=xml />
    <xsl:template match=/>
        <html>
            <body>
                <table border=>
                    <xsl:foreach select=Table/Record>
                        <tr>
                            <xsl:foreach select=*>
                                <td>
                                    <xsl:valueof select= />
                                </td>
                            </xsl:foreach>
                        </tr>
                    </xsl:foreach>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

  數據XML文檔是一個很簡單的XML文檔此處不加說明了重點說說XSLT樣式表文檔可以看到XSLT樣式表文檔本身一個XML文檔它采用XML的樹狀結構來描述遞歸處理過程也比較好理解

  在樣式表文檔中根元素為 xsl:stylesheet 裡面定義了一個名為xsl的名稱空間這個根節點及其屬性值都是固定的 [NextPage]

  xsl:output 元素是可選的它的method屬性用於指定輸出文檔的格式可以設置為xmlhtml或text值此處使用xml輸出樣式說明輸出的文檔是XML格式的XSLT轉換會盡量生成XML文檔但不作保證因此仍然有可能生成不合格的XML文檔

  xsl:template 用於定義一個XSLT模板模板類似編程語言中的函數可實現XSLT代碼的重用模板可以使用name屬性定義名稱也可以使用match屬性定義匹配的XPath路徑這個模板使用了match屬性來匹配XML文檔本身

  然後是 html 元素由於html元素沒有使用xsl的前綴因此不屬於xslt代碼因此將原樣輸出跟著後面的bodytable元素也是一樣的

  xsl:foreach 元素類似C#中的foreach 語法結果表示循環遍歷元素它使用select屬性指定一個XPath相對路徑XSLT使用這個相對路徑查詢所有要遍歷的XML節點此時當前節點就是XML文檔本身因此XSLT處理器會調用XmlDocument的SelectNodes 函數來獲得要遍歷的XML節點函數的參數就是Table/Record於是我們開始循環遍歷所有的Record元素了

  在循環遍歷Record元素時對每一個Record元素都要輸出xsl:foreach的子節點首先是 tr 元素這不是XSLT元素因此原樣輸出這裡還套嵌定義了另外一個foreach元素於是我們又開始了一個新的循環遍歷了新的循環指定的相對XPath路徑是一個星號表示匹配所有名稱的子元素這類似DOS命令Dir中使用星號匹配所有文件此處表示循環遍歷Record元素下面所有的字段元素

  對每一個字段元素首先輸出td 元素然後處理xsl:valueof 元素xsl:valueof 表示輸出指定相對路徑的節點的值這裡指定的XPath是一個點號表示當前節點本身由於當前節點是XML元素因此也就輸出元素的文本內容相當於輸出XmlElement的InnerText 屬性值

    為了讓大家更清楚的了解XSLT執行過程我寫了一段C#代碼來模擬實現這個XSLT轉換過程代碼在演示程序的 codexsltaspx 中代碼如下

   // 此處代碼動態構造 xml 文檔對象結構來輸出XML文檔
SystemXmlXmlDocument XmlDoc = new SystemXmlXmlDocument();
查詢數據庫填充XmlDoc
// 保存輸出結果的緩沖區
SystemIOStringWriter myResult = new SystemIOStringWriter();
myResultWriteLine(<html>);
myResultWriteLine(    <body>);
myResultWriteLine(        <table border=>);
// 模擬 <xsl:foreach select=Table/Record>
foreach( SystemXmlXmlNode node in XmlDocSelectNodes(Table/Record))
{
    myResultWriteLine(        <tr>);
    // 模擬 <xsl:foreach select=*>
    foreach( SystemXmlXmlNode node in nodeSelectNodes(*))
    {
        myResultWrite(            <td>);
        // 模擬 <xsl:valueof select= />
        myResultWrite( nodeInnerText );
        myResultWriteLine(</td>);
    }
    myResultWriteLine(        </tr>);
}
myResultWriteLine(        </table>);
myResultWriteLine(    </body>);
myResultWriteLine(</html>);
myResultClose();

  代碼很簡單這裡我就不詳細說明了

  這裡只是展示了一個非常簡單的XSLT轉換過程XSLT和XPath語法不少但花點時間是可以記下來的編寫XSLT模板是很有技巧性的一般的我們要設計XSLT模板首先獲得要轉換的XML文檔樣本以及所需轉換結果的樣本這兩個樣本可能相差非常大所有的差別都需要依靠XSLT轉換模板來彌補此時XSLT模板的編寫不只是XSLT元素和函數的堆砌而是需要同時兼顧輸入和輸出還需要使用面向過程的編程思想有時還需要編程對XSLT轉換器進行擴展

  XML/XSLT在WEB開發中的應用

  XML/XSLT技術在WEB開發中可以發揮很大的應用可以為WEB開發提供一種新的HTML頁面生成方式

  一般的在WEB開發中使用XML/XSLT技術主要有兩種模式一個是在服務器端執行XSLT轉換另一個是在客戶端執行XSLT轉換 [NextPage]

  在服務器端執行XSLT轉換時應用系統的業務模塊生成包含要顯示的數據的XML文檔然後調用事先寫好的XSLT模板文檔執行XSLT轉換轉換結果一般是HTML文檔當然也可以是其他類型的文本文檔此時客戶端就可以將生成的HTML文檔直接作為頁面響發送到客戶端浏覽器中客戶端浏覽器接受HTML文檔並顯示出來在這個過程中服務器端生成的XML文檔XSLT轉換生成的HTML文檔都是臨時生成的文檔都可以存留在內存中用完即可清除掉不需要寫到磁盤文件中

  在客戶端執行XSLT轉換時應用系統的業務模塊生成包含要顯示的數據的XML文檔加上XSLT轉換信息標記直接發送到客戶端浏覽器客戶端浏覽器獲得這個XML文檔根據其中的XSLT轉換信息標記從服務器上下載指定名稱的XSLT文檔然後調用自己的XSLT轉換器進行轉換在內存中生成了HTML文檔並顯示出來此時顯示的HTML頁面不會出現在浏覽器的緩沖文件夾中也看不到HTML源代碼只能看到XML的源代碼

  由於XSLT轉換是國際標准在服務器端的轉換結果和在客戶端的轉換結果是一樣的因此兩種模式下浏覽器中顯示的頁面內容是一樣的

    在傳統的WEB開發中我們都是直接使用業務系統拼湊出HTML字符串來生成要顯示的HTML頁面雖然在ASPNET中大量使用Web控件來簡化開發但web控件內部還是拼湊HTML字符串的使用程序代碼來拼湊HTML字符串會影響程序代碼的可讀性很容易使得程序代碼雜亂無章而且生成的HTML可讀性差

  若使用XML/XSLT技術則可以有效的改善這種情況由於XML文檔格式檢查非常嚴格因此這就使得程序代碼生成XML文檔過程准確不得出現錯誤在這個環境下迫使程序員注意保持程序代碼質量而且生成的XML文檔不只用於生成HTML頁面還能方便的向其他程序模塊提供數據並可充當WebService

  考察WEB應用中生成的HTML代碼可以發現大量的HTML頁面中用於實現頁面各種動態效果和頁面格式的HTML代碼多於直接顯示數據的HTML代碼而且HTML代碼普遍重復這使得HTML頁面代碼臃腫文件大這會使得客戶端浏覽器下載頁面緩慢當采用XML/XSLT技術並在客戶端執行XSLT轉換時由於服務器端發送的XML文檔非常簡潔只包含純粹的數據並沒有其他冗余的代碼因此文檔小下載快與之配套的XSLT模板也是經過分析處理的代碼重復少因此XSLT文件也小這樣客戶端浏覽器以前要下載一個很大的HTML文檔而現在只要下載兩個較小的文檔這縮短了浏覽器下載數據的時間

  除了改善數據傳輸過程浏覽器自己執行XSLT轉換這樣能將一部分的工作量從服務器端轉移到客戶端此時服務器端只要快速生成包含數據的XML文檔即完成工作由於XSLT是廣泛采用的國際標准此時WEB系統能可靠的使用客戶端的運算能力從而減少服務器端運算壓力而利用客戶端長期閒置的運算能力 [NextPage]

  雖然XML/XSLT技術具有很大的優勢但在實際開發中仍然存在不小的問題其中最大的問題就是編制XSLT模板文件成本高我們在開發WEB系統中使用了很多開發工具包括VSNET的WEB窗體設計器美工人員使用的FrontPageDreamwave等等都是用於生成HTML文檔的而HTML文檔要求不嚴格很多內容還不符合XML規范因此需要使用各種方法將這些HTML文檔轉換為標准的XML文檔然後還需要分析頁面結構將這些XML文檔加工成XSLT文檔在目前的技術條件下這個過程成本比較大使得XML/XSLT技術難於推廣和普及在此建議大家多多思考如何低成本的將HTML文檔轉換為XSLT文檔

  而且XML/XSLT技術調試比較困難對開發者要求很高這也加大了這個技術的應用成本而且目前的web系統中大量使用的WEB控件沒有考慮到XML/XSLT技術這也阻礙了這種新技術的應用

  使用C#執行XSLT轉換

  在演示程序中其中有些代碼就是使用C#來執行XSLT轉換的

  recordaspx

  演示程序中recordaspx演示了在服務器端執行XSLT轉換打開這個頁面的C#代碼中在Page_Load函數中首先是查詢數據庫並生成一個包含數據的XML文檔然後我們使用了一個名為xsl的頁面參數這個參數就指定了使用XSLT模板文件若用戶指定了該參數我們開始執行XSLT轉換

  首先是創建一個XslTransform對象調用它的Load函數來加載用戶指定的XSLT模板文件然後調用它的Transform函數這個函數有四個參數第一個就是包含數據的XML文檔對象第二個是XSLT轉換參數的列表此處未用第三個就使輸出轉換結果的流對象我們就使用頁面輸出流最後一個是XML文檔解析對象此處未用

   string strXSLRef = thisRequestQueryString[xsl] ;
if( strXSLRef != null && strXSLRefLength > )
{
    // 根據頁面參數指定的XSLT樣式表名稱執行XSLT轉換
    strXSLRef = thisServerMapPath( strXSLRef );
    SystemXmlXslXslTransform transform = new SystemXmlXslXslTransform();
    transformLoad( strXSLRef );
    transformTransform( XmlDoc null thisResponseOutput null );
}

  可以看到在C#中執行XSLT轉換是非常簡單的只要創建一個XslTransform對象使用Load函數加載XSLT模板使用Transform函數來執行XSLT轉換即可

  recordxmlaspx

  演示程序中的recordxmlaspx演示了在客戶端執行XSLT轉換打開這個頁面的C#代碼在Page_Load函數中可以看到是查詢數據庫並使用XmlTextWriter輸出包含數據的XML文檔其中有這麼一段代碼首先判斷一個名為xsl的頁面參數是否存在若存在則調用xmlwriter的WriteProcessingInstruction方法輸出一段名為 xmlstylesheet的XML指令這個指令的 href 屬性值就使頁面參數指定的XSLT模板文件名

   // 輸出XSLT樣式表信息頭
string strXSLRef = thisRequestQueryString[xsl] ;
if( strXSLRef != null && strXSLRefLength > )
{
    xmlwriterWriteProcessingInstruction(
        xmlstylesheet
        type=text/xsl + strXSLRef + );
}

  客戶端浏覽器解析下載的XML文檔若遇到這個這段XML指令根據其中的href屬性下載XSLT模板文件然後執行XSLT轉換將生成的轉化結果再作為HTML文檔顯示出來

  在這個頁面中服務器端只負責輸出數據XML文檔並提供XSLT模板文件下載而XSLT轉換就給客戶端浏覽器處理這樣就能減少服務器端的工作量並利用客戶端的運算能力

  注意這裡的xmlstylesheet指令只對浏覽器有效一般其他的程序處理XML文檔時會忽略掉這個XML指令即使我們在服務器端使用XslTransform對象執行XSLT轉換這個XML指令也是毫無作用的就像不存在一樣

  使用C#執行XPath查詢

  演示程序中的recordxpathaspx就演示了使用C#執行XPath查詢打開這個頁面的界面設計可以看到其界面是比較簡單地其中一個單行文本框用於輸入XPath字符串一個大的多行文本框用於顯示查詢結果還有一個按鈕用於點擊執行操作頁面代碼主要在這個按鈕的點擊事件處理中

  雙擊這個按鈕可以看到該按鈕的點擊事件處理代碼在該處理中首先調用CreateRecordXMLDocument函數來獲得包含數據的XML文檔對象生成XML文檔的過程可以參考recordaspx的說明

  程序生成包含數據的XML文檔後在從單行的文本輸入框獲得用戶輸入的XPath字符串若用戶輸入的內容則對XML文檔的根節點調用SelectNodes方法執行XPath查詢SelectNodes函數返回一個XmlNodeList列表該列表中的元素類型是XmlNode我們遍歷這個列表對其中每一個XML節點對象獲得它的XML字符串然後進行輸出

  若用戶沒有輸入XPath字符串則直接輸出XML文檔根節點的內容

  在這裡我們定義了GetXMLString 函數這個函數主要是返回指定的XML節點對象的帶縮進的XML字符串用於取代Xml節點的OuterXml屬性

  小結

  在本課程中我們了解了XPathXML/XSLT的基礎知識並演示使用C#使用XPath和XML/XSLT技術

  XML及其派生的技術都是很重要的國際標准技術對現代WEB開發具有很大的影響力XML技術是一種優質的軟件開發技術因此大家要花點時間好好學習熟練掌握XML及其派生技術將大大提高大家的軟件開發能力


From:http://tw.wingwit.com/Article/program/net/201311/12953.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.