예제 #1
0
        /// <summary>
        /// Sets the first child in this container
        /// </summary>
        private void AddInitialChild(ProjectElement child)
        {
            ErrorUtilities.VerifyThrow(FirstChild == null && LastChild == null, "Expecting no children");

            VerifyForInsertBeforeAfterFirst(child, null);

            child.VerifyThrowInvalidOperationAcceptableLocation(this, null, null);

            child.Parent = this;

            FirstChild = child;
            LastChild  = child;

            child.PreviousSibling = null;
            child.NextSibling     = null;

            XmlElement.AppendChild(child.XmlElement);

            if (XmlDocument.PreserveWhitespace)
            {
                //  If we are trying to preserve formatting of the file, then the new node won't automatically be indented.
                //  So try to match the surrounding formatting and add one indentation level
                if (XmlElement.FirstChild.NodeType == XmlNodeType.Whitespace)
                {
                    //  This container had a whitespace node, which should generally be a newline and the indent
                    //  before the closing tag.  So we add the default indentation to it so the child will now be indented
                    //  further, and then create a new whitespace node after the child so the closing tag will be on
                    //  a new line with the same indentation.
                    //  If the whitespace we end up copying isn't actually (newline + indentation) like we expect, then it
                    //  should still be OK to copy it, as we'll still be trying to match the surrounding formatting.
                    string whitespace = XmlElement.FirstChild.Value;
                    XmlElement.FirstChild.Value = whitespace + DEFAULT_INDENT;
                    var newWhitespaceNode = XmlDocument.CreateWhitespace(whitespace);
                    XmlElement.InsertAfter(newWhitespaceNode, child.XmlElement);
                }
                else if (XmlElement.PreviousSibling != null &&
                         XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                {
                    //  This container didn't have any whitespace in it.  This probably means it didn't have separate open
                    //  and close tags.  So add a whitespace node before the new child with additional indentation over the
                    //  container's indentation, and add a whitespace node with the same level of indentation as the container
                    //  after the new child so the closing tag will be indented properly.
                    string parentWhitespace       = XmlElement.PreviousSibling.Value;
                    var    indentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace + DEFAULT_INDENT);
                    XmlElement.InsertBefore(indentedWhitespaceNode, child.XmlElement);
                    var unindentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace);
                    XmlElement.InsertAfter(unindentedWhitespaceNode, child.XmlElement);
                }
            }

            _count++;
            MarkDirty("Add child element named '{0}'", child.ElementName);
        }
