/// <summary> /// Build a tree of only one schema /// </summary> /// <param name="schemaA"></param> /// <returns></returns> public IDiffNode BuildTree(XmlSchemaObject obj) { // Setup the schema IDiffNode retVal = null; if (obj is XmlSchemaAttribute) retVal = new AttributeDiffNode() { Original = obj as XmlSchemaAttribute }; else if (obj is XmlSchemaElement) { retVal = new ElementDiffNode() { Original = obj as XmlSchemaElement }; CopyChildNodes((obj as XmlSchemaElement).SchemaType as XmlSchemaComplexType, retVal, new Stack<string>(), true); } else if (obj is XmlSchemaChoice) { retVal = new ChoiceDiffNode() { Original = obj as XmlSchemaChoice }; CopyChildNodes(obj as XmlSchemaChoice, retVal, new Stack<string>()); retVal = retVal.Children[0]; } else if (obj is XmlSchemaSequence) { retVal = new SequenceDiffNode() { Original = obj as XmlSchemaSequence }; CopyChildNodes(obj as XmlSchemaSequence, retVal, new Stack<string>()); if (TreatSequenceAsNode) retVal = retVal.Children[0]; } else return null; return retVal; }
/// <summary> /// Build a diff tree for the two schemas /// </summary> public DiffTree BuildTree(XmlSchemaSet schemaA, XmlSchemaSet schemaB) { // Setup the schema DiffTree retVal = new DiffTree() { Original = schemaA, Compared = schemaB }; // Now add all of the nodes in schemaA to the diff tree if (schemaA.Elements == null || schemaB.Elements == null || schemaA.Elements.Count == 0 || schemaB.Elements.Count == 0) throw new InvalidOperationException("Both schemas must have at least one root element in order to compare"); Stack<String> typeStack = new Stack<string>(); // Root node int i = 0; foreach (XmlSchemaElement ele in schemaA.Elements) { i++; ElementDiffNode rootNode = new ElementDiffNode() { Original = ele }; if (rootNode.Original.SchemaType is XmlSchemaComplexType) CopyChildNodes(rootNode.Original.SchemaType as XmlSchemaComplexType, rootNode, typeStack, false); retVal.Nodes.Add(rootNode); // Comparing, let any listeners know that we're still working if (Comparing != null) Comparing(this, ((float)i / schemaA.Elements.Count)/2); } // Comparison time... the DiffBuilder really just checks for added/removed nodes and places the NET nodes // into the tree... i = 0; foreach (XmlSchemaElement ele in schemaB.Elements) { i++; ElementDiffNode bRootNode = new ElementDiffNode() { Original = ele }; if (bRootNode.Original.SchemaType is XmlSchemaComplexType) CopyChildNodes(bRootNode.Original.SchemaType as XmlSchemaComplexType, bRootNode, typeStack, false); if (Comparing != null) Comparing(this, (float)(((float)i / schemaB.Elements.Count) / 2 + 0.5)); CompareNodes(retVal.Nodes, bRootNode, null); // Is this a new root node? if (retVal.Nodes.Find(o => o.FriendlyName == bRootNode.FriendlyName) == null) retVal.Nodes.Add(bRootNode); } retVal.CalculateDiff(); return retVal; }
/// <summary> /// Copy element data /// </summary> private void CopyChildNodes(XmlSchemaElement element, IDiffNode parent, Stack<String> typeStack) { if (element.MaxOccurs == "0") { if (parent.Children != null) { IDiffNode foundNode = parent.Children.Find(o => o.FriendlyName == element.Name); parent.Children.Remove(foundNode); } return; } else if (parent.Children != null && parent.Children.Find(o => o.FriendlyName == element.Name) != null) return; ElementDiffNode rootNode = new ElementDiffNode() { Original = element }; if (rootNode.Original.SchemaType is XmlSchemaComplexType) CopyChildNodes(rootNode.Original.SchemaType as XmlSchemaComplexType, rootNode, typeStack, true); parent.AddChild(rootNode); }