以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 精华版 』  (http://bbs.xml.org.cn/list.asp?boardid=37)
----  [020202010]xsl入门的好文章  (http://bbs.xml.org.cn/dispbbs.asp?boardid=37&rootid=&id=7892)


--  作者:yuji1998
--  发布时间:5/27/2004 2:40:00 AM

--  [020202010]xsl入门的好文章
[原作者:宇宙人]
             [疑问点击]    [意见箱]
你从本文中学到的最重要的一点是XSL不仅仅是应用样式。当使用XML处理器时,XSL源文档中的信息将被评价、重新安排,然后重新组装。我们最终得到的不只是XML数据的可爱的版本 - 而是可以被容易地添加、修改和重新排序的灵活的源信息。这个最终产品叫做结果树(Result Tree)。

这通过一系列测试产生。下面是一个简单的例子:

   <xsl:template match="recipe_name">
     <P>
       <xsl:process-children/>
     </P>
   </xsl:template>

最先要解释的是以"/" 结束的标记符是空的。即此种类型的标记符的起始和结束标记符之前什么也不发生。在HTML中类似的例子是<img>标记符。因为一个图像所需的所有信息都包含在一个标记符中,所以就没有必要存在结束标记符</img>。组织良好的XML文档可以接受空标记符,同时XSL样式表必须是组织良好的XML。

让我们再回到例子,它告诉XSL处理器如果发现一套<recipe_name>标记符,就应该分离出内容然后用<p>和</p>包围起来。或者,如果你想炫耀你的XSL的知识,你可以说“添加到结果树中。”

这是一个相当简单的测试,而且很典型。XML元素的内容被表现信息所包围。

现在让我们看看书写菜谱的XSL样式表的完整例子。

在我讲述更多的XSL标记之前,我要解释一个可能被问到的问题。谁都知道在HTML中<p>本身就足够了,那么我为什么要使用结束的</p>标记符呢?

有人能回答吗?答案是:没有对应的结束标记符,那部分就不是组织良好的XML,于是会产生一个致命的错误。
[center]第三节:一个XSL样式表 [/center]
下面是一个完整的样式表。

<xsl:stylesheet>
   <xsl:template match = "/">
     <HTML>
     <BODY>
         <xsl:process-children/>
     </BODY>
     </HTML>
   </xsl:template>
   <xsl:template match = "author">
         <H1>
         <xsl:process-children/>'s fabulous
         </H1>
   </xsl:template>
   <xsl:template match = "recipe_name">
      <H2>
      <xsl:process-children/>
      </H2>
   </xsl:template>
   <xsl:template match = "meal">
      <TABLE><TR><TD><H3>EAT FOR:</H3></TD>
      <TD><H3><xsl:process-children/></H3></TD>
      </TR></TABLE>
   </xsl:template>
   <xsl:template match = "directions">
      <H4>DIRECTIONS</H4>
      <P>
      <xsl:process-children/>
      </P>
   </xsl:template>
   <xsl:template match = "ingredients">
       <B>INGREDIENTS</B><BR></BR>
       <xsl:process-children/>
   </xsl:template>
   <xsl:template match = "item">
       <BR>
      <xsl:process-children/>
      </BR>
   </xsl:template>
</xsl:stylesheet>


其结果不会使我得到任何设计奖,但是它是一个能起作用的XSL。这里可能只有下面的命令需要解释:

  <xsl:template match = "/">
    <HTML>
     <BODY>
         <xsl:process-children/>
     </BODY>
     </HTML>
</xsl:template>

第一行的"/"告诉处理器这个节点应用到XML文档的根上。于是,这部分中的命令是结果树的基础。处理器被告之把<HTML>和<BODY>标记符放在文档的开始和结尾处,然后处理或打印所有的子元素。因为它是根元素,所以意味着“打印所有的东西。”

现在,如果你考虑几秒钟,就会觉得有点古怪。如果根层的process-children命令把源代码传递给结果树,那么所有与模板匹配的节点都可以与已经经过处理的源码一起工作。

然而,出现的问题是:XSL有一套确定哪些内容被传递给结果树的规则,其中最重要的规则是,最特定的匹配将会赢。显然,元素名的模板匹配比根层的匹配更特定。因此,所有模板匹配的节点将超越根层的规则。

注意用XML数据添加HTML标记符是多么的容易。当XSL处理器看到那些不在XSL词汇表中的标记符时,就会把他们传递给结果树。如果你花些时间,就可能发现其中巨大的潜力。XSL可以被用做一种转换语言。存储在一个XML文件中的数据可以用完全不同的标记符转换到另一个文件中。还有,信息可以被修改成与可以对应一套不同的标记符集的XML应用程序一起工作的形式。

而且还不只这些,如人们所期望的,样式表可以用匹配的标记符打开和关闭,其中是一套组织良好的单元。 很好,但是还有限制。

[center]第四节:选择XSL[/center]
简单的<xsl:template match>还不能完全满足我们的要求。比如,我希望当<course>标记符出现时取消<meal>标记符的内容。这样的话我就不用担心节面上同时显示"dinner"和"appetizer"。我可能还希望通过在最后的ingredient后面插入大量的空白来调整版面。

如同某个广告部的人说的:所有这些都是可能的 - 还要更多。SL有一套用来把元素与其父成员或子成员匹配的工具。它也允许位置上的匹配。例如,可以在第一个和最后一个某个特定元素上应用特定的格式,等等。

现在让我们考虑一些更复杂的事,比如令我在梦中出汗的任务。我需要菜谱名和它们的成分的清单。现在,如果我的网页与数据库没有联系,我就不得不写一个查询语句。因为我对SQL不太熟,所以需要得到的DBA帮助。但是如果知道XSL,我就会摆脱这些麻烦。

<xsl:style sheet>
   <xsl:template match = "/">
      <xsl:for-each select ="list/recipe">
         <TABLE>
         <TR><TD>
         <xsl:process select = "recipe_name"/></TD>
         <TD>
            <xsl:for-each select = "ingredients/item">
               <BR><xsl:process-children/></BR>
            </xsl:for-each>
         </TD></TR>
         </TABLE>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

结果并不神奇。但是在table标记符中加些花样将没问题。显然,我在XML中存储了信息,但是我认为最好还是仔细看看。

   <xsl:template match = "/">
      <xsl:for-each select ="list/recipe">

第一行很熟悉,只是简单地与模板相匹配。但是第二行却有些不同 - 在元素清单中出现的每个菜谱元素做每件事,直到</xsl:for-each>标记符。然后我开始HTML表格,用<xsl:process select="recipe_name"/>标记符把recipe_name元素中的内容输出到表格单元中。在关闭第一个表格单元后,事情开始变酷。下一行(<xsl:for-each select="ingredient/item">)开始一个附加的嵌套循环,允许我把全部ingredient输出到合适的显示信息中。样式表的其余部分应该很好理解。

但是等等,我知道你在想:“他说过酷了吗?什么这么酷?”

for-each函数是XSL的几个程序化的特征之一。还有if-then和选择函数。这些特征允许任何人都可以以任何能想到的方式(或至少是可行的方式)容易地操纵XML内容。如果你能实现这些特征,就很酷。

[center]第五节:从规范到实现[/center]
既然你已经看到XML的一些功能,那么我想提出一个问题:通过把内容分离到组织良好和有效的XML文件中,XML对这些内容有哪些不能做的呢?如我前面显示的,数据可以被操纵然后放入你选择的版面中。或者数据可以被处理成可以被其它应用程序使用的形式。那么,还有其它的吗?

我们再一次面对扩展性的核心。一旦定义了数据,我们可以做任何想做的事。如果我们来到一个有能处理XML的字处理、电子表格和表现程序的时代,同一套数据几乎可以被用在任何用途上。

但是,哎!这依然是个梦。

我们只能希望浏览器能实现这些功能,但是我们没有理由乐观。即使Tim Bray,XML的教父,也说过对XSL的尝试只能在CSS标准完全实现之后才能实现。谁知道什么时候才能实现呢?而且这也不是唯一的问题。

XSL要排除另一个障碍。XSL规范有两个截然不同的部分。第一部分,是我们这里讨论的,处理数据结构。另一部分是一套用来应用样式的有格式的对象。这部分需要做大量工作。在我看来,现在需要很多人去做很多事。例如,应该有既适合屏幕又适合打印输出的命令。如果规范的制定者继续这种“无所不包”的尝试,此规范将最终很难实现,而且最终用户用起来也困难。但是现在,我们做不了什么 - 只能过我们自己快乐的小日子,同时盼望负责的同志们别把事情弄糟。


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
46.875ms