예제 #1
0
        public static bool Validate(XDocument xDoc, XmlSchemaSet schemaSet, TextWriter output)
        {
            var hasError = false;
            var rules    = RuleParser.GetRules(schemaSet, xDoc.Root.GetDefaultNamespace().NamespaceName);

            xDoc.Validate(schemaSet, OnError, true);

            void OnError(object sender, ValidationEventArgs args)
            {
                hasError = true;
                output.WriteLine("Error");
                output.WriteLine($"- Message: {args.Exception.Message}");
                if (sender is XObject xo)
                {
                    output.WriteLine($"- Position: {XPath(xo)}");
                }
                else
                {
                    output.WriteLine("- Position: (Unknown)");
                }

                output.WriteLine();
            }

            return(hasError);

            string XPath(XObject xo)
            {
                var sb      = new StringBuilder();
                var current = xo;

                while (!(current is null))
                {
                    if (current is XElement xe)
                    {
                        if (rules.Contains(xe.Name.LocalName))
                        {
                            var selector = new StringBuilder();
                            var pks      = rules[xe.Name.LocalName].Where(r => r.IsPrimaryKey).ToList();
                            if (pks.Any())
                            {
                                selector.Append('[');
                                foreach (var key in pks)
                                {
                                    try
                                    {
                                        var value = xe.Attribute(key.PropertyName);
                                        if (value is null)
                                        {
                                            continue;
                                        }

                                        if (selector.Length > 1)
                                        {
                                            selector.Append(" and ");
                                        }

                                        selector.Append(value);
                                    }
                                    catch
                                    {
                                    }
                                }

                                selector.Append(']');

                                if (selector.Length > 2)
                                {
                                    sb.Insert(0, selector);
                                }
                            }
                        }

                        sb.Insert(0, $"/{xe.Name.LocalName}");
                    }
                    else if (current is XAttribute xa)
                    {
                        sb.Insert(0, $"/@{xa.Name.LocalName}");
                    }

                    current = current.Parent;
                }

                return(sb.ToString());
            }
        }