Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="docA"></param>
        /// <param name="docB"></param>
        public static void CompareXmlDocs(XmlDocument docA, XmlDocument docB)
        {
            XmlComparisonRules rules = new XmlComparisonRules();

            // optional output attributes
            //rules.AddOptionalAttribute(null, "xmlns"); // any node
            rules.AddOptionalAttribute(null, "xsi:schemaLocation");
            //rules.AddOptionalAttribute("requestAllocation/attr:", "xsi:schemaLocation");
            //rules.AddOptionalAttribute("requestAllocationRetracted/attr:", "xsi:schemaLocation");
            // add default values
            rules.AddDefaultAttribute(null, "entityIdScheme", "http://www.fpml.org/spec/2003/entity-id-RED-1-0");
            rules.AddDefaultAttribute(null, "contractualSupplementScheme", "http://www.fpml.org/coding-scheme/contractual-supplement");
            rules.AddDefaultAttribute(null, "currencyScheme", "http://www.fpml.org/ext/iso4217-2001-08-15");
            rules.AddDefaultAttribute(null, "exchangeIdScheme", "http://www.fpml.org/spec/2002/exchange-id-MIC-1-0");
            rules.AddDefaultAttribute(null, "partyIdScheme", "http://www.fpml.org/ext/iso9362");
            rules.AddDefaultAttribute(null, "facilityTypeScheme", "http://www.fpml.org/coding-scheme/facility-type");
            rules.AddDefaultAttribute(null, "dayCountFractionScheme", "http://www.fpml.org/coding-scheme/day-count-fraction");
            rules.AddDefaultAttribute(null, "routingIdCodeScheme", "http://www.fpml.org/ext/iso9362");
            rules.AddDefaultAttribute(null, "floatingRateIndexScheme", "http://www.fpml.org/coding-scheme/floating-rate-index");
            rules.AddDefaultAttribute(null, "interpolationMethodScheme", "http://www.fpml.org/coding-scheme/interpolation-method");
            rules.AddDefaultAttribute(null, "businessCenterScheme", "http://www.fpml.org/coding-scheme/business-center");
            rules.AddDefaultAttribute(null, "creditSupportAgreementTypeScheme", "http://www.fpml.org/coding-scheme/credit-support-agreement-type");
            rules.AddDefaultAttribute(null, "collateralMarginCallResponseReasonScheme", "http://www.fpml.org/coding-scheme/collateral-margin-call-response-reason");
            rules.AddDefaultAttribute(null, "categoryScheme", "http://www.fpml.org/coding-scheme/org-type-category");
            // nodes (trees) to ignore
            rules.AddPathToIgnore("xml/"); // XML declaration
            //rules.AddPathToIgnore("GWML/Signature/");
            //rules.AddPathToIgnore("GWML/trade/dateAdjustmentMethods/");
            //rules.AddPathToIgnore("GWML/trade/tradeHeader/partyTradeIdentifier/tradeId");
            CompareXmlAttrColls(rules, "attr:", docA.Attributes, docB.Attributes);
            CompareXmlNodeLists(rules, "", docA.ChildNodes, "", docB.ChildNodes);
        }
