/// ------------------------------------------------------------------------------------ /// <summary> /// Perform one increment migration step. /// /// In this case, the migration is not related to a model change, /// but is a simple data change that removes the class elements in the xml. /// The end resujlt xml will have the top-level 'rt' element and zero, or more, /// property level elements. /// </summary> /// ------------------------------------------------------------------------------------ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository) { DataMigrationServices.CheckVersionNumber(domainObjectDtoRepository, 7000014); // No. We need to convert all instances, even if they are no longer part of the model. // DM19, for example, removes LgWritingSystem instances and the class form the model, // but it tries to access the data as if it had been properly processed by DM15, // *but* this code would leave out LgWritingSystem instnaces form being processed here. //foreach (var dto in domainObjectDtoRepository.AllInstancesWithSubclasses("CmObject")) foreach (var dto in domainObjectDtoRepository.AllInstances()) { var rtElement = XElement.Parse(dto.Xml); // Removes all current child nodes (class level), // and replaces them with the old property nodes (if any). #if !__MonoCS__ rtElement.ReplaceNodes(rtElement.Elements().Elements()); dto.Xml = rtElement.ToString(); #else // FWNX-165: work around mono bug https://bugzilla.novell.com/show_bug.cgi?id=592435 var copy = new XElement(rtElement); copy.ReplaceNodes(rtElement.Elements().Elements()); dto.Xml = copy.ToString(); #endif domainObjectDtoRepository.Update(dto); } DataMigrationServices.IncrementVersionNumber(domainObjectDtoRepository); }
/// <summary> /// Move VSM to last child of element. /// </summary> /// <param name="element">Element that is getting its VSM moved to the end.</param> private void ReorderChildNodes(XElement element) { List<NodeCollection> nodeCollections = new List<NodeCollection>(); NodeCollection vsmNodeCollection = new NodeCollection(); var children = element.Nodes(); bool hasCollectionBeenAdded = false; NodeCollection currentNodeCollection = null; foreach (var child in children) { if (currentNodeCollection == null) { currentNodeCollection = new NodeCollection(); } currentNodeCollection.Nodes.Add(child); if (child.NodeType == XmlNodeType.Element) { if (this.VSMNode.IsMatch(((XElement)child).Name)) { // Extract VSM for adding to end. vsmNodeCollection = currentNodeCollection; hasCollectionBeenAdded = true; } else if (!hasCollectionBeenAdded) { // Maintain all other nodes. nodeCollections.Add(currentNodeCollection); hasCollectionBeenAdded = true; } currentNodeCollection = null; hasCollectionBeenAdded = false; } } var newNodes = (this.Mode == VisualStateManagerRule.Last) ? nodeCollections.SelectMany(_ => _.Nodes).Concat(vsmNodeCollection.Nodes) : vsmNodeCollection.Nodes.Concat(nodeCollections.SelectMany(_ => _.Nodes)); element.ReplaceNodes(newNodes); }
private XElement GetOrderedElement(XElement element) { var children = element.Nodes().ToList(); var childElements = children.OfType<XElement>(). OrderBy(e => (string)e.Attribute("env")). OrderBy(e => (string)e.Attribute("key")). OrderBy(e => e.Name.LocalName). ToList(); var newChildren = childElements.Cast<XNode>().ToList(); var comments = children.OfType<XComment>().ToList(); newChildren = ProcessComments(comments, newChildren); foreach (var subsidiaryElement in newChildren.OfType<XElement>().Where(e => e.HasElements)) { subsidiaryElement.ReplaceWith(GetOrderedElement(subsidiaryElement)); } element.ReplaceNodes(newChildren); return element; }
public void AddData(Bot bot, double refs, int trades) { StoreName(bot); if (File.Exists(fileName)) { XDocument doc = XDocument.Load(fileName); XElement service = new XElement(bot.DisplayName); service.ReplaceNodes("trades", trades.ToString()); doc.Save(fileName); } else if (File.Exists(fileName)) { XDocument doc = XDocument.Load(fileName); XElement service = new XElement(bot.DisplayName); service.ReplaceNodes("refs", refs.ToString()); doc.Save(fileName); } else { CreateFile(); if (File.Exists(fileName)) { XDocument doc = XDocument.Load(fileName); XElement service = new XElement(bot.DisplayName); service.Add(new XElement("trades", trades.ToString())); doc.Save(fileName); } if (File.Exists(fileName)) { XDocument doc = XDocument.Load(fileName); XElement service = new XElement(bot.DisplayName); service.Add(new XElement("refs", refs.ToString())); doc.Save(fileName); } } }
/// <summary> /// Move VSM to last child of element. /// </summary> /// <param name="element">Element that is getting its VSM moved to the end.</param> private void ReorderChildNodes(XElement element) { List<NodeCollection> nodeCollections = new List<NodeCollection>(); List<NodeCollection> propertyElementCollection = new List<NodeCollection>(); NodeCollection vsmNodeCollection = new NodeCollection(); var parentName = element.Name; var children = element.Nodes().ToList(); bool hasCollectionBeenAdded = false; NodeCollection currentNodeCollection = null; //remove last new line node to prevent new lines on every format if (this.Mode == VisualStateManagerRule.Last) { children.Remove(children.Last()); } foreach (var child in children) { if (currentNodeCollection == null) { currentNodeCollection = new NodeCollection(); } currentNodeCollection.Nodes.Add(child); if (child.NodeType == XmlNodeType.Element) { var childName = ((XElement)child).Name; if (this.VSMNode.IsMatch(childName)) { // Extract VSM for adding to end. vsmNodeCollection = currentNodeCollection; hasCollectionBeenAdded = true; } else if(childName.LocalName.StartsWith($"{parentName.LocalName}.")) { // Extract property-element syntax nodes. propertyElementCollection.Add(currentNodeCollection); hasCollectionBeenAdded = true; } else if (!hasCollectionBeenAdded) { // Maintain all other nodes. nodeCollections.Add(currentNodeCollection); hasCollectionBeenAdded = true; } currentNodeCollection = null; hasCollectionBeenAdded = false; } } // Add any trailing non-Element nodes (e.g., comments). if (currentNodeCollection != null) { nodeCollections.Add(currentNodeCollection); } var newNodes = ((this.Mode == VisualStateManagerRule.Last) ? propertyElementCollection.SelectMany(_ => _.Nodes) .Concat(nodeCollections.SelectMany(_ => _.Nodes)) .Concat(vsmNodeCollection.Nodes) : propertyElementCollection.SelectMany(_ => _.Nodes) .Concat(vsmNodeCollection.Nodes) .Concat(nodeCollections.SelectMany(_ => _.Nodes))).ToList(); var firstNode = newNodes.First() as XText; if ((this.Mode == VisualStateManagerRule.Last) && firstNode != null && string.IsNullOrWhiteSpace(firstNode.Value.Trim())) { newNodes.Remove(firstNode); } element.ReplaceNodes(newNodes); }
public void XElementReplaceWithIEnumerable() { XElement xElem = new XElement("root"); IEnumerable<XNode> newValue = InputSpace.GetElement(1000, 2).DescendantNodes(); XElement xElemOriginal = new XElement(xElem); using (UndoManager undo = new UndoManager(xElem)) { undo.Group(); using (EventsHelper eHelper = new EventsHelper(xElem)) { xElem.ReplaceNodes(newValue); eHelper.Verify(XObjectChange.Add, newValue.ToArray()); } undo.Undo(); Assert.True(XNode.DeepEquals(xElem, xElemOriginal), "Undo did not work!"); } }
public void ExecuteXElementVariation(XNode toReplace) { XNode newValue = new XText("text"); XElement xElem = new XElement("root", InputSpace.GetAttributeElement(10, 1000).Elements().Attributes(), toReplace); XElement xElemOriginal = new XElement(xElem); using (UndoManager undo = new UndoManager(xElem)) { undo.Group(); using (EventsHelper eHelper = new EventsHelper(xElem)) { xElem.ReplaceNodes(newValue); Assert.True(xElem.Nodes().Count() == 1, "Did not replace correctly"); Assert.True(Object.ReferenceEquals(xElem.FirstNode, newValue), "Did not replace correctly"); Assert.True(xElem.HasAttributes, "ReplaceNodes removed attributes"); xElem.Verify(); eHelper.Verify(new XObjectChange[] { XObjectChange.Remove, XObjectChange.Add }, new XObject[] { toReplace, newValue }); } 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!"); } }
private void ProcessGrid(XElement element) { List<GridNodeContainer> lstNodeContainers = new List<GridNodeContainer>(); int commentIndex = int.MaxValue; var children = element.Nodes(); // Run through child elements & read the attributes foreach (var child in children) { switch (child.NodeType) { case XmlNodeType.Element: // it's an element. Search for Grid.Row attribute / Grid.Column attribute var childElement = (XElement)child; var rowAttr = childElement.Attributes("Grid.Row"); var columnAttr = childElement.Attributes("Grid.Column"); int row; int column; if (rowAttr == null || !rowAttr.Any() || !int.TryParse(rowAttr.First().Value, out row)) { row = childElement.Name.LocalName.Contains(".") ? -2 : -1; } if (columnAttr == null || !columnAttr.Any() || !int.TryParse(columnAttr.First().Value, out column)) { column = -1; } while (commentIndex < lstNodeContainers.Count) { lstNodeContainers[commentIndex].Row = row; commentIndex++; } commentIndex = int.MaxValue; // no attribute? 0,0 lstNodeContainers.Add(new GridNodeContainer(child, row, column)); break; default: // it's not an element - add it, passing in the previous row/column value - this ensures // comments, whitespace, ... are kept in the correct place var prev = lstNodeContainers.LastOrDefault(); if (prev != null) { lstNodeContainers.Add(new GridNodeContainer(child, prev.Row, prev.Column)); } else { lstNodeContainers.Add(new GridNodeContainer(child, int.MinValue, int.MinValue)); } if (child.NodeType == XmlNodeType.Comment && commentIndex == int.MaxValue) { commentIndex = lstNodeContainers.Count - 1; } break; } } // sort that list. lstNodeContainers = lstNodeContainers.OrderBy(nc => nc.Row).ThenBy(nc => nc.Column).ToList(); // replace the element's nodes element.ReplaceNodes(lstNodeContainers.Select(nc => nc.Node)); }
public void SaveAsXml(string path) { var xdoc = new XDocument(); xdoc.Add(new XElement("root")); //xdoc.Root = new XElement("root"); foreach (DataRow row in this.ResultTable.Rows) { var xItem = new XElement("item"); foreach (DataColumn column in ResultTable.Columns) { var xElement = new XElement(column.ColumnName); if (column.ColumnName == "details") xElement.ReplaceNodes(new XCData(row[column].ToString())); else xElement.Value = row[column].ToString(); xItem.Add(xElement); } xdoc.Root.Add(xItem); } xdoc.Save(path); }
/// <summary> /// Reorder child nodes matching ChildNodeNames /// </summary> /// <param name="element">Element thats getting its children reordered</param> private void ReorderChildNodes(XElement element) { List<NodeCollection> nodeCollections = new List<NodeCollection>(); var children = element.Nodes(); // This indicates if last element matched ChildNodeNames bool inMatchingChildBlock = false; // This value changes each time a non matching ChildNodeName is reached ensuring that only sortable elements are reordered int childBlockIndex = 0; NodeCollection currentNodeCollection = null; // Run through children foreach (var child in children) { if (currentNodeCollection == null) { currentNodeCollection = new NodeCollection(); nodeCollections.Add(currentNodeCollection); } if (child.NodeType == XmlNodeType.Element) { XElement childElement = (XElement)child; var isMatchingChild = ChildNodeNames.Any(match => match.IsMatch(childElement.Name)); if (isMatchingChild == false || inMatchingChildBlock == false) { childBlockIndex++; inMatchingChildBlock = isMatchingChild; } if (isMatchingChild) { currentNodeCollection.SortAttributeValues = SortByAttributes.Select(x => x.GetValue(childElement)).ToArray(); } currentNodeCollection.BlockIndex = childBlockIndex; } currentNodeCollection.Nodes.Add(child); if (child.NodeType == XmlNodeType.Element) currentNodeCollection = null; } if (currentNodeCollection != null) currentNodeCollection.BlockIndex = childBlockIndex + 1; // sort node list nodeCollections = nodeCollections.OrderBy(x => x).ToList(); // replace the element's nodes element.ReplaceNodes(nodeCollections.SelectMany(nc => nc.Nodes)); }
/// <summary> /// Reorder child nodes matching ChildNodeNames /// </summary> /// <param name="element">Element thats getting its children reordered</param> private void ReorderChildNodes(XElement element) { List<NodeCollection> nodeCollections = new List<NodeCollection>(); var children = element.Nodes(); // This indicates if last element matched ChildNodeNames. bool inMatchingChildBlock = false; // This value changes each time a non matching ChildNodeName is reached ensuring // that only sortable elements are reordered. int childBlockIndex = 0; NodeCollection currentNodeCollection = null; // Run through children. foreach (var child in children) { if (currentNodeCollection == null) { currentNodeCollection = new NodeCollection(); nodeCollections.Add(currentNodeCollection); } if (child.NodeType == XmlNodeType.Element) { XElement childElement = (XElement)child; var isMatchingChild = this.ChildNodeNames.Any(_ => _.IsMatch(childElement.Name)) && !this.ignoredNodeNames.Any(_ => _.IsMatch(childElement.Name)); if (!isMatchingChild || !inMatchingChildBlock) { childBlockIndex++; inMatchingChildBlock = isMatchingChild; } if (isMatchingChild) { currentNodeCollection.SortAttributeValues = this.SortByAttributes.Select(_ => _.GetValue(childElement)).ToArray(); } currentNodeCollection.BlockIndex = childBlockIndex; } currentNodeCollection.Nodes.Add(child); if (child.NodeType == XmlNodeType.Element) { currentNodeCollection = null; } } if (currentNodeCollection != null) { currentNodeCollection.BlockIndex = (childBlockIndex + 1); } // Sort node list. nodeCollections = nodeCollections.OrderBy(_ => _).ToList(); // Replace the element's nodes. element.ReplaceNodes(nodeCollections.SelectMany(_ => _.Nodes)); }
private void SortElement(XElement xe, bool sortElements, bool sortAttributes) { if (!xe.Elements().Any()) { return; } if (sortElements) { xe.ReplaceNodes(xe.Elements().OrderBy(x => x.Name.LocalName)); } if (sortAttributes) { xe.ReplaceAttributes(xe.Attributes().OrderBy(x => x.Name.LocalName)); } foreach (XElement xc in xe.Elements()) { SortElement(xc, sortElements, sortAttributes); } }
/// <summary> /// Order child setters by property/targetname /// /// Notes on index vars used: /// /// /// </summary> /// <param name="element"></param> private void ProcessSetters(XElement element) { // A string that hopefully always are sorted at the en List<SetterNodeCollection> nodeCollections = new List<SetterNodeCollection>(); var children = element.Nodes(); // This is increased each time Define sortable parameters int settersBlockIndex = 1; bool inSettersBlock = false; SetterNodeCollection currentNodeCollection = null; // Run through children foreach (var child in children) { if (currentNodeCollection == null) { currentNodeCollection = new SetterNodeCollection(); nodeCollections.Add(currentNodeCollection); } if (child.NodeType == XmlNodeType.Element) { XElement childElement = (XElement)child; var isSetter = childElement.Name.LocalName == "Setter" && childElement.Name.NamespaceName == "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; if (isSetter != inSettersBlock) { settersBlockIndex++; inSettersBlock = isSetter; } if (isSetter) { currentNodeCollection.Property = (string)childElement.Attribute("Property"); currentNodeCollection.TargetName = (string)childElement.Attribute("TargetName"); } currentNodeCollection.BlockIndex = settersBlockIndex; } currentNodeCollection.Nodes.Add(child); if (child.NodeType == XmlNodeType.Element) currentNodeCollection = null; } if (currentNodeCollection != null) currentNodeCollection.BlockIndex = settersBlockIndex + 1; // sort that list. switch (Options.ReorderSetters) { case ReorderSettersBy.None: break; case ReorderSettersBy.Property: nodeCollections = nodeCollections.OrderBy(x => x.BlockIndex).ThenBy(x=>x.Property).ToList(); break; case ReorderSettersBy.TargetName: nodeCollections = nodeCollections.OrderBy(x => x.BlockIndex).ThenBy(x => x.TargetName).ToList(); break; case ReorderSettersBy.TargetNameThenProperty: nodeCollections = nodeCollections.OrderBy(x => x.BlockIndex).ThenBy(x => x.TargetName).ThenBy(x => x.Property).ToList(); break; default: throw new ArgumentOutOfRangeException(); } // replace the element's nodes element.ReplaceNodes(nodeCollections.SelectMany(nc => nc.Nodes)); }
/// <summary> /// Validate ReplaceNodes on container. /// </summary> /// <param name="contextValue"></param> /// <returns></returns> //[Variation(Desc = "ContainerReplaceNodes")] public void ContainerReplaceNodes() { XElement element = new XElement("foo", new XAttribute("att", "bar"), "abc", new XElement("nested", new XText("abcd"))); // Replace with a node, attribute, string, some other value, and an IEnumerable. // ReplaceNodes does not remove attributes. XComment comment = new XComment("this is a comment"); XComment comment2 = new XComment("this is a comment 2"); XComment comment3 = new XComment("this is a comment 3"); XAttribute attribute = new XAttribute("att2", "att-value"); string str = "this is a string"; TimeSpan other1 = new TimeSpan(1, 2, 3); element.ReplaceNodes( comment, attribute, str, other1, new XComment[] { comment2, comment3 }); Validate.EnumeratorDeepEquals( element.Nodes(), new XNode[] { comment, new XText(str + XmlConvert.ToString(other1)), comment2, comment3 }); Validate.Count(element.Attributes(), 2); Validate.AttributeNameAndValue(element.Attribute("att"), "att", "bar"); Validate.AttributeNameAndValue(element.Attribute("att2"), "att2", "att-value"); }
//[Variation(Desc = "Tuple - New Dev10 Types", Param = 1)] //[Variation(Desc = "DynamicObject - New Dev10 Types", Param = 2)] //[Variation(Desc = "Guid - old type", Param = 3)] //[Variation(Desc = "Dictionary - old type", Param = 4)] public void CreatingXElementsFromNewDev10Types() { object t = null; Type type = typeof(object); int param = (int)this.Variation.Param; switch (param) { case 1: t = Tuple.Create(1, "Melitta", 7.5); type = typeof(Tuple); break; case 3: t = new Guid(); type = typeof(Guid); break; case 4: t = new Dictionary<int, string>(); ((Dictionary<int, string>)t).Add(7, "a"); type = typeof(Dictionary<int, string>); break; } XElement e = new XElement("e1", new XElement("e2"), "text1", new XElement("e3"), t); e.Add(t); e.FirstNode.ReplaceWith(t); XNode n = e.FirstNode.NextNode; n.AddBeforeSelf(t); n.AddAnnotation(t); n.ReplaceWith(t); e.FirstNode.AddAfterSelf(t); e.AddFirst(t); e.Annotation(type); e.Annotations(type); e.RemoveAnnotations(type); e.ReplaceAll(t); e.ReplaceAttributes(t); e.ReplaceNodes(t); e.SetAttributeValue("a", t); e.SetElementValue("e2", t); e.SetValue(t); XAttribute a = new XAttribute("a", t); XStreamingElement se = new XStreamingElement("se", t); se.Add(t); try { new XDocument(t); } catch (ArgumentException) { try { new XDocument(t); } catch (ArgumentException) { return; } } TestLog.Compare(false, "Failed"); }
public void XLinq65() { XElement elem = new XElement("customer", "this is an XElement", new XAttribute("id", "abc")); Console.WriteLine("Original element {0}", elem); elem.ReplaceNodes("this is a coustomer element"); Console.WriteLine("Updated element {0}", elem); object[] newContent = { "this is a customer element", new XElement("phone", "555-555-5555"), new XComment("new customer"), new XAttribute("name", "Jack") }; elem.ReplaceNodes(newContent); Console.WriteLine("Updated element {0}", elem); }
private void MergeAsRawXml(XElement mergedElement, XElement partElement) { if (partElement.HasAttributes) MergeAttributes(mergedElement, partElement); var elements = mergedElement.Nodes().ToList(); var partNodes = partElement.Nodes(); foreach (var partNode in partNodes) { if (partNode is XComment) { elements.Add(partNode); continue; } if (partNode is XText) { elements.Clear(); elements.Add(partNode); return; } if (partNode is XElement) { var partChildElement= (XElement)partNode; var correspondingMergedElements = elements.Where(e => e is XElement && ((XElement) e).Name.Equals(partChildElement.Name)).ToList(); if (correspondingMergedElements.Count != 1) elements.Add(partChildElement); else MergeAsRawXml((XElement) correspondingMergedElements[0], partChildElement); } } mergedElement.ReplaceNodes(elements); }
private static XElement SortXml (XElement node) { node.ReplaceNodes ( from element in node.Elements () orderby element.Attribute ("category").Value, element.Attribute ("id").Value select SortXml(element)); return node; }
private void MergeBasedOnConfig(XElement mergedElement, XElement partElement, ConfigurationElement configElement) { var defaultCollectionProperty = configElement.GetType() .GetProperties() .FirstOrDefault(p => { var attr = (ConfigurationPropertyAttribute) Attribute.GetCustomAttribute(p, typeof (ConfigurationPropertyAttribute)); return attr!=null && attr.IsDefaultCollection; }); if (defaultCollectionProperty != null) { var configCollectionAttribute = (ConfigurationCollectionAttribute)Attribute.GetCustomAttribute(defaultCollectionProperty.PropertyType, typeof (ConfigurationCollectionAttribute)); if (configCollectionAttribute != null) { var keyProperty = configCollectionAttribute.ItemType.GetProperties() .Select(p => new { Property = p, Attribute = (ConfigurationPropertyAttribute) Attribute.GetCustomAttribute(p, typeof ( ConfigurationPropertyAttribute )) }) .FirstOrDefault(p => p.Attribute != null && p.Attribute.IsKey); if (keyProperty != null) { MergeAttributes(mergedElement, partElement); var mergedElements = mergedElement.Nodes().OfType<XElement>().ToList(); foreach (var partChildElement in partElement.Nodes().OfType<XElement>()) { var key = partChildElement.Attributes() .FirstOrDefault( a => a.Name.LocalName.Equals(keyProperty.Attribute.Name, StringComparison.OrdinalIgnoreCase)); if (key == null) continue; var mergedChildElement = mergedElements .FirstOrDefault(e => { var keyAttribute = e.Attribute(key.Name); return keyAttribute != null && key.Value.Equals(keyAttribute.Value); }); if (mergedChildElement != null) mergedElements.Remove(mergedChildElement); mergedElements.Add(partChildElement); } mergedElement.ReplaceNodes(mergedElements); return; } } } // TODO: actually, we should dig into each ConfigurationElement, but we'll skip it for now MergeAsRawXml(mergedElement, partElement); }
/// <summary> /// Method to add a new book to the catalog. /// Defines the implementation of the POST method. /// </summary> public BookDetails CreateBook(BookDetails book) { try { // Retrieve the book with the highest ID from the catalog. var highestBook = ( from bookNode in xmlDocument.Elements("catalog").Elements("book") orderby bookNode.Attribute("id").Value descending select bookNode).Take(1); // Extract the ID from the book data. string highestId = highestBook.Attributes("id").First().Value; // Create an ID for the new book. string newId = "bk" + (Convert.ToInt32(highestId.Substring(2)) + 1).ToString(); // Verify that this book ID does not currently exist. if (this.ReadBook(newId) == null) { // Retrieve the parent element for the book catalog. XElement bookCatalogRoot = xmlDocument.Elements("catalog").Single(); // Create a new book element. XElement newBook = new XElement("book", new XAttribute("id", newId)); // Create elements for each of the book's data items. XElement[] bookInfo = FormatBookData(book); // Add the element to the book element. newBook.ReplaceNodes(bookInfo); // Append the new book to the XML document. bookCatalogRoot.Add(newBook); // Save the XML document. xmlDocument.Save(xmlFilename); // Return an object for the newly-added book. return this.ReadBook(newId); } } catch (Exception ex) { // Rethrow the exception. throw ex; } // Return null to signify failure. return null; }
private void ProcessCanvas(XElement element) { List<CanvasNodeContainer> lstNodeContainers = new List<CanvasNodeContainer>(); var children = element.Nodes(); // Run through child elements & read the attributes foreach (var child in children) { switch (child.NodeType) { case XmlNodeType.Element: // it's an element. Search for attached Canvas properties var leftAttr = ((XElement)child).Attributes("Canvas.Left"); var topAttr = ((XElement)child).Attributes("Canvas.Top"); var rightAttr = ((XElement)child).Attributes("Canvas.Right"); var bottomAttr = ((XElement)child).Attributes("Canvas.Bottom"); int left = -1; int right = -1; int top = -1; int bottom = -1; if (leftAttr != null && leftAttr.Any() && !int.TryParse(leftAttr.First().Value, out left)) { left = -1; } if (rightAttr != null && rightAttr.Any() && !int.TryParse(rightAttr.First().Value, out right)) { right = -1; } if (bottomAttr != null && bottomAttr.Any() && !int.TryParse(bottomAttr.First().Value, out bottom)) { bottom = -1; } if (topAttr != null && topAttr.Any() && !int.TryParse(topAttr.First().Value, out top)) { top = -1; } // no attribute? 0,0 lstNodeContainers.Add(new CanvasNodeContainer(child, left, top, right, bottom)); break; default: // it's not an element - add it, passing in the previous attached property value - this ensures // comments, whitespace, ... are kept in the correct place var prev = lstNodeContainers.LastOrDefault(); if (prev != null) { lstNodeContainers.Add(new CanvasNodeContainer(child, prev.Left, prev.Top, prev.Right, prev.Bottom)); } else { // add with minvalue - this must be the first item at all times. // cfr: https://github.com/NicoVermeir/XamlStyler/issues/9 lstNodeContainers.Add(new CanvasNodeContainer(child, double.MinValue, double.MinValue, double.MinValue, double.MinValue)); } break; } } // sort that list. lstNodeContainers = lstNodeContainers.OrderBy(nc => nc.LeftNumeric).ThenBy(nc => nc.TopNumeric) .ThenBy(nc => nc.RightNumeric).ThenBy(nc => nc.BottomNumeric).ToList(); // replace the element's nodes element.ReplaceNodes(lstNodeContainers.Select(nc => nc.Node)); }