程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#發現之旅第三講 使用C#開發基於XSLT的代碼生成器(2)(4)

C#發現之旅第三講 使用C#開發基於XSLT的代碼生成器(2)(4)

編輯:關於C語言

現在我們根據前因後果來說明其中的過程。在XSLT文件中,唯一的一個 xsl:template模板定義塊命中XML文檔的根節點,然後使用name函數來測試當前節點的名稱是 否為Table,若不是則輸出“本模板只能用於單表”的提示信息。XSLT沒有return 語句,只能按順序執行下去,因此不管XML文檔是否正確還是繼續輸出。

接著輸出 textarea標簽,由於使用Html格式顯示代碼,而這裡使用textarea元素,我們就不用做尖括 號字符轉義了。

這裡有xsl:variable 元素,說明開始定義一個變量,該變量的名稱 是classname,也就是這個C#類的名稱。XSLT變量不是真的變量,應當算是常量,其值是不能 改變的。這裡還用到了concat函數,這是XSLT中字符串連接函數,用於將多個字符串拼湊起 來,這個函數的參數個數不固定,但必須等於或超過2個。函數裡面可以使用XPath路徑來引 用某個XML節點,用單引號來定義固定的字符串。

然後XSLT輸出代碼開頭的一些說明 性的注釋文本,這裡是用了count函數來累計所有的字段個數。接著開始輸出C#代碼了,在輸 出類型定義中使用了xsl:value-of標記來輸出類型名稱,它是用$classname來引用剛才定義 的名為classname的XSLT變量。然後我們輸出靜態屬性TableName返回數據表的名稱。

在輸出FIEldNames屬性時,我們遍歷輸出了字段名稱,這裡有個判斷,若position函數的值 大於1則在字段名稱前輸出一個逗號,position函數用於返回當前處理的節點在整個要處理的 節點列表中的從1開始的序號。若position值大於1,則表示不是輸出第一個字段名稱,由於 這裡是定義一個字符串數組的,因此需要添加逗號。

在這裡我們使用xsl:text來輸出 純文本數據,這裡輸出逗號時可以不需要使用xsl:text元素,可以直接輸出,但使用 xsl:text元素可以改善XSLT代碼的可讀性。而且xsl:text元素可以輸出連續的空白字符。

接著我們輸出myValues 變量和Values屬性,然後又開始遍歷字段輸出各個字段的屬 性代碼了。

首先我們定義了一個名為remark的變量,用於保存字段說明文本。然後輸 出字段屬性的說明性注釋,並判斷PrimaryKey元素值,若該元素值為true則輸出文本“ 關鍵字段”。然後輸出public 屬性數據類型 屬性名稱,這裡是用concat函數來連接屬 性數據類型和字段名稱,中間加了一個空格。

這裡我們使用了xsl:choose結構, xsl:choose類似C#中的swith語句,下面的xsl:when 類似C#的case 語句,而xsl:otherwise 類似C#的default語句。Xsl:choose 可以包含若干個xsl:when,而且最多包含一個 xsl:oterwise元素。每一個xsl:when都可以進行各自的判斷,這點和switch不同,更像連續 的if else ifelse 語句。

在這裡,第一個xsl:when判斷字段類型名稱是否是 System.Byte[],也就是字節數組,若是字節數組則輸出字節數組強制轉化的C#代碼。剩余的 情況使用xsl:otherwise來輸出使用Convert.To函數進行類型轉換的C#代碼。

經過上 述的XSLT轉換處理,我們就能根據描述數據表和字段設計信息的XML文檔來自動生成C#代碼了 。把這個C#代碼復制到C#工程中就可以編譯了。這段代碼內部使用一個哈西表來保存字段的 值,並使用一個個屬性來影射數據庫表的字段。

在程序目錄下存在一些類似的模板, 比如_cshapr.xslt就是生成另外一種的C#代碼的模板,在生成的代碼中不是用哈西列表保存 數據,而是是用一個個變量來保存字段數據。_java.xslt是生成Java代碼的,_VB6.xslt是生 成VB6代碼的。

_Html.xslt

程序目錄下還有其他的代碼生成器模板,例如 _HTML.xslt能生成Html代碼,能是用表格的樣式來展示多個表結構信息。該 模板有個特點就 是既能生成單個表的信息,也能生成整個數據庫中所有表的信息。該模板的XSLT代碼為

<xsl:stylesheet XMLns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output indent='yes' />
  <xsl:template match="/*">
    <xsl:for-each select="//Table">
      <xsl:call-template name="table" />
    </xsl:for-each>
   </xsl:template>
  <xsl:template name="table">
    <div>
      <span>
         <span>數據表 </span>
        <b>
           <xsl:value-of select="Name" />
         </b>
        <span> 結構,共 </span>
         <xsl:value-of select="count( Fields/FIEld )" />
         <span> 個字段 </span>
        <xsl:value -of select="concat(' ', Remark)" />
         <xsl:if test="count( Fields/FIEld[PrimaryKey='true']) > 0 ">
          <span>關鍵字段:</span>
           <b>
            <xsl:for-each select="Fields/FIEld[PrimaryKey='true']">
               <xsl:if test="position()> 1 ">,</xsl:if>
              <xsl:value-of select="Name" />
            </xsl:for- each>
          </b>
         </xsl:if>
      </span>
      <table style="border: black 1 solid"
           border="0" width="100%"
           rules='all' cellspacing="0"
           cellpadding="0" bordercolor="#000000">
         <tr bgcolor="#eeee99">
          <td width="150">字段名</td>
          <td width="80">字段類型</td>
          <td width="50">長度</td>
          <td width="80">可否為空</td>
          <td width="80">是否索引</td>
          <td>說 明</td>
        </tr>
        <xsl:for- each select="Fields/FIEld">
          <xsl:sort select="Name" />
          <tr valign="top">
            <xsl:attribute name="bgcolor">
               <xsl:iftest="position() mod 2 = 0">#eeeeee</xsl:if>
             </xsl:attribute>
             <td>
              <font>
                 <xsl:if test="PrimaryKey='true'">
                   <xsl:attribute name="color">red</xsl:attribute>
                 </xsl:if>
                <xsl:value-of select="concat(' ' , Name)" />
               </font>
            </td>
             <td>
              <xsl:value-of select="FIEldType" />
            </td>
            <td>
               <xsl:value-of select="FIEldWidth" />
             </td>
            <td>
               <xsl:if test="Nullable='true'">是</xsl:if>
            </td>
            <td>
              <xsl:if test="Indexed='true'">是</xsl:if>
             </td>
            <td>
               <xsl:value-of select="Remark" />
               <xsl:if test="Description !=''">
                 <br />
                 <xsl:value-of select="Description" />
               </xsl:if>
            </td>
           </tr>
        </xsl:for-each>
       </table>
    </div>
    <p />
   </xsl:template>
< /xsl:stylesheet>

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved