首先,請確認如下概念您都有一定的了解,當然,如果您並沒有相應的基礎,這里列出了一些基本概念和W3C相應教程的鏈接。
XML
XML 指可擴展標記語言,其被設計用來傳輸和存儲數據。
XSL
XSL 指擴展樣式表語言(EXtensible Stylesheet Language),其作用一定程度上相當於HTML中的CSS,但它不僅僅是一種樣式表語言,而是包含了如下三部分:
XSLT
XSLT 指 XSL 轉換。 既是將 XML 文檔通過 XSL 轉換為其他文檔,比如 XHTML。
XPath
XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標准的主要元素,並且 XQuery 和 XPointer 同時被構建於 XPath 表達之上。
XML Schema
XML Schema 用於描述 XML 文檔的結構,XML Schema 語言也稱作 XML Schema 定義(XML Schema Definition,XSD)。
接下來應該對上面所提到的技術或多或少有了一些了解了吧?那么就說一下我接下來想要做些什么練習題吧!哦,對了,我還用到了Bootstrap,誰讓咱美工不太好呢。
先看看東西效果。然后再清理一下思緒。接着在着手做出類似的東西來鞏固下。
界面是不怎么樣,不過咱不也不只是為了看個界面嗎,就是為了知道要做個什么東西出來。不過這可不是最終目標哦!只是其中一個課題。當然,就算到了最后,我也不能夠把我的整個項目都拿出來給大家,但是還是會很樂意給出一些自己的見解與大家一起分享,把一些做項目中做得小功課拿出來跟大家分享。
首先,先整理下這些知識點:
在XML中引用一個XSLT樣式表
1 <!-- 在XML中引入一個XSLT樣式表--> 2 <?xml-stylesheet type="text/xsl" href="xslt/catalog.xslt"?>
在一個XSLT文件中引用一個外部XSLT文件
<!-- 在一個XSLT文件中引用一個外部XSLT文件 --> <xsl:import href="path/file.xslt" />
輸出符合HTML5 標准的HTML代碼
1 <!-- 輸出符合HTML5 標准的HTML代碼 --> 2 <?xml version="1.0" encoding="utf-8"?> 3 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 4 5 <xsl:output method="html" indent="yes" /> 6 7 <!-- 將Page替換為XML根節點,即可作為XSLT入口 --> 8 <xsl:template match="/Page"> 9 <!-- 輸出符合HTML5規范的DOCTYPE --> 10 <xsl:text disable-output-escaping='yes'><!DOCTYPE html></xsl:text> 11 <html lang="zh-cn"> 12 <head> 13 <meta charset="utf-8" /> 14 <title> 15 <xsl:value-of select="@Title"/> 16 </title> 17 <link href="css/bootstrap.min.css" rel="stylesheet" /> 18 <link href="css/bootstrap-responsive.min.css" rel="stylesheet" /> 19 <script src="js/jquery-1.7.1.min.js"></script> 20 <script src="js/bootstrap.min.js"></script> 21 </head> 22 <body> 23 <!-- 根據XML節點自動應用符合條件的模板 --> 24 <xsl:apply-templates select="*"></xsl:apply-templates> 25 </body> 26 </html> 27 </xsl:template> 28 29 </xsl:stylesheet>
匹配當前節點的 XSLT 模板
1 <!-- 匹配當前節點的 XSLT 模板 --> 2 <xsl:template match="//TextField"> 3 </xsl:template>
命名的XSLT模板以及如何調用命名的XSLT模板
<!-- 命名的XSLT模板 --> <xsl:template name="named-template"> </xsl:template> <!-- 調用命名的XSLT模板 --> <xsl:call-template name="named-template"></xsl:call-template>
整理上面提到的知識點時,就不得不對XSLT的模板多加思考下,於是就想,如果一個空間的表現、數據綁定、交互都能有它們的定義,我們能僅僅只是組合這些定義,具體的操作事先已經被封裝到XSLT的模板里面,那該多好呢!
哦!想法不錯,那如果基礎不牢固怎么辦呢?先做第一個功課,來鞏固一下XSLT相關的知識好嗎?順便也多想想現有方案的缺點,一起找出更好的解決方案。於是,我做了如下設想:
呵呵,XSD能想到怎么定義了嗎?要不我把我的先拿上來吧,不過臨時定義的,邏輯很不嚴謹。而且結構也非常不好。不過又說回來了,我上來就哪個完美的,接下來還學習什么呢?就啃它嗎?

