internal static void BuildSubtree(XmlReader reader, XmlWriter writer) { // important (perf) string literal... string xmlnsUri = XmlConst.ReservedNsXmlNs; // http://www.w3.org/2000/xmlns/ ReadState readState = reader.ReadState; if (readState != ReadState.Initial && readState != ReadState.Interactive) { throw new ArgumentException(SR.Xml_InvalidOperation, "reader"); } int level = 0; if (readState == ReadState.Initial) { if (!reader.Read()) return; level++; // if start in initial, read everything (not just first) } do { switch (reader.NodeType) { case XmlNodeType.Element: writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); bool isEmptyElement = reader.IsEmptyElement; while (reader.MoveToNextAttribute()) { if ((object)reader.NamespaceURI == (object)xmlnsUri) { if (reader.Prefix.Length == 0) { // Default namespace declaration "xmlns" Debug.Assert(reader.LocalName == "xmlns"); writer.WriteAttributeString("", "xmlns", xmlnsUri, reader.Value); } else { Debug.Assert(reader.Prefix == "xmlns"); writer.WriteAttributeString("xmlns", reader.LocalName, xmlnsUri, reader.Value); } } else { writer.WriteStartAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI); writer.WriteString(reader.Value); writer.WriteEndAttribute(); } } reader.MoveToElement(); if (isEmptyElement) { // there might still be a value, if there is a default value specified in the schema writer.WriteEndElement(); } else { level++; } break; case XmlNodeType.EndElement: writer.WriteFullEndElement(); //should not read beyond the level of the reader's original position. level--; break; case XmlNodeType.Text: case XmlNodeType.CDATA: writer.WriteString(reader.Value); break; case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: writer.WriteString(reader.Value); break; case XmlNodeType.Comment: writer.WriteComment(reader.Value); break; case XmlNodeType.ProcessingInstruction: writer.WriteProcessingInstruction(reader.LocalName, reader.Value); break; case XmlNodeType.EntityReference: reader.ResolveEntity(); break; case XmlNodeType.EndEntity: case XmlNodeType.None: case XmlNodeType.DocumentType: case XmlNodeType.XmlDeclaration: break; case XmlNodeType.Attribute: if ((object)reader.NamespaceURI == (object)xmlnsUri) { if (reader.Prefix.Length == 0) { // Default namespace declaration "xmlns" Debug.Assert(reader.LocalName == "xmlns"); writer.WriteAttributeString("", "xmlns", xmlnsUri, reader.Value); } else { Debug.Assert(reader.Prefix == "xmlns"); writer.WriteAttributeString("xmlns", reader.LocalName, xmlnsUri, reader.Value); } } else { writer.WriteStartAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI); writer.WriteString(reader.Value); writer.WriteEndAttribute(); } break; } } while (reader.Read() && (level > 0)); }
private void ReadElementFrom(XmlReader r, LoadOptions o) { if (r.ReadState != ReadState.Interactive) throw new InvalidOperationException(SR.InvalidOperation_ExpectedInteractive); name = XNamespace.Get(r.NamespaceURI).GetName(r.LocalName); if ((o & LoadOptions.SetBaseUri) != 0) { string baseUri = r.BaseURI; if (!string.IsNullOrEmpty(baseUri)) { SetBaseUri(baseUri); } } IXmlLineInfo li = null; if ((o & LoadOptions.SetLineInfo) != 0) { li = r as IXmlLineInfo; if (li != null && li.HasLineInfo()) { SetLineInfo(li.LineNumber, li.LinePosition); } } if (r.MoveToFirstAttribute()) { do { XAttribute a = new XAttribute(XNamespace.Get(r.Prefix.Length == 0 ? string.Empty : r.NamespaceURI).GetName(r.LocalName), r.Value); if (li != null && li.HasLineInfo()) { a.SetLineInfo(li.LineNumber, li.LinePosition); } AppendAttributeSkipNotify(a); } while (r.MoveToNextAttribute()); r.MoveToElement(); } if (!r.IsEmptyElement) { r.Read(); ReadContentFrom(r, o); } r.Read(); }