File: System\Xml\Linq\XStreamingElement.cs
Web Access
Project: src\src\libraries\System.Private.Xml.Linq\src\System.Private.Xml.Linq.csproj (System.Private.Xml.Linq)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Generic;
using System.IO;
 
using CultureInfo = System.Globalization.CultureInfo;
 
namespace System.Xml.Linq
{
    /// <summary>
    /// Represents a class that allows elements to be streamed
    /// on input and output.
    /// </summary>
    public class XStreamingElement
    {
        internal XName name;
        internal object? content;
 
        /// <summary>
        ///  Creates a <see cref="XStreamingElement"/> node with a given name
        /// </summary>
        /// <param name="name">The name to assign to the new <see cref="XStreamingElement"/> node</param>
        public XStreamingElement(XName name)
        {
            ArgumentNullException.ThrowIfNull(name);
 
            this.name = name;
        }
 
        /// <summary>
        /// Creates a <see cref="XStreamingElement"/> node with a given name and content
        /// </summary>
        /// <param name="name">The name to assign to the new <see cref="XStreamingElement"/> node</param>
        /// <param name="content">The content to assign to the new <see cref="XStreamingElement"/> node</param>
        public XStreamingElement(XName name, object? content)
            : this(name)
        {
            this.content = content is List<object?> ? new object?[] { content } : content;
        }
 
        /// <summary>
        /// Creates a <see cref="XStreamingElement"/> node with a given name and content
        /// </summary>
        /// <param name="name">The name to assign to the new <see cref="XStreamingElement"/> node</param>
        /// <param name="content">An array containing content to assign to the new <see cref="XStreamingElement"/> node</param>
        public XStreamingElement(XName name, params object?[] content)
            : this(name)
        {
            this.content = content;
        }
 
        /// <summary>
        /// Gets or sets the name of this streaming element.
        /// </summary>
        public XName Name
        {
            get
            {
                return name;
            }
            set
            {
                ArgumentNullException.ThrowIfNull(value);
                name = value;
            }
        }
 
        /// <summary>
        /// Add content to an <see cref="XStreamingElement"/>
        /// </summary>
        /// <param name="content">Object containing content to add</param>
        public void Add(object? content)
        {
            if (content != null)
            {
                List<object>? list = this.content as List<object>;
                if (list == null)
                {
                    list = new List<object>();
                    if (this.content != null) list.Add(this.content);
                    this.content = list;
                }
                list.Add(content);
            }
        }
 
        /// <summary>
        /// Add content to an <see cref="XStreamingElement"/>
        /// </summary>
        /// <param name="content">array of objects containing content to add</param>
        public void Add(params object?[] content)
        {
            Add((object)content);
        }
 
        /// <summary>
        /// Save the contents of an <see cref="XStreamingElement"/> to a <see cref="Stream"/>
        /// with formatting.
        /// </summary>
        /// <param name="stream"><see cref="Stream"/> to write to </param>
        public void Save(Stream stream)
        {
            Save(stream, SaveOptions.None);
        }
 
        /// <summary>
        /// Save the contents of an <see cref="XStreamingElement"/> to a <see cref="Stream"/>,
        /// optionally formatting.
        /// </summary>
        /// <param name="stream"><see cref="Stream"/> to write to </param>
        /// <param name="options">
        /// If SaveOptions.DisableFormatting is enabled the output is not indented.
        /// If SaveOptions.OmitDuplicateNamespaces is enabled duplicate namespace declarations will be removed.
        /// </param>
        public void Save(Stream stream, SaveOptions options)
        {
            XmlWriterSettings ws = XNode.GetXmlWriterSettings(options);
            using (XmlWriter w = XmlWriter.Create(stream, ws))
            {
                Save(w);
            }
        }
 
        /// <summary>
        /// Save the contents of an <see cref="XStreamingElement"/> to a text writer
        /// with formatting.
        /// </summary>
        /// <param name="textWriter"><see cref="TextWriter"/> to write to </param>
        public void Save(TextWriter textWriter)
        {
            Save(textWriter, SaveOptions.None);
        }
 
