Adobe Spry 中文文档库 -- 使用Spry XML数据集(上)
使用Spry XML数据集
Spry XML数据集是一个JavaScript对象,可以使用它在WEB页面上显示XML数据文件中的数据。你可以用这个数据根据访问者的选择在页面的主要和详细区域中更新数据。你可以访问 Adobe LiveDocs获得本文的最新版本。
Spry XML数据集基本概要
Spry数据集就是一个JavaScript对象。你在WEB页面里用少量的代码就可以使浏览器在打开页面时创建对象并装载XML源到对象中。数据集的结果在一个平面的数组中并可以表现为一个包含行和列的标准表。
假设你有一个XML源文件cafetownsend.xml, 其中包含下列内容:
<?xml version="1.0" encoding="UTF-8"?> <specials> <menu_item id="1"> <item>Summer Salad</item> <description>organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette.</description> <price>7</price> </menu_item> <menu_item id="2"> <item>Thai Noodle Salad</item> <description>lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.</description> <price>8</price> </menu_item> <menu_item id="3"> <item>Grilled Pacific Salmon</item> <description>served with new potatoes, diced beets, Italian parlsey, and lemon zest.</description> <price>16</price> </menu_item> </specials>
使用XPath来指示你所感兴趣的数据(在这个范例中,关注的节点为specials/menu_item),数据被平面化到一个对象数组中,对象为行,属性为列,表现为下表:
@id |
item |
description |
price |
---|---|---|---|
1 |
Summer salad |
organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette. |
7 |
2 |
Thai Noodle Salad |
lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions. |
8 |
3 |
Grilled Pacific Salmon |
served with new potatoes, diced beets, Italian parlsey, and lemon zest. |
16 |
这个数据集包含每个菜单项,每行为一个菜单项,包含的列有:@id, item, description, 和 price。列表现为XML中specials/menu_item节点下的子节点,附加了一些属性和子标记在menu_item标记里。
这个数据集包含了一个内建的数据参考(built-in data references)称作ds_RowID(不显示),当显示数据时会变的非常有用。另外数据集也包含了其他的内建数据参考(built-in data references),例如:ds_RecordCount, ds_CurrentRow等,你可以用他们来操作数据显示。
你通过Spry.Data.XMLDataSet和XPath创建一个Spry数据集。XPath定义数据集的缺省结构,作为例子,如果你用XPath指定一个包含3个子节点的重复XML节点,那么每一个重复的XML节点将表现为数据集中的一行,3个子节点将表现为列。(数据集会创建列来表示任何重复节点或子节点所包含的属性)
如果你没有指定一个XPath,那么XML源中的所有数据将被包含在数据集中。
数据集被创建后,它可以让你容易的管理和显示数据。做范例,你可以创建一个简单的表来显示XML数据,并用简单的方法和属性去重载(reload)、排序、过滤(filter)或页面显示。
下面的范例中,创建了一个叫dsSpecials的Spry数据集,并且从cafetownsend.xml中装载数据:
<head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Spry Example</title> <!--Link the Spry libraries--> <script type="text/javascript" src="includes/xpath.js"></script> <script type="text/javascript" src="includes/SpryData.js"></script> <!--Create a data set object--> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); </script> </head> . . . <body> </body>
注意:以上范例仅仅用于示意,可以运行的范例请查看Adobe Labs中的Spry栏目下的demos栏目。
在这个范例中,第一个script标记链接了一个开源的XPath库用于XML数据的显示。XPath库允许你在创建数据集时使用复杂的Xpath:
<script type="text/javascript" src="includes/xpath.js"></script>
第二个scrip块链接了SpryData.js,Spry数据操作库, 它存储于includes目录下:
<script type="text/javascript" src="includes/SpryData.js"></script>
Spry数据操作库以来于XPath库,所以必须先引用XPath库。
第三个script块用于创建一个dsSpecials数据集,cafetownsend.xml文件存储在data目录中:
var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");
注意:JavaScript和XML都是大小写敏感的,请在书写脚本和列名时注意大小写。
在JavaScript中,使用new操作符来创建对象。Spry.Data.XMLDataSet包含在Spry数据操作库(Spry data library)中。其构造器有两个参数:数据源 ("data/cafetownsend.xml",这里是一个相对路径) 和用于指定XML中节点的XPath表达式("specials/menu_item")
In JavaScript the new operator is used to create objects. The Spry.Data.XMLDataSet method is a constructor in the Spry data library that creates new Spry data set objects. The constructor takes two parameters: the source of the data ("data/cafetownsend.xml", in this case, a relative URL) and an XPath expression that specifies the node or nodes in the XML to supply the data ("specials/menu_item").
你也可以指定一个XML数据文件的绝对路径:
var dsSpecials = new Spry.Data.XMLDataSet("http://www.somesite.com/somefolder/cafetownsend.xml", "specials/menu_item");
注意:使用绝对路径还是相对路径取决于你使用的浏览器的安全模型,这以为着你仅能从与HTML页相同域的XML源装载数据,你也可以消除这个限制,但需要和你的服务器管理员沟通。
在前面的范例中,构造了一个dsSpecials数据集对象。并从cafatownsend.xml文件的specials/menu_item节点中获取数据并转化为平面对象和属性数组(a flattened array of objects),类似包含行与列的表。(作为表的范例,请查看本章的开始部分)
每个数据集都有一个当前行。默认情况下,当前行是数据集的第一行。稍侯,你可以通过数据集的setCurrentRow()方法来改变当前行。
注意:当你通过new操作符创建的数据集是没有包含数据的,要装载数据到数据集,首先调用数据集的loadData()方法,如果你的页面中没有使用任何区域(regions),那么你可以在页面中手动调用loadData()方法。装载过程是异步的,如果你在调用loadData()方法后立即访问数据,也许此时数据仍然是不可用的。
Spry XML 数据集高级范例
Spry XML数据集用XMLHTPPRequest对象异步装载指定的URL,当XML数据获取后,事实上是两种形式:文本形式、文档对象模型(DOM)树。
例如,你指定 “/photos.php?galleryid=2000" 作为你的数据源。(这是一个web service,返回XML数据)
<script type="text/javascript"> var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo"); </script>
下列代码为XML数据的文本形式:
<gallery id="12345"> <photographer id="4532">John Doe</photographer> <email>john@doe.com</email> <photos id="2000"> <photo path="sun.jpg" width="16" height="16" /> <photo path="tree.jpg" width="16" height="16" /> <photo path="surf.jpg" width="16" height="16" /> </photos> </gallery>
下面的范例中展示了XML数据的DOM树形式。
![](fig02.gif)
使用XPath在XML DOM树中指定部分节点,下面红色的部分为XPath所指定的/gallery/photos/photo节点 :
<gallery id="12345">
<photographer id="4532">John Doe</photographer>
<email>john@doe.com</email>
<photos id="2000">
<photo path="sun.jpg" width="16" height="16"/>
<photo path="tree.jpg" width="16" height="16"/>
<photo path="surf.jpg" width="16" height="16"/>
</photos>
</gallery>
下图展现了指定节点的DOM-树,黑色实心圆部分:
![](fig03.gif)
数据集指定节点的表形式:
@path |
@width |
@height |
---|---|---|
sun.jpg |
16 |
16 |
tree.jpg |
16 |
16 |
surf.jpg |
16 |
16 |
在这个范例中,Spry的列名取自指定节点的属性,Spry根据你的XPath来决定列的名称。
Spry是用下面的规则来平面化数据( flattening data)和创建列的:
-
如果指定的节点有属性,Spry为每个属性创建列并使用属性值来填充。列的名字由属性名前加@组成,例如:一个节点有一个id属性,那么列名则为@id。
-
如果指定的节点没有子元素,但有一个CDATA,那么Spry创建一个列并填充文本或CDATA。这个列的名字就是节点的名字。
- 如果指定的有子元素,Spry为每个元素及其属性创建列并填充值,但只对没有子元素的元素创建列,列名就是元素标记名, 子元素下的属性可以以这种格式表示"childTagName/@attrName"。
- 如果指定的节点有一个属性,Spry为这个属性创建列,该列的名字就是属性名前加@。
- Spry将忽略拥有子元素的子元素。
这个范例将更详细展示平面化处理以及Spry产生数据集列。
范例:指定、平面化一个元素的属性和文本值
下面的红色代码展示了被 /gallery/photographer XPath表达式所指定的数据:
<gallery id="12345">
<photographer id="4532">John Doe</photographer>
<email>john@doe.com</email>
<photos id="2000">
<photo path="sun.jpg" width="16" height="16" />
<photo path="tree.jpg" width="16" height="16" />
<photo path="surf.jpg" width="16" height="16" />
</photos>
</gallery>
用DOM树的形式展现为:
![](fig04.gif)
用表的形式展现为:
photographer |
@id |
---|---|
John Doe |
16 |
这里,仅有一个节点被指定,因此在数据集中只有一行,photographer节点的文本为"John Doe", 因此节点值保存在名字为photographer的列中。photographer节点下有一个id属性,因此该属性值放在@id列中。
范例:指定、平面化一个元素的属性和子元素
下面代码为/gallery XPath表达式选择的数据:
<gallery id="12345"> <photographer id="4532">John Doe</photographer> <email>john@doe.com</email> <photos id="2000"> <photo path="sun.jpg" width="16" height="16" /> <photo path="tree.jpg" width="16" height="16" /> <photo path="surf.jpg" width="16" height="16" /> </photos> </gallery>
用DOM树形式战线为:
![](fig05.gif)
用表的形式展现为:
@id |
photographer |
photographer/@id |
|
---|---|---|---|
12345 |
John Doe |
4532 |
john@doe.com |
注意子元素的属性的数据列名前缀为子元素名。在这里photographer是指定的gallery节点的子元素,所以id属性的前缀应该为photographer/@。 同样需要注意的是,表中没有photos 元素,这是因为Spry不能平面化任何包含子元素的子元素。
范例:平面化选定元素的属性
使用XPath可以指定节点的属性。下列红色代码展示了gallery/photos/photo/@path XPath表达式所选择的数据:
<gallery id="12345"> <photographer id="4532">John Doe</photographer> <email>john@doe.com</email> <photos id="2000"> <photo path="sun.jpg" width="16" height="16" /> <photo path="tree.jpg" width="16" height="16" /> <photo path="surf.jpg" width="16" height="16" /> </photos> </gallery>
用DOM树形式展现为:
![](fig03.gif)
用表的形式展现为:
@path |
---|
sun.jpg |
tree.jpg |
surf.jpg |
Spry动态区域概要和组成
在你创建一个Spry数据集后,你可以在Spry动态区域中显示数据,一个Spry动态区域是也面上的一个范围,其与数据集绑定。区域显示通过数据集显示XML数据并当数据集变化后自动更新。
动态区域重建是因为他们注册为所绑定的数据集的观察器或侦听器。每当数据变化 (loaded, updated, sorted, filtered等),数据集将给他所拥有的所有观察器发送消息,触发正在侦听的动态区域的自动重建。
![](fig08.gif)
在一个容器标记里声明Spry动态区域,使用spry:region属性。大多数HTML元素可以成为动态区域容器,然而,下列标记不可以:
-
col
-
colgroup
-
frameset
-
html
-
iframe
-
select
-
style
-
table
-
tbody
-
tfoot
-
thead
-
title
-
tr
上面的这些标记不能作为Spry动态区域容器,但你可以在Spry动态区域容器内部使用他们。
注意:动态区域是在body标记内限定区域的,你不能添加spry:region属性到body标记之外的任何标记中。
在下面的范例中,下面有一个名叫Specials_DIV的用于动态区域的容器,它是一个div标记,并包含一个标准的HTML表。表是典型的用于动态区域的HTML元素,因为表的第一行可以作为表头,第二行就可以包含重复的XML数据了。
<!--Create the Spry dynamic region--> <div id="Specials_DIV" spry:region="dsSpecials"> <!--Display the data in a table--> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div>
在例子中,div标记创建动态区域仅仅需要两个属性:spry:region属性用于声明动态区域并指定绑定的数据集,另一个为id属性用于命名区域:
<div id="Specials_DIV" spry:region="dsSpecials">
一个新的区域是dsSpecials数据集的一个观察器(observer)。只要dsSpecials数据集有变化,区域将根据更新的进行数据重建。
用一个HTML表显示数据:
<table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table>
从表的第2行开始根据数据集循环显示数据。因为XML数据经常包含重复的节点,这个例子同样在表的第2行标记中声明spry:repeat属性,这将导致用户装载页面时数据集中的所有数据被显示(否则只显示数据集的当前行) 。