internal XmlReadMode ReadXml(XmlReader reader, XmlReadMode mode, bool denyResolving) { DataTable.RowDiffIdUsageSection rowDiffIdUsage = new DataTable.RowDiffIdUsageSection(); try { bool fSchemaFound = false; bool fDataFound = false; bool fIsXdr = false; int iCurrentDepth = -1; XmlReadMode ret = mode; // Dev11 904428: prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Prepare(this); if (reader == null) return ret; bool originalEnforceConstraint = false; if (this.DataSet != null) { originalEnforceConstraint = this.DataSet.EnforceConstraints; this.DataSet.EnforceConstraints = false; } else { originalEnforceConstraint = this.EnforceConstraints; this.EnforceConstraints = false; } if (reader is XmlTextReader) ((XmlTextReader) reader).WhitespaceHandling = WhitespaceHandling.Significant; XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema if ((mode != XmlReadMode.Fragment) && (reader.NodeType == XmlNodeType.Element)) iCurrentDepth = reader.Depth; reader.MoveToContent(); if (Columns.Count == 0) { if (IsEmptyXml(reader)) { reader.Read(); return ret; } } XmlDataLoader xmlload = null; if (reader.NodeType == XmlNodeType.Element) { XmlElement topNode = null; if (mode == XmlReadMode.Fragment) { xdoc.AppendChild(xdoc.CreateElement("ds_sqlXmlWraPPeR")); topNode = xdoc.DocumentElement; } else { //handle the top node if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { if ((mode == XmlReadMode.DiffGram) || (mode == XmlReadMode.IgnoreSchema)) { if (Columns.Count == 0) { if(reader.IsEmptyElement) { reader.Read(); return XmlReadMode.DiffGram; } throw ExceptionBuilder.DataTableInferenceNotSupported(); } this.ReadXmlDiffgram(reader); // read the closing tag of the current element ReadEndElement(reader); } else { reader.Skip(); } RestoreConstraint(originalEnforceConstraint); return ret; } if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI==Keywords.XDRNS) { // load XDR schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema)) { ReadXDRSchema(reader); } else { reader.Skip(); } RestoreConstraint(originalEnforceConstraint); return ret; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI==Keywords.XSDNS) { // load XSD schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema)) { ReadXmlSchema(reader, denyResolving); } else reader.Skip(); RestoreConstraint(originalEnforceConstraint); return ret; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) { if (this.DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property this.DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { this.enforceConstraints = originalEnforceConstraint; } throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); } // now either the top level node is a table and we load it through dataReader... // ... or backup the top node and all its attributes topNode = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); if (reader.HasAttributes) { int attrCount = reader.AttributeCount; for (int i=0;i<attrCount;i++) { reader.MoveToAttribute(i); if (reader.NamespaceURI.Equals(Keywords.XSD_XMLNS_NS)) topNode.SetAttribute(reader.Name, reader.GetAttribute(i)); else { XmlAttribute attr = topNode.SetAttributeNode(reader.LocalName, reader.NamespaceURI); attr.Prefix = reader.Prefix; attr.Value = reader.GetAttribute(i); } } } reader.Read(); } while(MoveToElement(reader, iCurrentDepth)) { if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI==Keywords.XDRNS) { // load XDR schema if (!fSchemaFound && !fDataFound && (mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema)) { ReadXDRSchema(reader); fSchemaFound = true; fIsXdr = true; } else { reader.Skip(); } continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI==Keywords.XSDNS) { // load XSD schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema)) { ReadXmlSchema(reader, denyResolving); fSchemaFound = true; } else { reader.Skip(); } continue; } if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { if ((mode == XmlReadMode.DiffGram) || (mode == XmlReadMode.IgnoreSchema)) { if (Columns.Count == 0) { if(reader.IsEmptyElement) { reader.Read(); return XmlReadMode.DiffGram; } throw ExceptionBuilder.DataTableInferenceNotSupported(); } this.ReadXmlDiffgram(reader); ret = XmlReadMode.DiffGram; } else { reader.Skip(); } continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) { if (this.DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property this.DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { this.enforceConstraints = originalEnforceConstraint; } throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); } if (mode == XmlReadMode.DiffGram) { reader.Skip(); continue; // we do not read data in diffgram mode } // if we are here we found some data fDataFound = true; if (mode == XmlReadMode.InferSchema) { //save the node in DOM until the end; XmlNode node = xdoc.ReadNode(reader); topNode.AppendChild(node); } else { if (Columns.Count == 0) { throw ExceptionBuilder.DataTableInferenceNotSupported(); } if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, topNode, mode == XmlReadMode.IgnoreSchema); xmlload.LoadData(reader); } } //end of the while // read the closing tag of the current element ReadEndElement(reader); // now top node contains the data part xdoc.AppendChild(topNode); if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, mode == XmlReadMode.IgnoreSchema); if (mode == XmlReadMode.DiffGram) { // we already got the diffs through XmlReader interface RestoreConstraint(originalEnforceConstraint); return ret; } //todo // Load Data if (mode == XmlReadMode.InferSchema) { if (Columns.Count == 0) { throw ExceptionBuilder.DataTableInferenceNotSupported(); } // [....] xmlload.InferSchema(xdoc, null); // [....] xmlload.LoadData(xdoc); } } RestoreConstraint(originalEnforceConstraint); return ret; } finally { // Dev11 904428: prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Cleanup(); } }
internal XmlReadMode ReadXml(XmlReader reader, bool denyResolving) { IntPtr hscp; Bid.ScopeEnter(out hscp, "<ds.DataTable.ReadXml|INFO> %d#, denyResolving=%d{bool}\n", ObjectID, denyResolving); try { DataTable.RowDiffIdUsageSection rowDiffIdUsage = new DataTable.RowDiffIdUsageSection(); try { bool fDataFound = false; bool fSchemaFound = false; bool fDiffsFound = false; bool fIsXdr = false; int iCurrentDepth = -1; XmlReadMode ret = XmlReadMode.Auto; // clear the hashtable to avoid conflicts between diffgrams, SqlHotFix 782 rowDiffIdUsage.Prepare(this); if (reader == null) return ret; bool originalEnforceConstraint = false; if (this.DataSet != null) { originalEnforceConstraint = this.DataSet.EnforceConstraints; this.DataSet.EnforceConstraints = false; } else { originalEnforceConstraint = this.EnforceConstraints; this.EnforceConstraints = false; } if (reader is XmlTextReader) ((XmlTextReader) reader).WhitespaceHandling = WhitespaceHandling.Significant; XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema XmlDataLoader xmlload = null; reader.MoveToContent(); if (Columns.Count == 0) { if (IsEmptyXml(reader)) { reader.Read(); return ret; } } if (reader.NodeType == XmlNodeType.Element) { iCurrentDepth = reader.Depth; if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { if (Columns.Count == 0) { if (reader.IsEmptyElement) { reader.Read(); return XmlReadMode.DiffGram; } throw ExceptionBuilder.DataTableInferenceNotSupported(); } this.ReadXmlDiffgram(reader); // read the closing tag of the current element ReadEndElement(reader); RestoreConstraint(originalEnforceConstraint); return XmlReadMode.DiffGram; } // if reader points to the schema load it if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI==Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); RestoreConstraint(originalEnforceConstraint); return XmlReadMode.ReadSchema; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI==Keywords.XSDNS) { // load XSD schema and exit ReadXmlSchema(reader, denyResolving); RestoreConstraint(originalEnforceConstraint); return XmlReadMode.ReadSchema; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) { if (this.DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property this.DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { this.enforceConstraints = originalEnforceConstraint; } throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); } // now either the top level node is a table and we load it through dataReader... // ... or backup the top node and all its attributes because we may need to InferSchema XmlElement topNode = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); if (reader.HasAttributes) { int attrCount = reader.AttributeCount; for (int i=0;i<attrCount;i++) { reader.MoveToAttribute(i); if (reader.NamespaceURI.Equals(Keywords.XSD_XMLNS_NS)) topNode.SetAttribute(reader.Name, reader.GetAttribute(i)); else { XmlAttribute attr = topNode.SetAttributeNode(reader.LocalName, reader.NamespaceURI); attr.Prefix = reader.Prefix; attr.Value = reader.GetAttribute(i); } } } reader.Read(); while(MoveToElement(reader, iCurrentDepth)) { if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { this.ReadXmlDiffgram(reader); // read the closing tag of the current element ReadEndElement(reader); RestoreConstraint(originalEnforceConstraint); return XmlReadMode.DiffGram; } // if reader points to the schema load it... if (!fSchemaFound && !fDataFound && reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI==Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); fSchemaFound = true; fIsXdr = true; continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI==Keywords.XSDNS) { // load XSD schema and exit ReadXmlSchema(reader, denyResolving); fSchemaFound = true; continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) { if (this.DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property this.DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { this.enforceConstraints = originalEnforceConstraint; } throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); } if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { this.ReadXmlDiffgram(reader); fDiffsFound = true; ret = XmlReadMode.DiffGram; } else { // we found data here fDataFound = true; if (!fSchemaFound && Columns.Count == 0) { XmlNode node = xdoc.ReadNode(reader); topNode.AppendChild(node); } else { if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, topNode, false); xmlload.LoadData(reader); if (fSchemaFound) ret = XmlReadMode.ReadSchema; else ret = XmlReadMode.IgnoreSchema; } } } // read the closing tag of the current element ReadEndElement(reader); // now top node contains the data part xdoc.AppendChild(topNode); if (!fSchemaFound && Columns.Count == 0) { if (IsEmptyXml(reader)) { reader.Read(); return ret; } throw ExceptionBuilder.DataTableInferenceNotSupported(); } if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, false); // so we InferSchema if (!fDiffsFound) {// we need to add support for inference here } } RestoreConstraint(originalEnforceConstraint); return ret; } finally { rowDiffIdUsage.Cleanup(); } } finally{ Bid.ScopeLeave(ref hscp); } }