internal XmlReadMode ReadXml(XmlReader reader, XmlReadMode mode, bool denyResolving) { RowDiffIdUsageSection rowDiffIdUsage = new RowDiffIdUsageSection(); try { bool fSchemaFound = false; bool fDataFound = false; bool fIsXdr = false; int iCurrentDepth = -1; XmlReadMode ret = mode; // prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Prepare(this); if (reader == null) { return ret; } bool originalEnforceConstraint = false; if (DataSet != null) { originalEnforceConstraint = DataSet.EnforceConstraints; DataSet.EnforceConstraints = false; } else { originalEnforceConstraint = EnforceConstraints; 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(); } 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 (DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { _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(); } 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 (DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { _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; } // Load Data if (mode == XmlReadMode.InferSchema) { if (Columns.Count == 0) { throw ExceptionBuilder.DataTableInferenceNotSupported(); } } } RestoreConstraint(originalEnforceConstraint); return ret; } finally { // prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Cleanup(); } }
internal XmlReadMode ReadXml(XmlReader reader, bool denyResolving) { long logScopeId = DataCommonEventSource.Log.EnterScope("<ds.DataTable.ReadXml|INFO> {0}, denyResolving={1}", ObjectID, denyResolving); try { RowDiffIdUsageSection rowDiffIdUsage = new 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 (DataSet != null) { originalEnforceConstraint = DataSet.EnforceConstraints; DataSet.EnforceConstraints = false; } else { originalEnforceConstraint = EnforceConstraints; 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(); } 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 (DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { _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)) { 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 (DataSet != null) { // we should not throw for constraint, we already will throw for unsupported schema, so restore enforce cost, but not via property DataSet.RestoreEnforceConstraints(originalEnforceConstraint); } else { _enforceConstraints = originalEnforceConstraint; } throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); } if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { 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); ret = fSchemaFound ? XmlReadMode.ReadSchema : 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 { DataCommonEventSource.Log.ExitScope(logScopeId); } }