XML技術在界面生成中的簡單應用(XSLT相關)1


  先,請確認如下概念您都有一定的了解,當然,如果您並沒有相應的基礎,這里列出了一些基本概念和W3C相應教程的鏈接。

XML

  XML  指可擴展標記語言,其被設計用來傳輸和存儲數據。

XSL

  XSL 指擴展樣式表語言(EXtensible Stylesheet Language),其作用一定程度上相當於HTML中的CSS,但它不僅僅是一種樣式表語言,而是包含了如下三部分:

  1. XSLT(一種用於轉換 XML 文檔的語言)
  2. XPath(一種用於在 XML 文檔中導航的語言)
  3. XSL-FO(一種用於格式化 XML 文檔的語言)

XSLT

  XSLT 指 XSL 轉換。 既是將 XML 文檔通過 XSL 轉換為其他文檔,比如 XHTML

XPath

  XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標准的主要元素,並且 XQueryXPointer 同時被構建於 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'>&lt;!DOCTYPE html&gt;</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能想到怎么定義了嗎?要不我把我的先拿上來吧,不過臨時定義的,邏輯很不嚴謹。而且結構也非常不好。不過又說回來了,我上來就哪個完美的,接下來還學習什么呢?就啃它嗎?

 

View Code
  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相同,就實現了單選了, 哦,復選也差不多哦。就放一起了。挺晚了,我還是少說點,直接上代碼,您稍稍看看也就明白了。因為這次說的本來就是簡單的東西的。

View Code
 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 (教程 | 文檔)怎么樣,要不您找個更好的也行,反正也就一類庫,就算自己寫,只要功能能實現,足夠穩定都是可以的,不是嗎?

源代碼很亂,我就先扔這里了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM