实现一个客户端的DataSet-----ClientDataSet.htc
2024-07-21 02:16:59
供稿:网友
<public:component lightweight="true">
<public:property name="name" value="dataset" />
<public:property name="namespace" value="http://tempuri.org" />
<public:property name="xmldata" />
<public:property name="xmlschema" />
<public:method name="readxml" />
<public:method name="readxmlschema" />
<public:method name="gettable" />
<public:method name="acceptchanges" />
<public:method name="rejectchanges" />
<public:method name="getchanges" />
<public:event name="ondatachanged" id="datachanged" />
</public:component>
<script>
//////////////////////////////////////////////////////////
// 实现一个客户端的dataset
//////////////////////////////////////////////////////////
function datarow(dt, onode)
{
this.datatable = dt;
this.xmlnode = onode;
this.getvalue = datarow_getvalue;
this.setvalue = datarow_setvalue;
this.delete = datarow_delete;
}
function datarow_getvalue(vindex)
{
var onode;
switch (typeof(vindex))
{
case "string":
onode = this.xmlnode.selectsinglenode(vindex);
break;
default:
throw "you must index into a datarow using the string name.";
}
if (onode != null)
{
return onode.text;
}
return null;
}
function datarow_setvalue(vindex, vvalue)
{
var onode;
var oschemanode;
switch (typeof(vindex))
{
case "string":
onode = this.xmlnode.selectsinglenode(vindex);
oschemanode = this.datatable.schemanode.selectsinglenode('xsd:complextype/xsd:sequence/xsd:element[@name="' + vindex + '"]');
if (oschemanode == null)
throw "invaid column index: " + vindex;
break;
default:
//onode = this.xmlnode.childnodes[vindex];
throw "invaid column index: " + vindex;
}
var minoccurs = oschemanode.getattribute("minoccurs");
// minoccurs默认为1
if (minoccurs == null)
minoccurs = 1;
else
minoccurs = new number(minoccurs);
// 如果该列允许空值或请求值为空就去掉节点
if (vvalue == null && minoccurs == 0) {
if (onode != null)
onode.parentnode.removechild(onode);
return;
}
// 如果以前没有设置值则添加值
if (onode == null) {
var colname = oschemanode.getattribute("name");
onode = this.xmlnode.ownerdocument.createelement(colname);
onode.text = vvalue;
this.xmlnode.appendchild(onode);
return;
}
// 如果该列已存在值则只有在值不同时才更改
var curvalue = onode.text;
if (curvalue != vvalue.tostring())
{
if (this.xmlnode.getattribute("diffgr:haschanges") != "inserted") {
// 备份原始值
var odiffgrambefore = this.datatable.dataset.xmldata.documentelement.selectsinglenode("diffgr:before");
if (odiffgrambefore == null) {
odiffgrambefore = this.xmlnode.ownerdocument.createnode(1, "diffgr:before", "urn:schemas-microsoft-com:xml-diffgram-v1");
this.xmlnode.ownerdocument.documentelement.appendchild(odiffgrambefore);
}
var path = this.datatable.tablename + "[@diffgr:id='" + this.xmlnode.getattribute("diffgr:id") + "']";
var ooriginalrow = odiffgrambefore.selectsinglenode(path);
if (ooriginalrow == null) {
// 拷贝原始行
odiffgrambefore.appendchild(this.xmlnode.clonenode(true));
}
this.xmlnode.setattribute("diffgr:haschanges", "modified");
}
onode.text = new string(vvalue);
}
}
function datarow_delete()
{
var odiffgrambefore = this.datatable.dataset.xmldata.documentelement.selectsinglenode("diffgr:before");
if (odiffgrambefore == null) {
odiffgrambefore = this.xmlnode.ownerdocument.createnode(1, "diffgr:before", "urn:schemas-microsoft-com:xml-diffgram-v1");
this.xmlnode.ownerdocument.documentelement.appendchild(odiffgrambefore);
}
var obeforenode = odiffgrambefore.selectsinglenode(this.xmlnode.nodename + "[@diffgr:id='" + this.xmlnode.getattribute("diffgr:id") + "']");
if (obeforenode == null) {
//this.xmlnode.setattribute("xmlns", this.datatable.dataset.namespace);
odiffgrambefore.appendchild(this.xmlnode);
this.xmlnode.setattribute("xmlns", this.datatable.dataset.namespace);
}
else {
this.xmlnode.parentnode.removechild(this.xmlnode);
}
this.xmlnode = null;
}
function datatable(ds, name, onodes)
{
this.xmlnodes = onodes;
this.dataset = ds;
this.tablename = name;
this.getrowcount = datatable_getrowcount;
this.getrow = datatable_getrow;
this.addrow = datatable_addrow;
this.findrow = datatable_findrow;
this.schemanode = ds.xmlschema.selectsinglenode('//xsd:element[@name="' + name + '"]');
if (this.schemanode == null) {
throw name + " table not found in dataset schema.";
}
}
function datatable_getrowcount()
{
return this.xmlnodes.length;
}
function datatable_getrow(i)
{
return new datarow(this, this.xmlnodes[i]);
}
function datatable_addrow()
{
var orow = this.dataset.xmldata.createelement(this.tablename);
orow.setattribute("diffgr:id", createid());
//orow.setattribute("msdata:roworder", this.getrowcount());
orow.setattribute("diffgr:haschanges", "inserted");
// add the column elements with their default values to the new empty row
var columns = this.schemanode.selectnodes("xsd:complextype/xsd:sequence/xsd:element");
for (var i=0; i<columns.length; i++)
{
var col = columns[i];
var minoccurs = col.getattribute("minoccurs");
var defaultvalue = col.getattribute("default");
if (minoccurs == null)
minoccurs = 1;
else
minoccurs = new number(minoccurs);
if (minoccurs > 0 || defaultvalue != null) {
var colname = col.getattribute("name");
var ocol = this.dataset.xmldata.createelement(colname);
if (defaultvalue != null)
ocol.text = new string(defaultvalue);
orow.appendchild(ocol);
}
}
var odataset = this.dataset.xmldata.documentelement.selectsinglenode(this.dataset.name);
odataset.appendchild(orow);
this.xmlnodes = odataset.selectnodes(this.tablename);
return new datarow(this, orow);
}
function datatable_findrow(xpr)
{
var odataset = this.dataset.xmldata.selectnodes(this.dataset.name);
if (odataset) {
var orow = odataset.selectsinglenode(this.tablename + "[" + expr + "]");
if (orow) {
return new datarow(this, orow);
}
}
return null;
}
//////////////////////////////////////////////////////////
// private variables
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// private methods
//////////////////////////////////////////////////////////
function createid()
{
return element.document.createelement("div").uniqueid;
}
//////////////////////////////////////////////////////////
// public methods
//////////////////////////////////////////////////////////
function gettable(vindex)
{
var onodes;
var tablename = "";
switch (typeof(vindex))
{
case "string":
// 返回行
tablename = vindex;
onodes = xmldata.documentelement.selectnodes(name + "/" + tablename);
break;
case "number":
throw "index by position not supported.";
break;
}
if (onodes != null)
{
return new datatable(this, tablename, onodes);
}
return null;
}
function acceptchanges()
{
// 删除节点
var beforenode = this.xmldata.documentelement.selectsinglenode("diffgr:before");
if (beforenode) {
this.xmldata.documentelement.removechild(beforenode);
}
// 改变diffgr:haschanges属性
var haschangesattributes = xmldata.selectnodes("//@diffgr:haschanges");
while (haschangesattributes.peeknode() != null) {
haschangesattributes.removenext();
}
}
function rejectchanges()
{
// 删除数据
var datasetnode = this.xmldata.documentelement.selectsinglenode(this.name);
var beforenodes = this.xmldata.documentelement.selectnodes("diffgr:before/*");
while (beforenodes.peeknode() != null) {
var beforenode = beforenodes.nextnode();
var path = beforenode.nodename + "[@diffgr:id='" + beforenode.getattribute("diffgr:id") + "']";
var changedrow = datasetnode.selectsinglenode(path);
if (changedrow != null)
datasetnode.replacechild(beforenode, changedrow)
else
datasetnode.appendchild(beforenode);
}
// 删除节点
var beforenode = this.xmldata.documentelement.selectsinglenode("diffgr:before");
this.xmldata.documentelement.removechild(beforenode);
}
function getchanges()
{
var ds = new activexobject("microsoft.xmldom");
ds.async = false;
ds.loadxml('<dataset/>');
var schemanode = xmlschema.documentelement.clonenode(true);
var diffnode = ds.createnode(1, "diffgr:diffgram", "urn:schemas-microsoft-com:xml-diffgram-v1");
diffnode.setattribute("xmlns:msdata", "urn:schemas-microsoft-com:xml-msdata");
var datanode = ds.createelement(name);
datanode.setattribute("xmlns", this.namespace);
var changednodes = xmldata.documentelement.selectnodes(name + '/*[@diffgr:haschanges]');
while (changednodes.peeknode() != null) {
var changednode = changednodes.nextnode();
datanode.appendchild(changednode.clonenode(true));
}
diffnode.appendchild(datanode);
var beforenode = xmldata.documentelement.selectsinglenode("diffgr:before");
if (beforenode) {
diffnode.appendchild(beforenode.clonenode(true));
}
// 合并schema和数据
ds.documentelement.appendchild(schemanode);
ds.documentelement.appendchild(diffnode);
return ds.documentelement;
}
function readxml(doc)
{
readxmlschema(doc);
var odiffgram = doc.selectsinglenode("diffgr:diffgram");
if (odiffgram != null) {
xmldata = new activexobject("microsoft.xmldom");
xmldata.documentelement = odiffgram;
}
}
function readxmlschema(doc)
{
xmldata = null;
// 得到schema
var oschema = doc.selectsinglenode("xsd:schema");
if (oschema != null)
{
xmlschema = new activexobject("microsoft.xmldom");
xmlschema.documentelement = oschema;
name = oschema.selectsinglenode('xsd:element[@msdata:isdataset="true"]').getattribute("name")
namespace = oschema.getattribute("targetnamespace");
}
}
</script>