您的位置:首页 > 其它

在不同格式的XML文档之间相互转换(二)加工源数据

2010-11-19 00:41 417 查看
上篇日志展示了文档转换的基本功能,即根据指定的路径从源文档中取出数据,在使用模板生成目标文档的同时填充数据到相应位置。应用中,这种简单的数据转移或者叫复制并不能满足我们的要求。我们常常需要将数据进行适当加工后再填充到目标文档,简单说,最终数据必须由代码动态生成。对于student.src.xml,现在修改如下。

student.src.xml

<?xml version="1.0" encoding="utf-8"?>
<students>
<student sn="001">
<name>张刚</name>
<age>19</age>
<subjects>
<subject>
<name>高等数学</name><score>80</score>
</subject>
<subject>
<name>操作系统</name><score>92</score>
</subject>
<subject>
<name>哲学</name><score>70</score>
</subject>
</subjects>
</student>
<student sn="002">
<name>李明</name>
<age>20</age>
<subjects>
<subject>
<name>高等数学</name><score>90</score>
</subject>
<subject>
<name>操作系统</name><score>95</score>
</subject>
<subject>
<name>哲学</name><score>85</score>
</subject>
</subjects>
</student>
<student sn="003">
<name>孙伟</name>
<age>18</age>
<subjects>
<subject>
<name>高等数学</name><score>79</score>
</subject>
<subject>
<name>操作系统</name><score>83</score>
</subject>
<subject>
<name>哲学</name><score>69</score>
</subject>
</subjects>
</student>
<student sn="004">
<name>刘鑫</name>
<age>18</age>
<subjects>
<subject>
<name>高等数学</name><score>60</score>
</subject>
<subject>
<name>操作系统</name><score>75</score>
</subject>
<subject>
<name>哲学</name><score>95</score>
</subject>
</subjects>
</student>
<student sn="005">
<name>高健</name>
<age>18</age>
<subjects>
<subject>
<name>高等数学</name><score>72</score>
</subject>
<subject>
<name>操作系统</name><score>45</score>
</subject>
<subject>
<name>哲学</name><score>50</score>
</subject>
</subjects>
</student>
<student sn="006">
<name>王晨</name>
<age>18</age>
<subjects>
<subject>
<name>高等数学</name><score>80</score>
</subject>
<subject>
<name>操作系统</name><score>81</score>
</subject>
<subject>
<name>哲学</name><score>70</score>
</subject>
</subjects>
</student>
</students>


现在我们需要统计每个人各科成绩的总分和平均分,然后按照由高到低的顺序排名。新的模板文档student.tpl.xml如下。

student.tpl.xml

