internal void LoadFromReader(XmlReader reader, XmlSpace space) { ArgumentNullException.ThrowIfNull(reader); XPathDocumentBuilder builder; IXmlLineInfo? lineInfo; string?xmlnsUri; bool topLevelReader; int initialDepth; // Determine line number provider lineInfo = reader as IXmlLineInfo; if (lineInfo == null || !lineInfo.HasLineInfo()) { lineInfo = null; } _hasLineInfo = (lineInfo != null); _nameTable = reader.NameTable; builder = new XPathDocumentBuilder(this, lineInfo, reader.BaseURI, LoadFlags.None); try { // Determine whether reader is in initial state topLevelReader = (reader.ReadState == ReadState.Initial); initialDepth = reader.Depth; // Get atomized xmlns uri Debug.Assert((object?)_nameTable.Get(string.Empty) == (object)string.Empty, "NameTable must contain atomized string.Empty"); xmlnsUri = _nameTable.Get(XmlReservedNs.NsXmlNs); // Read past Initial state; if there are no more events then load is complete if (topLevelReader && !reader.Read()) { return; } // Read all events do { // If reader began in intermediate state, return when all siblings have been read if (!topLevelReader && reader.Depth < initialDepth) { return; } switch (reader.NodeType) { case XmlNodeType.Element: { bool isEmptyElement = reader.IsEmptyElement; builder.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.BaseURI); // Add attribute and namespace nodes to element while (reader.MoveToNextAttribute()) { string namespaceUri = reader.NamespaceURI; if ((object)namespaceUri == (object?)xmlnsUri) { if (reader.Prefix.Length == 0) { // Default namespace declaration "xmlns" Debug.Assert(reader.LocalName == "xmlns"); builder.WriteNamespaceDeclaration(string.Empty, reader.Value); } else { Debug.Assert(reader.Prefix == "xmlns"); builder.WriteNamespaceDeclaration(reader.LocalName, reader.Value); } } else { builder.WriteStartAttribute(reader.Prefix, reader.LocalName, namespaceUri); builder.WriteString(reader.Value, TextBlockType.Text); builder.WriteEndAttribute(); } } if (isEmptyElement) { builder.WriteEndElement(true); } break; } case XmlNodeType.EndElement: builder.WriteEndElement(false); break; case XmlNodeType.Text: case XmlNodeType.CDATA: builder.WriteString(reader.Value, TextBlockType.Text); break; case XmlNodeType.SignificantWhitespace: if (reader.XmlSpace == XmlSpace.Preserve) { builder.WriteString(reader.Value, TextBlockType.SignificantWhitespace); } else { // Significant whitespace without xml:space="preserve" is not significant in XPath/XQuery data model goto case XmlNodeType.Whitespace; } break; case XmlNodeType.Whitespace: // We intentionally ignore the reader.XmlSpace property here and blindly trust // the reported node type. If the reported information is not in sync // (in this case if the reader.XmlSpace == Preserve) then we make the choice // to trust the reported node type. Since we have no control over the input reader // we can't even assert here. // Always filter top-level whitespace if (space == XmlSpace.Preserve && (!topLevelReader || reader.Depth != 0)) { builder.WriteString(reader.Value, TextBlockType.Whitespace); } break; case XmlNodeType.Comment: builder.WriteComment(reader.Value); break; case XmlNodeType.ProcessingInstruction: builder.WriteProcessingInstruction(reader.LocalName, reader.Value, reader.BaseURI); break; case XmlNodeType.EntityReference: reader.ResolveEntity(); break; case XmlNodeType.DocumentType: // Create ID tables IDtdInfo?info = reader.DtdInfo; if (info != null) { builder.CreateIdTables(info); } break; case XmlNodeType.EndEntity: case XmlNodeType.None: case XmlNodeType.XmlDeclaration: break; } }while (reader.Read()); } finally { builder.Close(); } }
internal void LoadFromReader(XmlReader reader, XmlSpace space) { if (reader == null) { throw new ArgumentNullException("reader"); } IXmlLineInfo lineInfo = reader as IXmlLineInfo; if ((lineInfo == null) || !lineInfo.HasLineInfo()) { lineInfo = null; } this.hasLineInfo = lineInfo != null; this.nameTable = reader.NameTable; XPathDocumentBuilder builder = new XPathDocumentBuilder(this, lineInfo, reader.BaseURI, LoadFlags.None); try { bool isEmptyElement; string str2; bool flag = reader.ReadState == ReadState.Initial; int depth = reader.Depth; string str = this.nameTable.Get("http://www.w3.org/2000/xmlns/"); if (flag && !reader.Read()) { return; } Label_007D: if (!flag && (reader.Depth < depth)) { return; } switch (reader.NodeType) { case XmlNodeType.Element: isEmptyElement = reader.IsEmptyElement; builder.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.BaseURI); goto Label_017B; case XmlNodeType.Text: case XmlNodeType.CDATA: builder.WriteString(reader.Value, TextBlockType.Text); goto Label_022B; case XmlNodeType.EntityReference: reader.ResolveEntity(); goto Label_022B; case XmlNodeType.ProcessingInstruction: builder.WriteProcessingInstruction(reader.LocalName, reader.Value, reader.BaseURI); goto Label_022B; case XmlNodeType.Comment: builder.WriteComment(reader.Value); goto Label_022B; case XmlNodeType.DocumentType: { IDtdInfo dtdInfo = reader.DtdInfo; if (dtdInfo != null) { builder.CreateIdTables(dtdInfo); } goto Label_022B; } case XmlNodeType.Whitespace: goto Label_01C9; case XmlNodeType.SignificantWhitespace: if (reader.XmlSpace != XmlSpace.Preserve) { goto Label_01C9; } builder.WriteString(reader.Value, TextBlockType.SignificantWhitespace); goto Label_022B; case XmlNodeType.EndElement: builder.WriteEndElement(false); goto Label_022B; default: goto Label_022B; } Label_0113: str2 = reader.NamespaceURI; if (str2 == str) { if (reader.Prefix.Length == 0) { builder.WriteNamespaceDeclaration(string.Empty, reader.Value); } else { builder.WriteNamespaceDeclaration(reader.LocalName, reader.Value); } } else { builder.WriteStartAttribute(reader.Prefix, reader.LocalName, str2); builder.WriteString(reader.Value, TextBlockType.Text); builder.WriteEndAttribute(); } Label_017B: if (reader.MoveToNextAttribute()) { goto Label_0113; } if (isEmptyElement) { builder.WriteEndElement(true); } goto Label_022B; Label_01C9: if ((space == XmlSpace.Preserve) && (!flag || (reader.Depth != 0))) { builder.WriteString(reader.Value, TextBlockType.Whitespace); } Label_022B: if (reader.Read()) { goto Label_007D; } } finally { builder.Close(); } }