数据排序及如何动态排序

数据排序及如何动态排序

//Belltree
//http://www.lurer.net/

//初学XML,错误之处多多,各路高手多多指正

在<xsl:for-each select="//item" order-by="text()">及<xsl:apply-templates select="//item"/>中都可以看到
order-by属性,该属性可以对选出来的节点按照order-by的值进行排序.

<singer>
<title>Christina Aguilera</title>
<songs>
<item id="0" href="genieinabottle.christina.xml">Genie in a bottle</item>
<item id="1" href="whatagirlwants.christina.xml">What a girl wants</item>
<item id="2" href="iturntoyou.christina.xml">I turn to you</item>
<item id="5" href="soemotional.christina.xml">So emotional</item>
<item id="4" href="comeonover.christina.xml">Come on over</item>
<item id="3" href="reflection.christina.xml">Reflection</item>
<item id="6" href="lovefor.christina.xml">Love for all seasons</item>
<item id="7" href="somebody.christina.xml">Somebody's somebody</item>
<item id="10" href="puturhands.christina.xml">When you put your hands on me</item>
<item id="9" href="blessed.christina.xml">Blessed</item>
<item id="8" href="lovefindaway.christina.xml">Love will find a way</item>
<item id="11" href="obvious.christina.xml">obvious</item>
</songs>
</singer>

在这个例子中,如果我们需要一个按照歌名进行排序的列表,可以使用如下XSL:

<xsl:for-each select="//item" order-by="text()">
<a><xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute><xsl:value-of /></a>
<br/>
</xsl:for-each>

这样就按照每个item节点的值进行了排序,还可以使用id属性来排序,只要将order-by="text()"改为oder-by="@id"即可.

但如果我们需要让用户自己选择如何排序,甚至是不排序,即按照原始顺序.

这时就该让script和XML DOM上场了,在DOM中,有一系列的Methods和Attributes让你设置,你可以重新生成一棵树,我们就可
以利用这些东东将order-by属性的值改掉,然后再重新利用这个XSL节点对你需要的节点数据重新生成一棵树,这棵树是排序
了的,注意,order-by的值可不是原来的了,是你的新值.你甚至可以将order-by属性从XSL节点属性中去掉,这样生成的树就
是按照原始顺序了.

看看相应的XML DOM Methods:
selectSingleNode   返回单个节点
setAttribute       设置属性值,如果属性不存在,创建它并设置值
removeAttribute    移去属性
transformNode      使用相应的XSL stylesheet对该节点及其字节点进行处理后,返回一个结果树

最开始,我们要将XSL中的xsl:for-each节点选出来,并将它赋予一个变量s,好对它进行处理:
var s = document.XSLDocument.selectSingleNode("//xsl:for-each")

然后,对它的属性order-by的值从新设置:
setAttribute("order-by",key);  //key为一个变量,可以为id,text()

或者,将其删去:
removeAttribute("order-by");

哈哈,很简单吧

我们现在来看看源树中需要排序的部分,是singer/songs节点中的每个item节点,不需要选择整个树,只要singer/songs就可
以了

var xmldoc = document.XMLDocument.selectSingleNode("singer/songs");

将整个XSL树应用该节点:

divItems.innerHTML = xmldoc.transformNode(document.XSLDocument);  //错误来了

是不是要对这个节点应用整个XSL树呢?当然不必,这样也会带来错误,应为结果必须显示在某个地方,我们回头来看一看:
<xsl:template match="/">
<div id="divItems">
<div id="in">

<xsl:for-each select="//item" order-by="id">
<a><xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute><xsl:value-of /></a>
<br/>
</xsl:for-each>

</div>
</div>
</xsl:template>
我们在<xsl:for-each>的用<div>容器包住,为什么要用两个<div>呢,这个后面说明,先来看看transformNode,应用整个XSL
树会带来什么后果,这样又会重新生成一个<div id="divItems">...</div>,就会导致两个同id的div,结果是无法运行.

我们只需要选<div id="in">这个节点就够了.

var xsldoc = document.XSLDocument.selectSingleNode("//div[@id='in']");

