+//\r
+// xmldocdiff.cs\r
+//\r
+// Author:\r
+// Marek Safar (marek.safar@gmail.com)\r
+//\r
+// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+#if !MOBILE\r
+\r
using System;\r
using System.Collections;\r
+using System.Collections.Generic;\r
using System.Xml;\r
+using System.Linq;\r
\r
public class XmlComparer\r
{\r
}\r
}\r
\r
- static bool debug = false;\r
-/*\r
+ static readonly bool debug = false;\r
+ readonly string start;\r
\r
- public static void Main (string [] args)\r
+ public XmlComparer (string startNode)\r
{\r
- if (args.Length < 2) {\r
- Console.Error.WriteLine ("Usage: xmldocdiff [reference_output.xml] [actual_output.xml]");\r
- return;\r
- }\r
- if (args.Length > 2 && args [2].EndsWith ("-debug"))\r
- debug = true;\r
-\r
- try {\r
- Run (args[0], args[1]);\r
- } catch (Exception ex) {\r
- Console.WriteLine ("FAIL: " + args [1]);\r
- throw ex;\r
- }\r
- Console.WriteLine ("PASS: " + args [1]);\r
+ this.start = "/" + startNode;\r
}\r
-*/\r
- public static void Compare (string reference, string output)\r
+\r
+ public void Compare (string reference, string output)\r
{\r
XmlDocument doc1 = new XmlDocument ();\r
doc1.Load (reference);\r
XmlDocument doc2 = new XmlDocument ();\r
doc2.Load (output);\r
\r
- XmlNodeList memberList1 = doc1.SelectNodes ("/doc/members/member");\r
- XmlNodeList memberList2 = doc2.SelectNodes ("/doc/members/member");\r
+ var memberList1 = doc1.SelectSingleNode (start);\r
+ var memberList2 = doc2.SelectSingleNode (start);\r
+\r
+ CompareNodes (memberList1, memberList2);\r
+ }\r
+\r
+ static bool CompareNodes (XmlNode reference, XmlNode output)\r
+ {\r
+ List<Tuple<string, XmlNode>> ref_nodes = new List<Tuple<string, XmlNode>> ();\r
+ foreach (XmlNode node in reference.ChildNodes) {\r
+ if (node.NodeType == XmlNodeType.Comment)\r
+ continue;\r
\r
- Hashtable namedItems = new Hashtable ();\r
+ ref_nodes.Add (Tuple.Create (node.Name, node));\r
+ }\r
\r
- foreach (XmlElement el in memberList1)\r
- namedItems.Add (el.GetAttribute ("name"), el);\r
- foreach (XmlElement el2 in memberList2) {\r
- string name = el2.GetAttribute ("name");\r
- XmlElement el1 = namedItems [name] as XmlElement;\r
- if (el1 == null) {\r
- Report ("Extraneous element found. Name is '{0}'", name);\r
+ foreach (XmlNode node in output.ChildNodes) {\r
+ if (node.NodeType == XmlNodeType.Comment)\r
continue;\r
+\r
+ Tuple<string, XmlNode> found = null;\r
+ foreach (var entry in ref_nodes.Where (l => l.Item1 == node.Name)) {\r
+ if (node.Attributes == null) {\r
+ if (node.Attributes != entry.Item2.Attributes)\r
+ continue;\r
+ } else {\r
+ List<XmlAttribute> attrs = node.Attributes.Cast<XmlAttribute> ().ToList ();\r
+ XmlAttribute missing = null;\r
+ foreach (XmlAttribute attr in entry.Item2.Attributes) {\r
+ var match = attrs.Find (l => l.Name == attr.Name);\r
+ if (match == null) {\r
+ missing = attr;\r
+ break;\r
+ }\r
+\r
+ if (match.Value == attr.Value)\r
+ attrs.Remove (match);\r
+ }\r
+\r
+ if (missing != null || attrs.Count > 0) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (node.HasChildNodes != entry.Item2.HasChildNodes)\r
+ continue;\r
+\r
+ if (!node.HasChildNodes || CompareNodes (node, entry.Item2)) {\r
+ found = entry;\r
+ break;\r
+ }\r
}\r
- namedItems.Remove (name);\r
\r
- CompareNodes (el1, el2);\r
+ if (found == null) {\r
+ Report ("Expected node: " + node.OuterXml);\r
+ return false;\r
+ }\r
\r
+ ref_nodes.Remove (found);\r
}\r
- foreach (string name in namedItems.Keys)\r
- Report ("Expected comment was not found. Name is {0}, XML is {1}", name, ((XmlElement) namedItems [name]).OuterXml);\r
-\r
- // finally, check other nodes than members\r
- doc1.SelectSingleNode ("/doc/members").RemoveAll ();\r
- doc2.SelectSingleNode ("/doc/members").RemoveAll ();\r
- string xml1 = doc1.OuterXml.Replace ("\r", "").Trim ();\r
- string xml2 = doc2.OuterXml.Replace ("\r", "").Trim ();\r
- if (xml1 != xml2)\r
- Report (@"Either of doc, assembly, name, members elements are different.\r
-doc1: {0}\r
-doc2: {1}", xml1, xml2);\r
- }\r
\r
- private static void CompareNodes (XmlNode n1, XmlNode n2)\r
- {\r
- if (n2 == null) {\r
- Report (@"Nodes does not exist:\r
-Node1: {0}", n1.OuterXml);\r
- return;\r
- }\r
- if (n1.NodeType != n2.NodeType) {\r
- Report (@"Nodes differ:\r
-Node1: {0}\r
-Node2: {1}", n1.OuterXml, n2.OuterXml);\r
- return;\r
- }\r
- if (n1.Name != n2.Name) {\r
- Report (@"Node names differ:\r
-Node1: {0}\r
-Node2: {1}", n1.OuterXml, n2.OuterXml);\r
- return;\r
- }\r
- if (n1 is XmlElement) {\r
- for (int i = 0; i < n1.Attributes.Count; i++)\r
- CompareNodes (n1.Attributes [i],\r
- n2.Attributes [i]);\r
- for (int i = 0; i < n1.ChildNodes.Count; i++)\r
- CompareNodes (n1.ChildNodes [i],\r
- n2.ChildNodes [i]);\r
- }\r
- if (n1.NodeType != XmlNodeType.Comment && n1.Value != null) {\r
- string v1 = n1.Value.Trim ().Replace ("\r", "");\r
- string v2 = n2.Value.Trim ().Replace ("\r", "");\r
- if (v1 != v2)\r
- Report (@"Node values differ:\r
-Node1: {0}\r
-Node2: {1}", v1, v2);\r
+ if (ref_nodes.Count > 0) {\r
+ Report ("Unexpected node: " + ref_nodes[0].Item2.OuterXml);\r
+ return false;\r
}\r
+\r
+ return true;\r
}\r
\r
- static void Report (string format, params object [] args)\r
+ static void Report (string format, params object[] args)\r
{\r
if (debug)\r
Console.WriteLine (format, args);\r
}\r
}\r
\r
+#endif\r