public static void Combine(List <string> originalFiles, List <string> files, List <string> breadcrumbs, bool notifyCollissions, string outputPath) { XmlCombiner.notifyCollissions = notifyCollissions; var result = XmlTools.LoadDocument(originalFiles[originalFiles.Count - 1]); var originalDocElems = originalFiles.Select(file => (XmlNode)XmlTools.LoadDocument(file).DocumentElement).ToList(); var docElems = files.Select(file => (XmlNode)XmlTools.LoadDocument(file).DocumentElement).ToList(); RecursiveCombine(result.DocumentElement, originalDocElems, docElems, breadcrumbs); File.Delete(outputPath); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); result.Save(outputPath); }
public static void Combine(XmlDocument result, List <XmlDocument> originalDocs, List <XmlDocument> docs, List <string> breadcrumbs) { notifyCollissions = false; var docElems = new List <XmlNode>(docs.Count); var originalDocElems = new List <XmlNode>(originalDocs.Count); foreach (XmlDocument file in docs) { docElems.Add(file.DocumentElement); } foreach (XmlDocument file in originalDocs) { originalDocElems.Add(file.DocumentElement); } RecursiveCombine(result.DocumentElement, originalDocElems, docElems, breadcrumbs); System.Diagnostics.Debug.WriteLine(XmlTools.GetOuterXml(result.DocumentElement)); }
private static List <XmlNode> GetCorrespondingNodes(XmlNode originalNode, List <XmlNode> nodes) { var correspondingNodes = new List <XmlNode>(nodes.Count); var originalId = XmlTools.GetID(originalNode); if (originalId == null) { foreach (var node in nodes) { XmlNode result = null; if (originalNode.ParentNode.ChildNodes.Count == 1 && node.ChildNodes.Count == 1) { result = node.ChildNodes[0]; } correspondingNodes.Add(result); } } else { foreach (var node in nodes) { XmlNode result = null; foreach (XmlNode childNode in node) { var id = XmlTools.GetID(childNode); if (id == originalId) { result = childNode; break; } } correspondingNodes.Add(result); } } return(correspondingNodes); }
private static void RecursiveCombine(XmlNode result, List <XmlNode> originalNodes, List <XmlNode> nodes, List <string> breadcrumbs) { if (result.NodeType == XmlNodeType.Text) { foreach (var node in originalNodes) { if (node.NodeType != XmlNodeType.Text) { throw new Exception("All original nodes are not text nodes. Post a comment at jc3mods telling what mods you were trying to combine."); } } foreach (var node in nodes) { if (node.NodeType != XmlNodeType.Text) { throw new Exception("All nodes are not text nodes. Post a comment at jc3mods telling what mods you were trying to combine."); } } var selectionItems = GetSelectionItems(originalNodes, nodes, breadcrumbs); if (selectionItems.Count == 0) { return; } if (selectionItems.Count == 1) { if (selectionItems[0].Name != "Original") { ChangeNode(result, (XmlNode)selectionItems[0].Value); } return; } if (selectionItems[0].Name == "Original" && selectionItems.Count == 2) { ChangeNode(result, (XmlNode)selectionItems[1].Value); } var replacingNode = (XmlNode)selectionItems[selectionItems.Count - 1].Value; object selectionResult = null; if (notifyCollissions && SelectionDialog.Show("Collission at " + XmlTools.GetPath(result), selectionItems, out selectionResult, out notifyCollissions)) { replacingNode = (XmlNode)selectionResult; } ChangeNode(result, replacingNode); } else if (result.NodeType == XmlNodeType.Element) { var resultNodeDict = new NodeDictionary(result); var nodeDict = new NodeDictionary(); foreach (var node in nodes) { foreach (XmlNode childNode in node) { var id = XmlTools.GetID(childNode); if (id != null) { nodeDict[id] = childNode; } } } foreach (var node in originalNodes) { if (node.NodeType != XmlNodeType.Element) { throw new Exception("All original nodes are not Elements. Post a comment at jc3mods telling what mods you were trying to combine."); } } foreach (var node in nodes) { if (node.NodeType != XmlNodeType.Element) { throw new Exception("All nodes are not Elements. Post a comment at jc3mods telling what mods you were trying to combine."); } } var nodesToRemove = new List <XmlNode>(); foreach (XmlNode resultChildNode in result) { var correspondingOriginalNodes = GetCorrespondingNodes(resultChildNode, originalNodes); var correspondingNodes = GetCorrespondingNodes(resultChildNode, nodes); var changeIds = GetChangedIds(correspondingOriginalNodes, correspondingNodes); if (changeIds.Count == 0) { continue; } if (changeIds.Count == 1) { if (correspondingNodes[changeIds[0][0]] == null) { nodesToRemove.Add(resultChildNode); } else { ChangeNode(resultChildNode, correspondingNodes[changeIds[0][0]]); } continue; } var nullFound = false; var nonNullChangeFound = false; foreach (List <int> l in changeIds) { foreach (int i in l) { var node = nodes[i]; if (node == null) { nullFound = true; } else { nonNullChangeFound = true; } } } if (nullFound && !nonNullChangeFound) { nodesToRemove.Add(resultChildNode); } else { var nullIds = new List <int>(); var continueIds = new List <int>(); foreach (List <int> l in changeIds) { foreach (int i in l) { if (correspondingNodes[i] == null) { nullIds.Add(i); } else { continueIds.Add(i); } } } var continueCombining = correspondingNodes[changeIds[changeIds.Count - 1][0]] != null; if (notifyCollissions && nullIds.Count > 0) { var selectionItems = new List <SelectionItem>(); selectionItems.Add(new SelectionItem() { Name = "Null", Description = "", Value = false }); selectionItems.Add(new SelectionItem() { Name = "Continue combining", Description = "", Value = true }); foreach (int index in nullIds) { selectionItems[0].Description += (selectionItems[0].Description.Length == 0 ? "" : "\n") + breadcrumbs[index]; } foreach (int index in continueIds) { selectionItems[1].Description += (selectionItems[1].Description.Length == 0 ? "" : "\n") + breadcrumbs[index]; } object selectionResult = null; if (SelectionDialog.Show("Collission at " + XmlTools.GetPath(resultChildNode), selectionItems, out selectionResult, out notifyCollissions)) { continueCombining = (bool)selectionResult; } } if (!continueCombining) { nodesToRemove.Add(resultChildNode); } else { var originalChildNodes2 = correspondingOriginalNodes; originalChildNodes2.RemoveAll(item => item == null); var childNodes2 = new List <XmlNode>(continueIds.Count); var breadcrumbs2 = new List <string>(continueIds.Count); foreach (int index in continueIds) { childNodes2.Add(correspondingNodes[index]); breadcrumbs2.Add(breadcrumbs[index]); } RecursiveCombine(resultChildNode, originalChildNodes2, childNodes2, breadcrumbs2); } } } foreach (XmlNode node in nodesToRemove) { result.RemoveChild(node); } foreach (KeyValuePair <string, XmlNode> entry in nodeDict) { if (!resultNodeDict.ContainsKey(entry.Key)) { result.AppendChild(result.OwnerDocument.ImportNode(entry.Value, true)); } } } else { throw new Exception("Cant combine nodes of type " + result.NodeType); } }