然后将xsldoc应用到xmldoc上就成了

divItems.innerHTML = xmldoc.transformNode(xsldoc);

两个div还是有用的吧,第一个是一个显示结果的容器,第二个每次都包含在结果树中,如果没有<div id="in">直接选<div
id="divItems">就会出现和应用整个XSL树一样的错误.

最后,还是看看完整的:(具体效果请看http://go8.163.com/~belltree/test.xml)
XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>

<singer>
<title>Christina Aguilera</title>
<songs>
<item id="0" href="genieinabottle.christina.xml">Genie in a bottle</item>
<item id="1" href="whatagirlwants.christina.xml">What a girl wants</item>
<item id="2" href="iturntoyou.christina.xml">I turn to you</item>
<item id="3" href="soemotional.christina.xml">So emotional</item>
<item id="4" href="comeonover.christina.xml">Come on over</item>
<item id="5" href="reflection.christina.xml">Reflection</item>
<item id="6" href="lovefor.christina.xml">Love for all seasons</item>
<item id="7" href="somebody.christina.xml">Somebody's somebody</item>
<item id="8" href="puturhands.christina.xml">When you put your hands on me</item>
<item id="9" href="blessed.christina.xml">Blessed</item>
<item id="10" href="lovefindaway.christina.xml">Love will find a way</item>
<item id="11" href="obvious.christina.xml">obvious</item>
</songs>
</singer>

XSL:
<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

<xsl:template match="/">

<html>
<script language="javascript">
<xsl:comment>
function sort(key) {
  // Find the "for-each" attributes in the style sheet.
  var s = document.XSLDocument.selectSingleNode("//xsl:for-each");
                                            
  if (key=="")
  s.removeAttribute("order-by");
  else
  s.setAttribute("order-by",key);
  
  // Find the subset of the document we need to update.
  var xmldoc = document.XMLDocument.selectSingleNode("singer/songs");
  var xsldoc = document.XSLDocument.selectSingleNode("//div[@id='in']");
  
  // Apply the style sheet to the subset, and update the display.
  divItems.innerHTML = xmldoc.transformNode(xsldoc);
}

</xsl:comment>
</script>
<body>
<table border="1" cellspacing="0" cellpadding="1">
<tr><td>
<div id="divItems">
<div id="in">

<xsl:for-each select="//item" order-by="@id">
<a><xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute><xsl:value-of /></a>
<br/>
</xsl:for-each>

</div>
</div>
</td><td>
<input type="button" value=" Text " />
<input type="button" value=" @id " />
<input type="button" value="Origin" />
</td></tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

时间: 2024-12-20 05:42:05

数据排序及如何动态排序的相关文章

求JSP页面表格动态排序,动态显示数据的思路

问题描述 有个需求,在JSP页面上表格形式显示数据,并且可以动态排序,比如说点表头的时候是倒序,再次点击是正序.做个表格策略,并且可以让用户自定义数据列,动态显示数据(比如用户只想看到这个表的哪几行列,他可以选择,将多余的列删除).如果这两个结合又该怎么做呢?在用户自定义的数据下排序? 解决方案 解决方案二:这里的增加列,排序都好做,隐藏列的话不太好做.排序的话可以到网上查一下html表格排序,有相应的代码.相应的列显示与隐藏,是个问题,数据不知道保存在哪里好,保存在JS是可以,如果数据很长的话

XML卷之实战锦囊(1)——动态排序

排序功能让我们页面上的数据显的更人性化,是我们在网站上见过的很普遍的一个功能效果了.以往的自动排序都是用大量的脚本代码来完成的,对一般的爱好者来说这是件困难的事情.然而用XML来处理的话就简单多了.让自己的页面更加绚丽,哈哈,您是不是也心动了呢! 材料: XML卷之动态排序 有2个文件:paixu.xml 和 paixu.xsl 作用: 在不刷新页面的情况下更据用户自己的需要对数据重新进行排序显示,有效的提高数据互动功能,让自己的页面更加绚丽多彩. 代码: 以下为引用的内容: paixu.xml

XML卷之实战锦囊(1):动态排序

xml|动态|排序 动机: 排序功能让我们页面上的数据显的更人性化,是我们在网站上见过的很普遍的一个功能效果了.以往的自动排序都是用大量的脚本代码来完成的,对一般的爱好者来说这是件困难的事情.然而用XML来处理的话就简单多了.让自己的页面更加绚丽,哈哈,您是不是也心动了呢! 材料: XML卷之动态排序有2个文件:paixu.xml 和 paixu.xsl 作用: 在不刷新页面的情况下更据用户自己的需要对数据重新进行排序显示,有效的提高数据互动功能,让自己的页面更加绚丽多彩.  效果: 浏览这里 

使用 xsl 对 xml 文档进行动态排序,分页显示的扩展

xml|动态|分页|排序|显示 在 http://www.asptoday.com/articles/20000724.htm 有非常好的例子,是关于   使用 xsl 对 xml 文档进行动态排序,分页显示的.   主要使用三个文件:   default.asp 把 xml, xsl 文件串起来   getxml.asp 对 default 来说相当于 xml   sample.xsl 主要的格式编排工作在这里做   ======================================

数据库查询结果的动态排序(2)

动态|排序|数据|数据库 二.用列名字作为参数 另外一个选择是让查询以参数的形式接收一个列名字.Listing 2显示了修改后的GetSortedShippers存储过程.CASE表达式根据接收到的参数,确定SQL Server在ORDER BY子句中使用哪一个列值.注意,ORDER BY子句中的表达式并未在SELECT清单中出现.在ANSI SQL-92标准中,ORDER BY子句中不允许出现没有在SELECT清单中指定的表达式,但ANSI SQL-99标准允许.SQL Server一直允许这

数据库查询结果的动态排序(1)

动态|排序|数据|数据库 在公共新闻组中,一个经常出现的问题是"怎样才能根据传递给存储过程的参数返回一个排序的输出?".在一些高水平专家的帮助之下,我整理出了这个问题的几种解决方案. 一.用IF...ELSE执行预先编写好的查询 对于大多数人来说,首先想到的做法也许是:通过IF...ELSE语句,执行几个预先编写好的查询中的一个.例如,假设要从Northwind数据库查询得到一个货主(Shipper)的排序列表,发出调用的代码以存储过程参数的形式指定一个列,存储过程根据这个列排序输出结

数据库查询结果的动态排序(6)

动态|排序|数据|数据库 现在,如果我们用任意三个列名字之一作为参数调用存储过程,存储过程都能够正确地返回结果.Richard Romley提出了一种巧妙的处理方法,如Listing 6所示.它不再要求我们搞清楚可能涉及的列数据类型.这种方法把ORDER BY子句分成三个独立的CASE表达式,每一个表达式处理一个不同的列,避免了由于CASE只返回一种特定数据类型的能力而导致的问题. [Listing 6:用列名字作为参数,Romley提出的方法] ALTER PROC GetSortedShip

数据库查询结果的动态排序(5)

动态|排序|数据|数据库 为了解决这个问题,我们可以用前置的0补足ShipperID值,使得ShipperID值都有同样的长度.按照这种方法,基于字符的排序具有和整数排序同样的输出结果.修改后的存储过程如Listing 5所示.十个0被置于ShipperID的绝对值之前,而在结果中,代码只是使用最右边的10个字符.SIGN函数确定在正数的前面加上加号(+)前缀,还是在负数的前面加上负号(-)前缀.按照这种方法,输出结果总是有11个字符,包含一个"+"或"-"字符.前

数据库查询结果的动态排序(4)

动态|排序|数据|数据库 假设我们把更多的货主加入到表,如Listing 4所示(ShipperID列有IDENTITY属性,SQL Server自动为该列生成值). [Listing 4:向Shippers表插入一些记录] INSERT INTO Shippers VALUES('Shipper4', '(111) 222-9999') INSERT INTO Shippers VALUES('Shipper5', '(111) 222-8888') INSERT INTO Shippers