public override void Save(Stream w)
        {
            XmlWriter xmlWriter = null;

            try {
                if (PreserveWhitespace)
                {
                    XmlFormatter.Format(this);
                    xmlWriter = new XmlAttributePreservingWriter(w, TextEncoding);
                }
                else
                {
                    XmlTextWriter textWriter = new XmlTextWriter(w, TextEncoding);
                    textWriter.Formatting = Formatting.Indented;
                    xmlWriter             = textWriter;
                }
                WriteTo(xmlWriter);
            }
            finally {
                if (xmlWriter != null)
                {
                    xmlWriter.Flush();
                }
            }
        }
 public string GetAttributeNewLineString(XmlFormatter formatter)
 {
     if (attributeNewLineString == null)
     {
         attributeNewLineString = ComputeAttributeNewLineString(formatter);
     }
     return(attributeNewLineString);
 }
        public static void Format(XmlDocument document)
        {
            XmlFileInfoDocument errorInfoDocument = document as XmlFileInfoDocument;

            if (errorInfoDocument != null)
            {
                XmlFormatter formatter = new XmlFormatter(errorInfoDocument);
                formatter.FormatLoop(errorInfoDocument);
            }
        }
        private string ComputeAttributeNewLineString(XmlFormatter formatter)
        {
            string lookAheadString = LookAheadForNewLineString();

            if (lookAheadString != null)
            {
                return(lookAheadString);
            }
            else if (formatter != null)
            {
                return(formatter.CurrentAttributeIndent);
            }
            else
            {
                return(null);
            }
        }
 private void EnsureAttributeNewLineString(XmlFormatter formatter)
 {
     GetAttributeNewLineString(formatter);
 }
        internal void UpdatePreservationInfo(XmlAttributeCollection updatedAttributes, XmlFormatter formatter)
        {
            if (updatedAttributes.Count == 0)
            {
                if (orderedAttributes.Count > 0)
                {
                    // All attributes were removed, clear preservation info
                    leadingSpaces.Clear();
                    orderedAttributes.Clear();
                }
            }
            else
            {
                Dictionary <string, bool> attributeExists = new Dictionary <string, bool>();

                // Prepopulate the list with attributes that existed before
                foreach (string attributeName in orderedAttributes)
                {
                    attributeExists[attributeName] = false;
                }

                // Update the list with attributes that exist now
                foreach (XmlAttribute attribute in updatedAttributes)
                {
                    if (!attributeExists.ContainsKey(attribute.Name))
                    {
                        orderedAttributes.Add(attribute.Name);
                    }
                    attributeExists[attribute.Name] = true;
                }

                bool   firstAttribute        = true;
                string keepLeadingWhitespace = null;
                foreach (string key in orderedAttributes)
                {
                    bool exists = attributeExists[key];

                    // Handle removal
                    if (!exists)
                    {
                        // We need to figure out whether to keep the leading
                        // or trailing whitespace. The logic is:
                        //   1. The whitespace before the first attribute is
                        //      always kept, so remove trailing space.
                        //   2. We want to keep newlines, so if the leading
                        //      space contains a newline then remove trailing
                        //      space. If multiple newlines are being removed,
                        //      keep the last one.
                        //   3. Otherwise, remove leading space.
                        //
                        // In order to remove trailing space, we have to
                        // remove the leading space of the next attribute, so
                        // we store this leading space to replace the next.
                        if (leadingSpaces.ContainsKey(key))
                        {
                            string leadingSpace = leadingSpaces[key];
                            if (firstAttribute)
                            {
                                if (keepLeadingWhitespace == null)
                                {
                                    keepLeadingWhitespace = leadingSpace;
                                }
                            }
                            else if (ContainsNewLine(leadingSpace))
                            {
                                keepLeadingWhitespace = leadingSpace;
                            }

                            leadingSpaces.Remove(key);
                        }
                    }

                    else if (keepLeadingWhitespace != null)
                    {
                        // Exception to rule #2 above: Don't replace an existing
                        // newline with one that was removed
                        if (firstAttribute || !leadingSpaces.ContainsKey(key) || !ContainsNewLine(leadingSpaces[key]))
                        {
                            leadingSpaces[key] = keepLeadingWhitespace;
                        }
                        keepLeadingWhitespace = null;
                    }

                    // Handle addition
                    else if (!leadingSpaces.ContainsKey(key))
                    {
                        if (firstAttribute)
                        {
                            // This will prevent the textwriter from writing a
                            // newline before the first attribute
                            leadingSpaces[key] = " ";
                        }
                        else if (OneAttributePerLine)
                        {
                            // Add the indent space between each attribute
                            leadingSpaces[key] = GetAttributeNewLineString(formatter);
                        }
                        else
                        {
                            // Don't add any hard-coded spaces. All new attributes
                            // should be at the end, so they'll be formatted while
                            // writing. Make sure we have the right indent string,
                            // though.
                            EnsureAttributeNewLineString(formatter);
                        }
                    }

                    // firstAttribute remains true until we find the first
                    // attribute that actually exists
                    firstAttribute = firstAttribute && !exists;
                }
            }
        }
 void IXmlFormattableAttributes.FormatAttributes(XmlFormatter formatter)
 {
     preservationDict.UpdatePreservationInfo(Attributes, formatter);
 }