1 <?xml version="1.0" encoding="utf-8"?> 2 <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 3 <xs:element name="Page"> 4 <xs:complexType> 5 <xs:sequence> 6 <xs:element ref="Container"></xs:element> 7 </xs:sequence> 8 <xs:attribute name="Title" type="xs:string" use="required" /> 9 </xs:complexType> 10 </xs:element> 11 <xs:element name="Container"> 12 <xs:complexType> 13 <xs:sequence> 14 <xs:element ref="Form"></xs:element> 15 </xs:sequence> 16 <xs:attribute name="fluid" type="xs:boolean" use="required" /> 17 </xs:complexType> 18 </xs:element> 19 <xs:element name="Form"> 20 <xs:complexType> 21 <xs:sequence> 22 <xs:element maxOccurs="unbounded" ref="Group"></xs:element> 23 <xs:element ref="Row"></xs:element> 24 </xs:sequence> 25 <xs:attribute name="Layout" type="xs:string" use="required" /> 26 <xs:attribute name="Title" type="xs:string" use="required" /> 27 </xs:complexType> 28 </xs:element> 29 <xs:element name="Group"> 30 <xs:complexType> 31 <xs:sequence> 32 <xs:element maxOccurs="unbounded" ref="Row"></xs:element> 33 </xs:sequence> 34 <xs:attribute name="Title" type="xs:string" use="required" /> 35 </xs:complexType> 36 </xs:element> 37 <xs:element name="Row"> 38 <xs:complexType> 39 <xs:sequence> 40 <xs:element maxOccurs="unbounded" ref="Cell"></xs:element> 41 </xs:sequence> 42 </xs:complexType> 43 </xs:element> 44 <xs:element name="Cell"> 45 <xs:complexType> 46 <xs:sequence> 47 <xs:element minOccurs="0" ref="OptionGroup"></xs:element> 48 <xs:element minOccurs="0" ref="Dropdown"></xs:element> 49 <xs:element minOccurs="0" ref="TextField"></xs:element> 50 <xs:element ref="Actions"></xs:element> 51 </xs:sequence> 52 <xs:attribute name="Cols" type="xs:unsignedByte" use="required" /> 53 </xs:complexType> 54 </xs:element> 55 <xs:element name="Option"> 56 <xs:complexType> 57 <xs:attribute name="Multy" type="xs:boolean" use="required" /> 58 <xs:attribute name="Label" type="xs:string" use="required" /> 59 <xs:attribute name="GroupName" type="xs:string" use="required" /> 60 </xs:complexType> 61 </xs:element> 62 <xs:element name="OptionGroup"> 63 <xs:complexType> 64 <xs:sequence> 65 <xs:element maxOccurs="unbounded" ref="Option"></xs:element> 66 </xs:sequence> 67 <xs:attribute name="Title" type="xs:string" use="required" /> 68 </xs:complexType> 69 </xs:element> 70 <xs:element name="Dropdown"> 71 <xs:complexType> 72 <xs:sequence> 73 <xs:element maxOccurs="unbounded" name="Option"> 74 <xs:complexType> 75 <xs:attribute name="Text" type="xs:string" use="required" /> 76 <xs:attribute name="Value" type="xs:unsignedByte" use="required" /> 77 </xs:complexType> 78 </xs:element> 79 </xs:sequence> 80 <xs:attribute name="Label" type="xs:string" use="required" /> 81 <xs:attribute name="Caption" type="xs:string" use="required" /> 82 <xs:attribute name="Cols" type="xs:unsignedByte" use="required" /> 83 <xs:attribute name="Multy" type="xs:boolean" use="required" /> 84 </xs:complexType> 85 </xs:element> 86 <xs:element name="TextField"> 87 <xs:complexType> 88 <xs:attribute name="Label" type="xs:string" use="required" /> 89 <xs:attribute name="Cols" type="xs:unsignedByte" use="required" /> 90 </xs:complexType> 91 </xs:element> 92 <xs:element name="Actions"> 93 <xs:complexType> 94 <xs:sequence> 95 <xs:element maxOccurs="unbounded" ref="Action"></xs:element> 96 </xs:sequence> 97 </xs:complexType> 98 </xs:element> 99 <xs:element name="Action"> 100 <xs:complexType> 101 <xs:attribute name="Caption" type="xs:string" use="required" /> 102 </xs:complexType> 103 </xs:element> 104 </xs:schema>
接下來給出個思路和代碼,比如Form:
Form出現在什么位置不是我們所能確定的,但是我們可以要求用XML表達的時候一定用Form節點。
Form里面出現的內容我們也不能規定死,因為我們可能不僅僅想放表單元素,甚至還想放些東西布局是不,雖然說XSD定義的並不支持那么多,但是哪個XSD也只是我臨時定義的,而且結構不合理。之后我要有時間會盡量多花些時間定義些相對好些的XSD。
好了,思路有了, 實現也不會難到那里去吧! Form位置的不確定性和XML中規定使用Form節點表示正好表達了要我們使用一個匹配當前Form節點的模板,別忘了還有個Title,至於Action什么的現在都先不考慮,現在只管呈現! Form里面不管放了什么內容, 都先給它呈現吧!像這樣是不?
1 <xsl:template match="//Form"> 2 <form> 3 <fieldset> 4 <legend> 5 <xsl:value-of select="@Title"/> 6 </legend> 7 8 <xsl:apply-templates select="*"></xsl:apply-templates> 9 10 </fieldset> 11 </form> 12 </xsl:template>
也許你會覺得Form這種東西本來就比較簡單, 再加上去掉了Method,ACTion等東西,也就不用什么邏輯就寫出來了。拿在看個有點邏輯的吧。 單選框組好不?那里面東西稍多些。其實不也就是一個標簽, 加上一堆單選輸入組件嗎。只要name相同,就實現了單選了, 哦,復選也差不多哦。就放一起了。挺晚了,我還是少說點,直接上代碼,您稍稍看看也就明白了。因為這次說的本來就是簡單的東西的。