예제 #2
0
        /// <summary>
        /// Insert the child before the reference child.
        /// Reference child if provided must be parented by this element.
        /// Reference child may be null, in which case this is equivalent to <see cref="AppendChild">AppendChild(child)</see>.
        /// Throws if the parent is not itself parented.
        /// Throws if the reference node does not have this node as its parent.
        /// Throws if the node to add is already parented.
        /// Throws if the node to add was created from a different project than this node.
        /// </summary>
        /// <remarks>
        /// Semantics are those of XmlNode.InsertBeforeChild.
        /// </remarks>
        public void InsertBeforeChild(ProjectElement child, ProjectElement reference)
        {
            ErrorUtilities.VerifyThrowArgumentNull(child, "child");

            if (reference == null)
            {
                AppendChild(child);
                return;
            }

            VerifyForInsertBeforeAfterFirst(child, reference);

            child.VerifyThrowInvalidOperationAcceptableLocation(this, reference.PreviousSibling, reference);

            child.Parent = this;

            if (FirstChild == reference)
            {
                FirstChild = child;
            }

            child.PreviousSibling = reference.PreviousSibling;
            child.NextSibling     = reference;

            reference.PreviousSibling = child;

            if (child.PreviousSibling != null)
            {
                ErrorUtilities.VerifyThrow(child.PreviousSibling.NextSibling == reference, "Invalid structure");
                child.PreviousSibling.NextSibling = child;
            }

            XmlElement.InsertBefore(child.XmlElement, reference.XmlElement);

            if (XmlDocument.PreserveWhitespace)
            {
                //  If we are trying to preserve formatting of the file, then the new node won't automatically be indented.
                //  So try to match the surrounding formatting by by checking the whitespace that precedes where we inserted
                //  the new node, and inserting the same whitespace between the node we added and the one after it.
                if (child.XmlElement.PreviousSibling != null &&
                    child.XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                {
                    var newWhitespaceNode = XmlDocument.CreateWhitespace(child.XmlElement.PreviousSibling.Value);
                    XmlElement.InsertBefore(newWhitespaceNode, reference.XmlElement);
                }
            }

            _count++;
            MarkDirty("Insert element {0}", child.ElementName);
        }
        /// <summary>
        /// Sets the first child in this container
        /// </summary>
        private void AddInitialChild(ProjectElement child)
        {
            ErrorUtilities.VerifyThrow(FirstChild == null && LastChild == null, "Expecting no children");

            VerifyForInsertBeforeAfterFirst(child, null);

            child.VerifyThrowInvalidOperationAcceptableLocation(this, null, null);

            child.Parent = this;

            FirstChild = child;
            LastChild  = child;

            child.PreviousSibling = null;
            child.NextSibling     = null;

            XmlElement.AppendChild(child.XmlElement);

            _count++;
            MarkDirty("Add child element named '{0}'", child.ElementName);
        }
예제 #4
0
        /// <summary>
        /// Insert the child before the reference child.
        /// Reference child if provided must be parented by this element.
        /// Reference child may be null, in which case this is equivalent to <see cref="AppendChild">AppendChild(child)</see>.
        /// Throws if the parent is not itself parented.
        /// Throws if the reference node does not have this node as its parent.
        /// Throws if the node to add is already parented.
        /// Throws if the node to add was created from a different project than this node.
        /// </summary>
        /// <remarks>
        /// Semantics are those of XmlNode.InsertBeforeChild.
        /// </remarks>
        public void InsertBeforeChild(ProjectElement child, ProjectElement reference)
        {
            ErrorUtilities.VerifyThrowArgumentNull(child, nameof(child));

            if (reference == null)
            {
                AppendChild(child);
                return;
            }

            VerifyForInsertBeforeAfterFirst(child, reference);

            child.VerifyThrowInvalidOperationAcceptableLocation(this, reference.PreviousSibling, reference);

            child.Parent = this;

            if (FirstChild == reference)
            {
                FirstChild = child;
            }

            child.PreviousSibling = reference.PreviousSibling;
            child.NextSibling     = reference;

            reference.PreviousSibling = child;

            if (child.PreviousSibling != null)
            {
                ErrorUtilities.VerifyThrow(child.PreviousSibling.NextSibling == reference, "Invalid structure");
                child.PreviousSibling.NextSibling = child;
            }

            AddToXml(child);

            Count++;
            MarkDirty("Insert element {0}", child.ElementName);
        }
        /// <summary>
        /// Insert the child after the reference child.
        /// Reference child if provided must be parented by this element.
        /// Reference child may be null, in which case this is equivalent to <see cref="PrependChild">PrependChild(child)</see>.
        /// Throws if the parent is not itself parented.
        /// Throws if the reference node does not have this node as its parent.
        /// Throws if the node to add is already parented.
        /// Throws if the node to add was created from a different project than this node.
        /// </summary>
        /// <remarks>
        /// Semantics are those of XmlNode.InsertAfterChild.
        /// </remarks>
        public void InsertAfterChild(ProjectElement child, ProjectElement reference)
        {
            ErrorUtilities.VerifyThrowArgumentNull(child, "child");

            if (reference == null)
            {
                PrependChild(child);
                return;
            }

            VerifyForInsertBeforeAfterFirst(child, reference);

            child.VerifyThrowInvalidOperationAcceptableLocation(this, reference, reference.NextSibling);

            child.Parent = this;

            if (LastChild == reference)
            {
                LastChild = child;
            }

            child.PreviousSibling = reference;
            child.NextSibling     = reference.NextSibling;

            reference.NextSibling = child;

            if (child.NextSibling != null)
            {
                ErrorUtilities.VerifyThrow(child.NextSibling.PreviousSibling == reference, "Invalid structure");
                child.NextSibling.PreviousSibling = child;
            }

            XmlElement.InsertAfter(child.XmlElement, reference.XmlElement);

            _count++;
            MarkDirty("Insert element {0}", child.ElementName);
        }