Beispiel #2
0
        private static void CompareXmlAttrColls(XmlComparisonRules rules, string path, XmlAttributeCollection a, XmlAttributeCollection b)
        {
            if (rules.IsIgnoredPath(path))
            {
                return;
            }
            if (a == null && b == null)
            {
                return;
            }
            SortedDictionary <string, XmlAttribute> listA = FilterAndSortAttrColl(path, a);
            SortedDictionary <string, XmlAttribute> listB = FilterAndSortAttrColl(path, b);
            // get all keys
            SortedSet <string> attrKeys = new SortedSet <string>();

            foreach (var key in listA.Keys)
            {
                attrKeys.Add(key);
            }
            foreach (var key in listB.Keys)
            {
                attrKeys.Add(key);
            }
            // compare attrs
            foreach (string attrKey in attrKeys)
            {
                if (!listA.TryGetValue(attrKey, out var attrA))
                {
                    continue;
                }
                if (listB.TryGetValue(attrKey, out var attrB))
                {
                    // both exist - compare
                    CompareXmlAttribute(rules, path + AttrSortKey(attrA) + "/", attrA, attrB);
                }
                else
                {
                    // attrB is missing - might be optional or have a default value
                    if (rules.IsOptionalAttribute(path, attrKey))
                    {
                        // allowed to be missing
                        continue;
                    }
                    if (rules.TryGetDefaultAttribute(path, attrKey, out var defaultAttribute))
                    {
                        CompareXmlAttribute(rules, path + AttrSortKey(attrA) + "/", attrA, defaultAttribute);
                    }
                    else
                    {
                        // missing and no default value - oops!
                        throw new Exception($"[{path}] Emitted Attribute '{attrKey}' missing!");
                    }
                }
            }
        }
Beispiel #3
0
        private static void CompareXmlTexts(XmlComparisonRules rules, string path, XmlText a, XmlText b)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (rules.IsIgnoredPath(path))
            {
                return;
            }

            if (a.InnerXml != b.InnerXml)
            {
                throw new Exception("[" + path + "] a.InnerXml != b.InnerXml");
            }
        }
Beispiel #4
0
 private static void CompareXmlAttribute(XmlComparisonRules rules, string path, XmlAttribute a, XmlDefaultAttribute b)
 {
     if (rules.IsIgnoredPath(path))
     {
         return;
     }
     if (a.Prefix != b.Prefix)
     {
         throw new Exception($"[{path}] Attr Prefix '{a.Prefix}' != '{b.Prefix}'");
     }
     if (a.LocalName != b.LocalName)
     {
         throw new Exception($"[{path}] Attr LocalName '{a.LocalName}' != '{b.LocalName}'");
     }
     if (a.Value != b.Value)
     {
         throw new Exception($"[{path}] Attr Value '{a.Value}' != '{b.Value}'");
     }
 }
Beispiel #5
0
        private static void CompareXmlNodeLists(XmlComparisonRules rules, string pathA, XmlNodeList nodeListA, string pathB, XmlNodeList nodeListB)
        {
            if (rules.IsIgnoredPath(pathA))
            {
                return;
            }
            if (nodeListA == null && nodeListB == null)
            {
                return;
            }
            SortedDictionary <string, XmlNode> listA = FilterAndSortNodeList(pathA, pathB, nodeListA);
            SortedDictionary <string, XmlNode> listB = FilterAndSortNodeList(pathA, pathB, nodeListB);
            // get all keys
            SortedSet <string> nodeKeys = new SortedSet <string>();

            foreach (var key in listA.Keys)
            {
                nodeKeys.Add(key);
            }
            foreach (var key in listB.Keys)
            {
                nodeKeys.Add(key);
            }
            // compare nodes
            foreach (string nodeKey in nodeKeys)
            {
                if (!listA.TryGetValue(nodeKey, out var nodeA))
                {
                    continue;
                }
                if (!listB.TryGetValue(nodeKey, out var nodeB))
                {
                    throw new Exception($"[{pathA}] Emitted node '{nodeKey}' missing!");
                }
                // both exist - compare
                CompareXmlNodes(rules, pathA + NodeSortKeyOld(nodeA, null) + "/", nodeA, pathB + NodeSortKeyOld(nodeB, null) + "/", nodeB);
            }
        }
