新增加的内容,首先是两个新变量的声明:subAry和subAryLen。它们和之前的变量dataArray和dataArrayLen类似,除了它们指向不同的数组(特别是它们将指向那些task元素-当dataArray和dataArrayLen指向pet元素的时候)。
我们也改变了变量insertData的初始值-我们增加了一个表格头(<th>)给我们的tasks字段。
下一步改变在于循环:我们把值赋给subAry和subAryLen变量。变量subAry成为当前<pet>的<task>元素的数组。变量subAryLen成为这个数组的长度,直到这个数组发生变化(当外部循环走到下一个<pet>时)。
我们创建了一个内嵌的循环来处理所有的<task>元素,一次一个。大概来说,我们创建一个新的数据格,放进一个用逗号分隔的任务列表,然后关闭数据表格以及当前行。尤其,这些<task>元素节点数据(任务本身,比如,喂食)放置入变量insertData里的数据格。
接下来,我们检验当前<pet>是否有其它更多的task。如果还有,我们增加一个逗号(,)到变量insertData来让每一个任务使用一个逗号分隔(a, b, c,而不是a, b, c,-注意,最后一个逗号在第二个任务那里,所以我们不需要)。这个工作在我们取得subAry数组长度的时候(给循环的“j”变量加1)就完成了。因为这个循环会在下一个循环的时候把变量j递增1,j会比它这次检验时还多1。因此,如果j+1(或者,当循环再次开始的时候j的值)等于subAryLen(当前<pet>节点的<task>节点数目),这个循环将停止。如果循环不再运行,我们就不再添加新的逗号来分隔任务。所以如果j+1不等于subAryLen,我们直到我们可以安全的加入逗号到insertData,为下一个<task>作准备。
一旦内循环结束,我们关闭task数据格以及pet行。外部循环会重新开始创建一个新行以及移动到下一个<pet>。这个处理一直进行到所有的<pet>元素(以及每一个pet的所有<task>元素)都被处理完。
有其他方法吗?
你也许会想:“那javascript变得相当复杂了,但它只会随着XML越来越复杂而跟着变复杂,也许我们能够简化XML,然后,简化javascript”。如果你这么想,很棒,因为你完全正确。我之前展示的不同方法之一,我详细说明的那个也许能够成为最合适的。我们怎么使用属性来对应每一只宠物以及相应任务?XML看起来会变成怎样?
<?
xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet type="猫" tasks="喂食, 饮水, 抓跳蚤" />
<pet type="狗" tasks="喂食, 饮水, 带出去遛遛" />
<pet type="鱼" tasks="喂食, 检查氧气,水的纯度,其它" />
</pets>
</data>
哇哦!看起来简单多了。让我们看看我们的processXML函数如何修改:
function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var insertData = '<table><tr><th>'
+ 'Pets</th><th>Tasks</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].getAttribute('type') + '</td>'
+ '<td>' + dataArray[i].getAttribute('tasks') + '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}