1 <xsl:template match="//OptionGroup"> 2 <div class="control-group"> 3 <xsl:if test="string-length(@Title) > 0"> 4 <label class="control-label"> 5 <xsl:value-of select="@Title"/> 6 </label> 7 </xsl:if> 8 <div class="controls"> 9 <xsl:for-each select="Option"> 10 <xsl:call-template name="option-template"> 11 <xsl:with-param name="groupName" select="@GroupName"></xsl:with-param> 12 </xsl:call-template> 13 </xsl:for-each> 14 </div> 15 </div> 16 </xsl:template> 17 18 <xsl:template name="option-template"> 19 <xsl:param name="groupName"></xsl:param> 20 <xsl:if test="@Multy != 'true'"> 21 <label class="radio inline"> 22 <input type="radio"> 23 <!--<xsl:if test="$groupName">--> 24 <xsl:attribute name="name"> 25 <xsl:value-of select="$groupName"/> 26 </xsl:attribute> 27 <!--</xsl:if>--> 28 <xsl:if test="@Selected"> 29 <xsl:attribute name="checked"> 30 <xsl:value-of select="'checked'"/> 31 </xsl:attribute> 32 </xsl:if> 33 </input> 34 <xsl:value-of select="@Label"></xsl:value-of> 35 </label> 36 </xsl:if> 37 <xsl:if test="@Multy = 'true'"> 38 <label class="checkbox inline"> 39 <input type="checkbox"> 40 <xsl:if test="@Selected"> 41 <xsl:attribute name="checked"> 42 <xsl:value-of select="'checked'"/> 43 </xsl:attribute> 44 </xsl:if> 45 </input> 46 <xsl:value-of select="@Label"></xsl:value-of> 47 </label> 48 </xsl:if> 49 </xsl:template>
簡單不?哦,數據綁定還沒加呢。先不考慮SEO吧。因為我做這個的目的是考慮AJAX項目快速開發的。當然,做非AJAX的會更加舒適,因為可以直接拿來XML當數據啊。讓后XSLT轉換啊。不過操作都在客戶端的AJAX項目也不用太愁,誰讓那么多有智慧又有愛心的人已經給我們准備好了那么多好用的Javascript庫呢。
先看看這個KnockoutJS (教程 | 文檔)怎么樣,要不您找個更好的也行,反正也就一類庫,就算自己寫,只要功能能實現,足夠穩定都是可以的,不是嗎?