当前位置: 首页 > 图文教程 > XML家族 > XSLT > XSL中的条件模板
在XSL选择XML中的元素进行转换和输出的时候,经常会遇到将选择XML中满足一定条件的节点。我们使用的基本方法是先定义一个模板(<xsl:template>),然后在匹配的条件下应用该模板(<xsl:apply-templates>)。 我们举典型的股票信息的示例来说明:
定义模板和应用模板
下面的股票XML文档(portfolio.xml)中给出由各股票元素(<stock>)组成,有股票的代码(symbol)、名称(name)和当前价格(price),另外还有exchange属性。
<?xml version="1.0"?>
<portfolio>
<stock exchange="nyse">
<name>zacx corp</name>
<symbol>ZCXM</symbol>
<price>28.875</price>
</stock>
<stock exchange="nasdaq">
<name>zaffymat inc</name>
<symbol>ZFFX</symbol>
<price>92.250</price>
</stock>
<stock exchange="nasdaq">
<name>zysmergy inc</name>
<symbol>ZYSZ</symbol>
<price>20.313</price>
</stock>
</portfolio>
最简单的情况,我们需要把这些股票以表格的形式输出成为XHTML在IE中显示。我们可以这样编写XSL(portfolio.xsl):
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"">
<xsl:template match="/">
<HTML>
<BODY>
<TABLE BORDER="2">
<TR>
<TD>Symbol</TD>
<TD>Name</TD>
<TD>Price</TD>
</TR>
<xsl:apply-templates />
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="portfolio/stock">
<TR>
<TD><xsl:value-of select="symbol"/></TD>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
</TR>
</xsl:template>
</xsl:stylesheet>
然后在portfolio.xml的开头(第二行)添加如下的处理指令:
<?xml-stylesheet type="text/xsl" href="portfolio.xsl"?>
在IE中浏览portfolio.xml文档将看到如下的结果:
Symbol Name Price
ZCXM zacx corp 28.875
ZFFX zaxffymat inc 92.250
ZYSZ zysmergy inc 20.313
<xsl:template match="/">匹配了XML中的文档根元素,它将整个XML文档通过XSL转换为一个(X)HTML文档。在该HTML中用表格来输出。第一行是固定的,<xsl:apply-templates/>表示将遍历当前节点的子节点,在得到匹配的模板时应用该模板。在这里,因为<xsl:template match="/">所在的是根元素,所以它将遍历所有的节点。我们定义了<xsl:template match="portfolio/stock">就是前面的模板将应用的对象。对于每个portfolio的stock自元素,将输出为表格中的一行。而各列将分别输出其symbol,name和price子元素的内容。
在以上的匹配条件中只是遍历XML文档取出适合位置的内容。并没有更多的条件判断,比如说我们要选择出在NASDAQ上市的股票并给予特殊特殊的标记那该怎么表达呢?XSL中提供了条件判断和选择的元素:<xsl:if>和<xsl:choose>元素。
<xsl:if> 元素的作用是在输出树中有条件的插入一定的结构。在下面的XSL例子中,我们在原来的基础上添加了一个<xsl:if>元素,该<xsl:if> 元素在NASDAQ上市的股票后插入了一个 "*"符号。<xsl:if> 元素的内容可以是简单的文本,如例子中所示,或者也可以是元素、属性和其它任何XSL允许的结构。
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"">
<xsl:template match="/">
<HTML>
<BODY>
<TABLE BORDER="2">
<TR>
<TD>Symbol</TD>
<TD>Name</TD>
<TD>Price</TD>
</TR>
<xsl:apply-templates />
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="portfolio/stock">
<TR>
<TD>
<xsl:value-of select="symbol"/>
<xsl:if test="@exchange[.='nasdaq']">*</xsl:if>
</TD>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
</TR>
</xsl:template>
</xsl:stylesheet>
转换的结果如下:
Symbol Name Price
ZCXM zacx corp 28.875
ZFFX* zaxffymat inc 92.250
ZYSZ* zysmergy inc 20.313
其中的test属性采用了是XSL的模式(pattern)表达式。当由该模式描述的查询选择到了一个或多个节点时,<xsl:if>模板将起作用,即将其包含的节点嵌入。如果选择的结果为空,该条件判断将省略。在这个例子中,"exchange[.='nasdaq']"将检查stock元素是否有"exchange" 属性,并且该属性的值为"nasdaq"。
在<xsl:if>元素只有两种选择,而如何要有多种选择单靠一个<xsl:if>元素就不能胜任了,<xsl:choose>就是在多种条件中进行判断选择的。<xsl:choose>包含了一组<xsl:when>元素,在test中属性中将规定各种条件,在测试时将从顶至底依次匹配直到找到满足的条件。如果所有的<xsl:when>元素都不满足要求,则应用 <xsl:otherwise> 元素。
现在我们要根据股票的价格标明不同的颜色可以添加<xsl:choose>元素,把<xsl:template match="porfolio/stock">修改为:
<xsl:template match="portfolio/stock">
<TR>
<xsl:attribute name="STYLE">color:
<xsl:choose>
<xsl:when test="price <= 25]">green</xsl:when>
<xsl:when test="price <= 50]">blue</xsl:when>
<xsl:otherwise>red</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<TD>
<xsl:value-of select="symbol"/>
<xsl:if test="@exchange[.='nasdaq']">*</xsl:if>
</TD>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
</TR>
</xsl:template>
其中把根据price元素的值,把股价从0-25的显示为绿色,25-50的显示为兰色,50以上的为红色。修改颜色的方法是根据不同的条件修改表格行的STYLE属性。
输出的结果如下:
Symbol Name Price
ZCXM zacx corp 28.875
ZFFX* zaxffymat inc 92.250
ZYSZ* zysmergy inc 20.313
条件组合选择
不论是<xsl:if>还是<xsl:when>中的test属性的值都是用XSL中的模式来表达的,确切的说是XPath语句,不过我们 常常使用XPath的简略形式。详细的XPath的语法可以参考XPath规范 。
有时,模式中指定的条件可能不止一项,对于这样的要求该如何表达呢?
例如我们要选择在NASDAQ上市并且股价小于25的股票,加上一列WARN提醒股民该股票价格较低(不过25元的股价在2001年的NASDAQ也不低了;-)。我们将把这个XSL修改为:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"">
<xsl:template match="/">
<HTML>
<BODY>
<TABLE BORDER="2">
<TR>
<TD>Symbol</TD>
<TD>Name</TD>
<TD>Price</TD>
<TD>WARN</TD>
</TR>
<xsl:apply-templates />
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="portfolio/stock">
<TR>
<TD><xsl:value-of select="symbol"/></TD>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
<TD>
<xsl:if test="price <= 25 and @exchange[.='nasdaq']">
<font color="red">WARN</font>
</xsl:if>
</TD>
</TR>
</xsl:template>
</xsl:stylesheet>
在<xsl:if test="price <= 25 and @exchange[.='nasdaq']">语句中,我们看到XSL的模式同样也可以支持条件组合的匹配,两者用and进行逻辑与,表示既要满足股价小于等于25而且exchange属性值为"nasdaq"。输出结果是这样的:
Symbol Name Price WARN
ZCXM zacx corp 28.875
ZFFX zaxffymat inc 92.250
ZYSZ zysmergy inc 20.313 WARN
以上代码在IE5.5/XML Spy 3.5/MS XML Parser 3.0环境下测试通过。而且所有的代码都遵循XSLT和XPath的规范(包括元素、属性和名域规定等)。你也可以亲自尝试一下!
评论 (0) All