实现一个客户端的DataSet-----ClientDataSet.htc
点击次数:25 次 发布日期:2008-11-27 01:21:57 作者:源代码网
|
<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"); } } </ 源代码网供稿. |
