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 (教程 | 文档)怎么样,要不您找个更好的也行,反正也就一类库,就算自己写,只要功能能实现,足够稳定都是可以的,不是吗?

源代码很乱,我就先扔这里了!

posted @ 2012-11-06 23:30  龍之韻  阅读(3257)  评论(4编辑  收藏  举报