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

来源:互联网 发布:风险判定矩阵表 编辑:程序博客网 时间:2024/05/01 19:35

问题提出:

    有一个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 数据五 

 

 


原创粉丝点击