把结点按索引是奇、偶数来分列显示

问题提出:

有一个XML,下面有n个结点(n>=1),用XSL将这n个结点转换到HTML的Table标记中,这个Table有两列,左边的列放入第1、3、5……个结点,右边的列放第2、4、6……个结点。

分析:

Table是Rows(<tr>)的集合,row是Cells(<td>)的集合,根据这个特点,企图直接按结点索引的奇偶将结点找到,然后生成列的方法是不可行的。

应该按Rows来生成Table。

n可能为奇数,也可能为偶数,因为n>=1 ,故Rows的总数等于n中的奇数个数。

程序流程为,一个for-each循环,判断是否为奇数结点,判断结果为真,则新建一个row;在新建row之后,创建两个cell,第一列放入奇数结点,第二列放入该奇数结点的下一个结点。主要用到xsl:for-each和xsl:variable两个XSLT元素。

XML代码:

<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type='text/xsl' href='3.xsl'?>
<subject>
<class>
<classid>1</classid>
<text>数据一</text>
</class>
<class>
<classid>2</classid>
<text>数据二</text>
</class>
<class>
<classid>3</classid>
<text>数据三</text>
</class>
<class>
<classid>4</classid>
<text>数据四</text>
</class>
<class>
<classid>5</classid>
<text>数据五</text>
</class>
</subject>

XSL代码:

<?xml version='1.0' encoding='gb2312'?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/TR/REC-html40"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table border ="1">
<xsl:for-each select="//class">

<xsl:if test="(position() mod 2 = 1)">
<xsl:variable name="n" select="position()"/>
<tr><td><xsl:value-of select="."/></td>
<td><xsl:value-of select="//class[$n+1]" /></td></tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

运行结果是:

1 数据一 2 数据二
3 数据三 4 数据四
5 数据五


优化上面的XSL

上面的方法检索N个结点,效率不是很高。直接用Xpath查询查到奇数结点,检索次数会减少一半。于是有了下面这个XSL:

<?xml version='1.0' encoding='gb2312'?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/TR/REC-html40"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table border ="1">
<xsl:apply-templates select="//class[position() mod 2 = 1]" />
</table>
</xsl:template>
<xsl:template match="//class[position() mod 2 = 1]">
<xsl:variable name="n" select="position()"/>
<tr><td><xsl:value-of select="."/></td>
<td><xsl:value-of select="//class[$n+1]" /></td></tr>
</xsl:template>
</xsl:stylesheet>

运行结果是:

1 数据一 2 数据二
3 数据三 3 数据三
5 数据五 4 数据四


这是为什么呢?position函数将返回该结点的索引,难道不对吗?注意,索引的建立取决于该结点的父母是谁,在上文提到的两个XSL中,结点的父母分别是//class与//class[position() mod 2 = 1],所以第二个XSL没有生成预期结果。

在第二个XSL中,该结点的possition与该结点在父母结点的索引的换算公式如下:n=2 * position() -1,那么该结点的下一个兄弟结点就是2 * position() 。我们把 <xsl:value-of select="//class[$n+1]" />修改成<xsl:value-of select="//class[$n * 2]" />,这样输出结果就正确了。

运行结果是:


1 数据一 2 数据二
3 数据三 4 数据四
5 数据五


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值