Beispiel #6
0
 private static void CompareXmlNodes(XmlComparisonRules rules, string pathA, XmlNode nodeA, string pathB, XmlNode nodeB)
 {
     if (rules.IsIgnoredPath(pathA))
     {
         return;
     }
     if (rules.IsIgnoredPath(pathB))
     {
         return;
     }
     if (nodeA == null && nodeB == null)
     {
         return;
     }
     if (nodeA == null || nodeB == null)
     {
         throw new Exception("[" + pathA + "] (nodeA == null) || (nodeB == null)");
     }
     if (nodeA.GetType() != nodeB.GetType())
     {
         throw new Exception("[" + pathA + "] nodeA.GetType() != nodeB.GetType()");
     }
     // generic node comparison
     CompareXmlNodeNames(pathA, nodeA, nodeB);
     CompareXmlNodeTypes(pathA, nodeA, nodeB);
     CompareXmlAttrColls(rules, pathA + "attr:", nodeA.Attributes, nodeB.Attributes);
     if (nodeA.HasChildNodes || nodeB.HasChildNodes)
     {
         CompareXmlNodeLists(rules, pathA, nodeA.ChildNodes, pathB, nodeB.ChildNodes);
     }
     else
     {
         // no children - just compare value
         if (String.Compare(nodeA.Value, nodeB.Value, StringComparison.OrdinalIgnoreCase) != 0)
         {
             // values are textually different but could be numerically equal
             if (BothAreDateTimes(nodeA.Value, nodeB.Value))
             {
                 if (!CompareDateTimes(DateTimeStyles.None, nodeA.Value, nodeB.Value) &&
                     !CompareDateTimes(DateTimeStyles.AssumeLocal, nodeA.Value, nodeB.Value) &&
                     !CompareDateTimes(DateTimeStyles.AssumeUniversal, nodeA.Value, nodeB.Value) &&
                     !CompareDateTimes(DateTimeStyles.NoCurrentDateDefault, nodeA.Value, nodeB.Value) &&
                     !CompareWithDateTimeZoneParser(nodeA.Value, nodeB.Value, false) &&
                     !CompareWithDateTimeZoneParser(nodeA.Value, nodeB.Value, true)
                     )
                 {
                     // date/times are not equal!
                     throw new Exception($"[{pathA}] NodeValue (as DateTime) '{nodeA.Value}' != '{nodeB.Value}'");
                 }
             }
             else if (DateTimeOffset.TryParse(nodeA.Value, out var dtoA) && DateTimeOffset.TryParse(nodeB.Value, out var dtoB))
             {
                 if (dtoA != dtoB)
                 {
                     throw new Exception($"[{pathA}] NodeValue (as DateTimeOffset) '{dtoA}' != '{dtoB}'");
                 }
             }
             else if (Int32.TryParse(nodeA.Value, out var intA) && Int32.TryParse(nodeB.Value, out var intB))
             {
                 if (intA != intB)
                 {
                     throw new Exception($"[{pathA}] NodeValue (as Int32) '{intA}' != '{intB}'");
                 }
             }
             else if (Decimal.TryParse(nodeA.Value, out var numA) && Decimal.TryParse(nodeB.Value, out var numB))
             {
                 if (Math.Round(numA, 12) != Math.Round(numB, 12))
                 {
                     throw new Exception($"[{pathA}] NodeValue (as Decimal) '{numA}' != '{numB}'");
                 }
             }
             else
             {
                 throw new Exception($"[{pathA}] NodeValue '{nodeA.Value}' != '{nodeB.Value}'");
             }
         }
     }
     // specific node type comparisons
     if (nodeA.GetType() == typeof(XmlElement))
     {
         //CompareXmlElements(ignorePaths, path + "elt:" + nodeA.Name, nodeA as XmlElement, nodeB as XmlElement);
     }
     else if (nodeA.GetType() == typeof(XmlDeclaration))
     {
         //CompareXmlDeclarations(ignorePaths, path + "decl:" + nodeA.Name, nodeA as XmlDeclaration, nodeB as XmlDeclaration);
     }
     else if (nodeA.GetType() == typeof(XmlText))
     {
         CompareXmlTexts(rules, pathA + "text:" + nodeA.Name, nodeA as XmlText, nodeB as XmlText);
     }
     else
     {
         throw new NotImplementedException("[" + pathA + "] NodeType: " + nodeA.GetType().Name);
     }
 }