        /// <summary>
        /// Save the contents of an <see cref="XStreamingElement"/> to a text writer
        /// optionally formatting.
        /// </summary>
        /// <param name="textWriter"><see cref="TextWriter"/> to write to </param>
        /// <param name="options">
        /// If SaveOptions.DisableFormatting is enabled the output is not indented.
        /// If SaveOptions.OmitDuplicateNamespaces is enabled duplicate namespace declarations will be removed.
        /// </param>
        public void Save(TextWriter textWriter, SaveOptions options)
        {
            XmlWriterSettings ws = XNode.GetXmlWriterSettings(options);
            using (XmlWriter w = XmlWriter.Create(textWriter, ws))
            {
                Save(w);
            }
        }
 
        /// <summary>
        /// Save the contents of an <see cref="XStreamingElement"/> to an XML writer, not preserving whitespace
        /// </summary>
        /// <param name="writer"><see cref="XmlWriter"/> to write to </param>
        public void Save(XmlWriter writer)
        {
            ArgumentNullException.ThrowIfNull(writer);
 
            writer.WriteStartDocument();
            WriteTo(writer);
            writer.WriteEndDocument();
        }
 
        /// <summary>
        /// Save an <see cref="XStreamingElement"/> to a file with formatting.
        /// </summary>
        /// <param name="fileName">Name of file to write content to</param>
        public void Save(string fileName)
        {
            Save(fileName, SaveOptions.None);
        }
 
        /// <summary>
        /// Save an <see cref="XStreamingElement"/> to a file, optionally formatting.
        /// </summary>
        /// <param name="fileName">Name of file to write content to</param>
        /// <param name="options">
        /// If SaveOptions.DisableFormatting is enabled the output is not indented.
        /// If SaveOptions.OmitDuplicateNamespaces is enabled duplicate namespace declarations will be removed.
        /// </param>
        public void Save(string fileName, SaveOptions options)
        {
            XmlWriterSettings ws = XNode.GetXmlWriterSettings(options);
            using (XmlWriter w = XmlWriter.Create(fileName, ws))
            {
                Save(w);
            }
        }
 
        /// <summary>
        /// Get the XML content of an <see cref="XStreamingElement"/> as a
        /// formatted string.
        /// </summary>
        /// <returns>The XML text as a formatted string</returns>
        public override string ToString()
        {
            return GetXmlString(SaveOptions.None);
        }
 
        /// <summary>
        /// Gets the XML content of this streaming element as a string.
        /// </summary>
        /// <param name="options">
        /// If SaveOptions.DisableFormatting is enabled the content is not indented.
        /// If SaveOptions.OmitDuplicateNamespaces is enabled duplicate namespace declarations will be removed.
        /// </param>
        /// <returns>An XML string</returns>
        public string ToString(SaveOptions options)
        {
            return GetXmlString(options);
        }
 
        /// <summary>
        /// Write this <see cref="XStreamingElement"/> to an <see cref="XmlWriter"/>
        /// </summary>
        /// <param name="writer"></param>
        public void WriteTo(XmlWriter writer)
        {
            ArgumentNullException.ThrowIfNull(writer);
 
            new StreamingElementWriter(writer).WriteStreamingElement(this);
        }
 
        private string GetXmlString(SaveOptions o)
        {
            using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
            {
                XmlWriterSettings ws = new XmlWriterSettings();
                ws.OmitXmlDeclaration = true;
                if ((o & SaveOptions.DisableFormatting) == 0) ws.Indent = true;
                if ((o & SaveOptions.OmitDuplicateNamespaces) != 0) ws.NamespaceHandling |= NamespaceHandling.OmitDuplicates;
                using (XmlWriter w = XmlWriter.Create(sw, ws))
                {
                    WriteTo(w);
                }
                return sw.ToString();
            }
        }
    }
}