实现客户端的DataSet
<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");
}
}
<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");
}
}