示例#1
0
 public void ExecuteXDocumentVariation(XNode[] toAdd, XNode contextNode)
 {
     IEnumerable<XNode> toAddList = toAdd.OfType<XNode>();
     XDocument xDoc = new XDocument(contextNode);
     XDocument xDocOriginal = new XDocument(xDoc);
     using (UndoManager undo = new UndoManager(xDoc))
     {
         undo.Group();
         using (EventsHelper docHelper = new EventsHelper(xDoc))
         {
             using (EventsHelper nodeHelper = new EventsHelper(contextNode))
             {
                 contextNode.AddBeforeSelf(toAdd);
                 Assert.True(toAddList.SequenceEqual(contextNode.NodesBeforeSelf(), XNode.EqualityComparer), "Nodes not added correctly!");
                 nodeHelper.Verify(0);
             }
             docHelper.Verify(XObjectChange.Add, toAdd);
         }
         undo.Undo();
         Assert.True(XNode.DeepEquals(xDoc, xDocOriginal), "Undo did not work!");
     }
 }
示例#2
0
 public void ExecuteXElementVariation(XNode[] toAdd, XNode contextNode)
 {
     IEnumerable<XNode> toAddList = toAdd.OfType<XNode>();
     XElement xElem = new XElement("root", contextNode);
     XElement xElemOriginal = new XElement(xElem);
     using (UndoManager undo = new UndoManager(xElem))
     {
         undo.Group();
         using (EventsHelper elemHelper = new EventsHelper(xElem))
         {
             using (EventsHelper nodeHelper = new EventsHelper(contextNode))
             {
                 contextNode.AddBeforeSelf(toAdd);
                 Assert.True(toAddList.SequenceEqual(contextNode.NodesBeforeSelf(), XNode.EqualityComparer), "Nodes not added correctly!");
                 nodeHelper.Verify(0);
             }
             elemHelper.Verify(XObjectChange.Add, toAdd);
         }
         undo.Undo();
         Assert.True(xElem.Nodes().SequenceEqual(xElemOriginal.Nodes(), XNode.EqualityComparer), "Undo did not work!");
         Assert.True(xElem.Attributes().EqualsAllAttributes(xElemOriginal.Attributes(), Helpers.MyAttributeComparer), "Undo did not work!");
     }
 }
示例#3
0
        /// <summary>
        /// Handles insignificant white spaces.
        /// There are 4 white spaces characters: carriage return '\r', linefeed '\n', tab '\t', and spacebar (' ').
        /// This handles xml:space = "preserve" that protects any text in an element or its
        /// descendants except inside any child with xml:space="default".
        /// </summary>
        /// <param name="this">This document.</param>
        /// <param name="actualTextProcessor">
        /// Optional transformer for texts that are not entirely white spaces and for which white spaces
        /// are not preserved. The function is called with the current start line and the <see cref="StringBuilder"/>
        /// that can be changed: the function must return true if the content of the StringBuilder must be considered.
        /// </param>
        /// <returns>This document.</returns>
        public static XDocument Beautify(this XDocument @this, Func <string, StringBuilder, bool> actualTextProcessor = null)
        {
            bool?GetPreserve(XElement e)
            {
                var p = (string)e.Attribute(_xmlSpace);

                return(p == null ? (bool?)null : p == "preserve");
            }

            string indent = "  ";

            void Process(XElement e, bool preserve, string outerStartLine, int depth)
            {
                string startLine = outerStartLine + indent;

                if (preserve)
                {
                    foreach (var child in e.Elements())
                    {
                        Process(child, preserve, startLine, depth + 1);
                    }
                    return;
                }
                bool  hasContent   = false;
                var   currentXText = new List <XText>();
                var   currentText  = new StringBuilder();
                XNode c            = e.FirstNode;

                while (c != null)
                {
                    if (c is XText t)
                    {
                        currentXText.Add(t);
                        currentText.Append(t.Value);
                    }
                    else
                    {
                        hasContent = true;
                        Debug.Assert(c is XElement || c is XComment || c is XCData || c is XProcessingInstruction);
                        // Handling current collected XText, possibly replacing them with a unique XText.
                        if (currentXText.Count == 0)
                        {
                            c.AddBeforeSelf(new XText(startLine));
                        }
                        else
                        {
                            HandleCollectedXText(actualTextProcessor, startLine, currentXText, currentText, false);
                        }
                        if (c is XElement cE)
                        {
                            Process(cE, GetPreserve(cE) ?? preserve, startLine, depth + 1);
                        }
                        currentXText.Clear();
                        currentText.Clear();
                    }
                    c = c.NextNode;
                }
                if (currentXText.Count == 0)
                {
                    if (hasContent)
                    {
                        e.LastNode.AddAfterSelf(new XText(outerStartLine));
                    }
                }
                else
                {
                    HandleCollectedXText(actualTextProcessor, outerStartLine, currentXText, currentText, !hasContent);
                }
            }

            Process(@this.Root, false, Environment.NewLine, 0);
            return(@this);
        }
示例#4
0
        /// <summary>
        ///     Ensures the whitespace separation for the first child element added to a node.
        /// </summary>
        /// <param name="element"></param>
        private void EnsureFirstNodeWhitespaceSeparation(XNode element)
        {
#if DEBUG
            if (element.Parent != null)
            {
                Debug.Assert(element.Parent.Elements().Count() == 1, "Unexpected count of elements!");
            }
            else
            {
                // if first.Parent is null, then this is the root element in a document
                Debug.Assert(element.Document.Root == element, "element had null parent, but is not the root element of the document");
            }
#endif

            var precedingNewLine = new XText(Environment.NewLine + new string(' ', GetIndentLevel() * 2));
            var trailingNewLine = new XText(Environment.NewLine + new string(' ', Parent.GetIndentLevel() * 2));
            element.AddBeforeSelf(precedingNewLine);
            element.AddAfterSelf(trailingNewLine);
        }
示例#5
0
        /// <summary>
        ///     Ensures the whitespace separation between two nodes.  Appropriate whitespace is added before the given node
        /// </summary>
        /// <param name="first"></param>
        private XText EnsureWhitespaceBeforeNode(XNode node)
        {
            Debug.Assert(
                node.Parent != null && node.Parent.Elements().Count() > 0,
                "Call EnsureFirstNodeWhitespaceSeparation when the added element is the first node");

            var newLine = new XText(Environment.NewLine + new string(' ', GetIndentLevel() * 2));
            node.AddBeforeSelf(newLine);
            return newLine;
        }