Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / Dom / DocumentXmlWriter.cs / 1305376 / DocumentXmlWriter.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Xml.Schema; namespace System.Xml { enum DocumentXmlWriterType { InsertSiblingAfter, InsertSiblingBefore, PrependChild, AppendChild, AppendAttribute, ReplaceToFollowingSibling, } // Implements a XmlWriter that augments a XmlDocument. sealed class DocumentXmlWriter : XmlRawWriter, IXmlNamespaceResolver { enum State { Error, Attribute, Prolog, Fragment, Content, Last, // always last } enum Method { WriteXmlDeclaration, WriteStartDocument, WriteEndDocument, WriteDocType, WriteStartElement, WriteEndElement, WriteFullEndElement, WriteStartAttribute, WriteEndAttribute, WriteStartNamespaceDeclaration, WriteEndNamespaceDeclaration, WriteCData, WriteComment, WriteProcessingInstruction, WriteEntityRef, WriteWhitespace, WriteString, } DocumentXmlWriterType type; // writer type XmlNode start; // context node XmlDocument document; // context document XmlNamespaceManager namespaceManager; // context namespace manager State state; // current state XmlNode write; // current node Listfragment; // top level node cache XmlWriterSettings settings; // wrapping writer settings DocumentXPathNavigator navigator; // context for replace XmlNode end; // context for replace public DocumentXmlWriter(DocumentXmlWriterType type, XmlNode start, XmlDocument document) { this.type = type; this.start = start; this.document = document; state = StartState(); fragment = new List (); settings = new XmlWriterSettings(); settings.ReadOnly = false; settings.CheckCharacters = false; settings.CloseOutput = false; settings.ConformanceLevel = (state == State.Prolog ? ConformanceLevel.Document : ConformanceLevel.Fragment); settings.ReadOnly = true; } public XmlNamespaceManager NamespaceManager { set { namespaceManager = value; } } public override XmlWriterSettings Settings { get { return settings; } } internal void SetSettings(XmlWriterSettings value) { settings = value; } public DocumentXPathNavigator Navigator { set { navigator = value; } } public XmlNode EndNode { set { end = value; } } internal override void WriteXmlDeclaration(XmlStandalone standalone) { VerifyState(Method.WriteXmlDeclaration); if (standalone != XmlStandalone.Omit) { XmlNode node = document.CreateXmlDeclaration("1.0", string.Empty, standalone == XmlStandalone.Yes ? "yes" : "no"); AddChild(node, write); } } internal override void WriteXmlDeclaration(string xmldecl) { VerifyState(Method.WriteXmlDeclaration); string version, encoding, standalone; XmlLoader.ParseXmlDeclarationValue(xmldecl, out version, out encoding, out standalone); XmlNode node = document.CreateXmlDeclaration(version, encoding, standalone); AddChild(node, write); } public override void WriteStartDocument() { VerifyState(Method.WriteStartDocument); } public override void WriteStartDocument(bool standalone) { VerifyState(Method.WriteStartDocument); } public override void WriteEndDocument() { VerifyState(Method.WriteEndDocument); } public override void WriteDocType(string name, string pubid, string sysid, string subset) { VerifyState(Method.WriteDocType); XmlNode node = document.CreateDocumentType(name, pubid, sysid, subset); AddChild(node, write); } public override void WriteStartElement(string prefix, string localName, string ns) { VerifyState(Method.WriteStartElement); XmlNode node = document.CreateElement(prefix, localName, ns); AddChild(node, write); write = node; } public override void WriteEndElement() { VerifyState(Method.WriteEndElement); if (write == null) { throw new InvalidOperationException(); } write = write.ParentNode; } internal override void WriteEndElement(string prefix, string localName, string ns) { WriteEndElement(); } public override void WriteFullEndElement() { VerifyState(Method.WriteFullEndElement); XmlElement elem = write as XmlElement; if (elem == null) { throw new InvalidOperationException(); } elem.IsEmpty = false; write = elem.ParentNode; } internal override void WriteFullEndElement(string prefix, string localName, string ns) { WriteFullEndElement(); } internal override void StartElementContent() { // nop } public override void WriteStartAttribute(string prefix, string localName, string ns) { VerifyState(Method.WriteStartAttribute); XmlAttribute attr = document.CreateAttribute(prefix, localName, ns); AddAttribute(attr, write); write = attr; } public override void WriteEndAttribute() { VerifyState(Method.WriteEndAttribute); XmlAttribute attr = write as XmlAttribute; if (attr == null) { throw new InvalidOperationException(); } if (!attr.HasChildNodes) { XmlNode node = document.CreateTextNode(string.Empty); AddChild(node, attr); } write = attr.OwnerElement; } internal override void WriteNamespaceDeclaration(string prefix, string ns) { this.WriteStartNamespaceDeclaration(prefix); this.WriteString(ns); this.WriteEndNamespaceDeclaration(); } internal override bool SupportsNamespaceDeclarationInChunks { get { return true; } } internal override void WriteStartNamespaceDeclaration(string prefix) { VerifyState(Method.WriteStartNamespaceDeclaration); XmlAttribute attr; if (prefix.Length == 0) { attr = document.CreateAttribute(prefix, document.strXmlns, document.strReservedXmlns); } else { attr = document.CreateAttribute(document.strXmlns, prefix, document.strReservedXmlns); } AddAttribute(attr, write); write = attr; } internal override void WriteEndNamespaceDeclaration() { VerifyState(Method.WriteEndNamespaceDeclaration); XmlAttribute attr = write as XmlAttribute; if (attr == null) { throw new InvalidOperationException(); } if (!attr.HasChildNodes) { XmlNode node = document.CreateTextNode(string.Empty); AddChild(node, attr); } write = attr.OwnerElement; } public override void WriteCData(string text) { VerifyState(Method.WriteCData); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); XmlNode node = document.CreateCDataSection(text); AddChild(node, write); } public override void WriteComment(string text) { VerifyState(Method.WriteComment); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); XmlNode node = document.CreateComment(text); AddChild(node, write); } public override void WriteProcessingInstruction(string name, string text) { VerifyState(Method.WriteProcessingInstruction); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); XmlNode node = document.CreateProcessingInstruction(name, text); AddChild(node, write); } public override void WriteEntityRef(string name) { VerifyState(Method.WriteEntityRef); XmlNode node = document.CreateEntityReference(name); AddChild(node, write); // } public override void WriteCharEntity(char ch) { WriteString(new string(ch, 1)); } public override void WriteWhitespace(string text) { VerifyState(Method.WriteWhitespace); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); if (document.PreserveWhitespace) { XmlNode node = document.CreateWhitespace(text); AddChild(node, write); } } public override void WriteString(string text) { VerifyState(Method.WriteString); XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); XmlNode node = document.CreateTextNode(text); AddChild(node, write); } public override void WriteSurrogateCharEntity(char lowCh, char highCh) { WriteString(new string(new char[] {highCh, lowCh})); } public override void WriteChars(char[] buffer, int index, int count) { WriteString(new string(buffer, index, count)); } public override void WriteRaw(char[] buffer, int index, int count) { WriteString(new string(buffer, index, count)); } public override void WriteRaw(string data) { WriteString(data); } public override void Close() { // nop } internal override void Close(WriteState currentState) { if (currentState == WriteState.Error) { return; } try { switch (type) { case DocumentXmlWriterType.InsertSiblingAfter: XmlNode parent = start.ParentNode; if (parent == null) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } for (int i = fragment.Count - 1; i >= 0; i--) { parent.InsertAfter(fragment[i], start); } break; case DocumentXmlWriterType.InsertSiblingBefore: parent = start.ParentNode; if (parent == null) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } for (int i = 0; i < fragment.Count; i++) { parent.InsertBefore(fragment[i], start); } break; case DocumentXmlWriterType.PrependChild: for (int i = fragment.Count - 1; i >= 0; i--) { start.PrependChild(fragment[i]); } break; case DocumentXmlWriterType.AppendChild: for (int i = 0; i < fragment.Count; i++) { start.AppendChild(fragment[i]); } break; case DocumentXmlWriterType.AppendAttribute: CloseWithAppendAttribute(); break; case DocumentXmlWriterType.ReplaceToFollowingSibling: if (fragment.Count == 0) { throw new InvalidOperationException(Res.GetString(Res.Xpn_NoContent)); } CloseWithReplaceToFollowingSibling(); break; } } finally { fragment.Clear(); } } private void CloseWithAppendAttribute() { XmlElement elem = start as XmlElement; Debug.Assert(elem != null); XmlAttributeCollection attrs = elem.Attributes; for (int i = 0; i < fragment.Count; i++) { XmlAttribute attr = fragment[i] as XmlAttribute; Debug.Assert(attr != null); int offset = attrs.FindNodeOffsetNS(attr); if (offset != -1 && ((XmlAttribute)attrs.Nodes[offset]).Specified) { throw new XmlException(Res.Xml_DupAttributeName, attr.Prefix.Length == 0 ? attr.LocalName : string.Concat(attr.Prefix, ":", attr.LocalName)); } } for (int i = 0; i < fragment.Count; i++) { XmlAttribute attr = fragment[i] as XmlAttribute; Debug.Assert(attr != null); attrs.Append(attr); } } private void CloseWithReplaceToFollowingSibling() { XmlNode parent = start.ParentNode; if (parent == null) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } if (start != end) { if (!DocumentXPathNavigator.IsFollowingSibling(start, end)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } if (start.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } DocumentXPathNavigator.DeleteToFollowingSibling(start.NextSibling, end); } XmlNode fragment0 = fragment[0]; parent.ReplaceChild(fragment0, start); for (int i = fragment.Count - 1; i >= 1; i--) { parent.InsertAfter(fragment[i], fragment0); } navigator.ResetPosition(fragment0); } public override void Flush() { // nop } IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope) { return namespaceManager.GetNamespacesInScope(scope); } string IXmlNamespaceResolver.LookupNamespace(string prefix) { return namespaceManager.LookupNamespace(prefix); } string IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return namespaceManager.LookupPrefix(namespaceName); } void AddAttribute(XmlAttribute attr, XmlNode parent) { if (parent == null) { fragment.Add(attr); } else { XmlElement elem = parent as XmlElement; if (elem == null) { throw new InvalidOperationException(); } elem.Attributes.Append(attr); } } void AddChild(XmlNode node, XmlNode parent) { if (parent == null) { fragment.Add(node); } else { parent.AppendChild(node); } } State StartState() { XmlNodeType nodeType = XmlNodeType.None; switch (type) { case DocumentXmlWriterType.InsertSiblingAfter: case DocumentXmlWriterType.InsertSiblingBefore: XmlNode parent = start.ParentNode; if (parent != null) { nodeType = parent.NodeType; } if (nodeType == XmlNodeType.Document) { return State.Prolog; } else if (nodeType == XmlNodeType.DocumentFragment) { return State.Fragment; } break; case DocumentXmlWriterType.PrependChild: case DocumentXmlWriterType.AppendChild: nodeType = start.NodeType; if (nodeType == XmlNodeType.Document) { return State.Prolog; } else if (nodeType == XmlNodeType.DocumentFragment) { return State.Fragment; } break; case DocumentXmlWriterType.AppendAttribute: return State.Attribute; case DocumentXmlWriterType.ReplaceToFollowingSibling: break; } return State.Content; } static State[] changeState = { // State.Error, State.Attribute,State.Prolog, State.Fragment, State.Content, // Method.XmlDeclaration: State.Error, State.Error, State.Prolog, State.Content, State.Error, // Method.StartDocument: State.Error, State.Error, State.Error, State.Error, State.Error, // Method.EndDocument: State.Error, State.Error, State.Error, State.Error, State.Error, // Method.DocType: State.Error, State.Error, State.Prolog, State.Error, State.Error, // Method.StartElement: State.Error, State.Error, State.Content, State.Content, State.Content, // Method.EndElement: State.Error, State.Error, State.Error, State.Error, State.Content, // Method.FullEndElement: State.Error, State.Error, State.Error, State.Error, State.Content, // Method.StartAttribute: State.Error, State.Content, State.Error, State.Error, State.Content, // Method.EndAttribute: State.Error, State.Error, State.Error, State.Error, State.Content, // Method.StartNamespaceDeclaration: State.Error, State.Content, State.Error, State.Error, State.Content, // Method.EndNamespaceDeclaration: State.Error, State.Error, State.Error, State.Error, State.Content, // Method.CData: State.Error, State.Error, State.Error, State.Content, State.Content, // Method.Comment: State.Error, State.Error, State.Prolog, State.Content, State.Content, // Method.ProcessingInstruction: State.Error, State.Error, State.Prolog, State.Content, State.Content, // Method.EntityRef: State.Error, State.Error, State.Error, State.Content, State.Content, // Method.Whitespace: State.Error, State.Error, State.Prolog, State.Content, State.Content, // Method.String: State.Error, State.Error, State.Error, State.Content, State.Content, }; void VerifyState(Method method) { state = changeState[(int)method * (int)State.Last + (int)state]; if (state == State.Error) { throw new InvalidOperationException(Res.GetString(Res.Xml_ClosedOrError)); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlDictionaryReader.cs
- X509ThumbprintKeyIdentifierClause.cs
- OperationAbortedException.cs
- CodeGroup.cs
- WebPermission.cs
- DiagnosticStrings.cs
- UiaCoreTypesApi.cs
- OutgoingWebRequestContext.cs
- DelayedRegex.cs
- BamlVersionHeader.cs
- SynchronizationContext.cs
- MetafileHeader.cs
- Evaluator.cs
- ComponentConverter.cs
- SingleAnimation.cs
- CmsUtils.cs
- TreeNodeCollection.cs
- CheckBoxList.cs
- EnumValidator.cs
- AdRotator.cs
- ListViewTableCell.cs
- WindowsFormsSynchronizationContext.cs
- DialogWindow.cs
- ErrorHandler.cs
- XsdDuration.cs
- AuthStoreRoleProvider.cs
- AggregatePushdown.cs
- SQLMoneyStorage.cs
- PageCache.cs
- BinaryConverter.cs
- DynamicEndpoint.cs
- FilePresentation.cs
- ArcSegment.cs
- ResourcePermissionBaseEntry.cs
- FragmentQueryKB.cs
- EmptyControlCollection.cs
- HandlerWithFactory.cs
- DesignTimeParseData.cs
- XmlILModule.cs
- AuthenticationModulesSection.cs
- ColumnBinding.cs
- UriExt.cs
- SafeRightsManagementSessionHandle.cs
- TogglePattern.cs
- MenuRenderer.cs
- TdsParameterSetter.cs
- URL.cs
- GenericEnumerator.cs
- METAHEADER.cs
- CheckedPointers.cs
- EntityDataSourceDataSelectionPanel.cs
- SHA512.cs
- Grant.cs
- UrlPath.cs
- AddInAttribute.cs
- GPPOINTF.cs
- SelectorAutomationPeer.cs
- ControlCollection.cs
- QueueProcessor.cs
- UncommonField.cs
- BitConverter.cs
- ColorTransformHelper.cs
- BitmapMetadataEnumerator.cs
- ActiveXHost.cs
- XmlAggregates.cs
- ComAwareEventInfo.cs
- MILUtilities.cs
- NamedObject.cs
- XmlMembersMapping.cs
- DbConnectionPoolGroupProviderInfo.cs
- ContentPropertyAttribute.cs
- HtmlDocument.cs
- ComPersistableTypeElementCollection.cs
- ExpressionBinding.cs
- RealizationContext.cs
- CharacterBufferReference.cs
- MemberPathMap.cs
- PartialCachingControl.cs
- KeyNotFoundException.cs
- ProfileEventArgs.cs
- AutomationIdentifierGuids.cs
- TextContainerHelper.cs
- Buffer.cs
- CertificateElement.cs
- GeometryValueSerializer.cs
- PropertyConverter.cs
- ConnectionInterfaceCollection.cs
- ObjectSet.cs
- HttpClientCertificate.cs
- ExceptionDetail.cs
- EntityTransaction.cs
- MenuItemStyleCollection.cs
- DoubleKeyFrameCollection.cs
- _SingleItemRequestCache.cs
- LateBoundBitmapDecoder.cs
- Token.cs
- COM2PictureConverter.cs
- ReadOnlyPropertyMetadata.cs
- ErrorTolerantObjectWriter.cs
- Certificate.cs