/// <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}.", StringComparison.Ordinal)) { // 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); }
/// <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)); if (isMatchingChild == false || inMatchingChildBlock == false) { 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)); }