<?xml version="1.0" encoding="utf-8"?>
<template rootname="table">
<attribute name="border" expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
<param name="#srcdocguid#" path="/" attr="guid" />
</paramlist>
<statement>
<![CDATA[
var ctrl = $$("#ctrlid#");
var srcDoc = $$("#srcdocguid#");
ctrl.$$secret.codebehind.scoreArray = [];
ctrl.$$secret.codebehind.totalStudent = 0;
ctrl.$$secret.codebehind.totalSubject = 0;
var totalStudent , totalSubject;
var studentList , subjectList;
studentList = srcDoc.documentElement.getElementsByTagName("student");
totalStudent = ctrl.$$secret.codebehind.totalStudent = studentList.length;
totalSubject = ctrl.$$secret.codebehind.totalSubject = (studentList.length != 0 && studentList.item(0).getElementsByTagName("subject").length != 0) ? studentList.item(0).getElementsByTagName("subject").length : 0;
var totalScore;
for(var si = 0 ; si < totalStudent ; si++){
totalScore = 0;
for(var sj = 0 ; sj < totalSubject ; sj++){
totalScore += parseFloat(studentList.item(si).getElementsByTagName("subject").item(sj).getElementsByTagName("score").item(0).firstChild.nodeValue);
}
ctrl.$$secret.codebehind.scoreArray.push
(
{
"sn" : studentList.item(si).getAttribute("sn"),
"name" : $System.XML.XMLUtil.XElement.getFirstElementChildByTagName(studentList.item(si) , "name").firstChild.nodeValue,
"total" : totalScore,
"average" : Math.round(totalScore * 10 / totalSubject) / 10
}
);
}
ctrl.$$secret.codebehind.scoreArray.sort
(
function(a , b){
if(a.total == b.total){
return 0;
}
if(a.total > b.total){
return 1;
}
return -1;
}
);
ctrl.$$secret.codebehind.scoreArray.reverse();
var border;
border = 1;
]]>
</statement>
</expression>
</attribute>
<element name="tr">
<attribute name="bgcolor" value="#6699FF" />
<element name="td">
<text>名次</text>
</element>
<element name="td">
<text>学号</text>
</element>
<element name="td">
<text>姓名</text>
</element>
<element name="td">
<text>总分</text>
</element>
<element name="td">
<text>平均分</text>
</element>
</element>
<for>
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
$$("#ctrlid#").$$secret.codebehind.iterI = 0;
var returnValue;
returnValue = "0," + $$("#ctrlid#").$$secret.codebehind.scoreArray.length;
]]>
</statement>
</expression>
<element name="tr">
<element name="td">
<text expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
var order;
order = $$("#ctrlid#").$$secret.codebehind.iterI + 1;
]]>
</statement>
</expression>
</text>
</element>
<element name="td">
<text expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
var sn;
sn = $$("#ctrlid#").$$secret.codebehind.scoreArray[$$("#ctrlid#").$$secret.codebehind.iterI].sn;
]]>
</statement>
</expression>
</text>
</element>
<element name="td">
<text expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
var sn;
sn = $$("#ctrlid#").$$secret.codebehind.scoreArray[$$("#ctrlid#").$$secret.codebehind.iterI].name;
]]>
</statement>
</expression>
</text>
</element>
<element name="td">
<text expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
var sn;
sn = $$("#ctrlid#").$$secret.codebehind.scoreArray[$$("#ctrlid#").$$secret.codebehind.iterI].total;
]]>
</statement>
</expression>
</text>
</element>
<element name="td">
<text expression="true">
<expression>
<paramlist>
<param name="#ctrlid#" path="/" attr="controlguid" />
</paramlist>
<statement>
<![CDATA[
var sn;
sn = $$("#ctrlid#").$$secret.codebehind.scoreArray[$$("#ctrlid#").$$secret.codebehind.iterI].average;
$$("#ctrlid#").$$secret.codebehind.iterI++;
sn;
]]>
</statement>
</expression>
</text>
</element>
</element>
</for>
</template>


这里我们引入了$System.UI.Control类,把一个dom元素简单包装成一个js对象。这个例子中这样做的目的是方便保存转换过程中的公共变量。对于转换过程中保存变量的方法可以有多种,这里只是提供了一种可行性,同时具体实现的优劣这里不做讨论。后面的讨论还可以看到,使用一种标准的方式将模板文档与其父容器关联,一定程度上弱化了文档的通用性,但另一方面,如果要生成能与容器乃至页面互动的DOM结构,总是要做些关联工作的。render方法的工作过程也可以浏览压缩包中相应的js源码。

转换代码如下。

var ctrl1 = new $System.UI.Control("div005");
var srcdoc = $System.XML.XMLUtil.loadXMLFile("xmltest\\student.src.xml");
var tpldoc = $System.XML.XMLUtil.loadXMLFile("xmltest\\student.tpl.xml");
ctrl1.renderE(srcdoc , tpldoc);


转换结果如下。



转换的复杂性通过嵌入模板文档的脚本来实现,也可以为每个脚本块指定参数,转换过程到达脚本块时会使用实参替换对应的占位符,然后执行脚本,将返回值(对最后一行代码求值的结果)插入目标文档要求的位置。

代码的试验仍按照上篇日志所述方法进行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: