private bool GetLineNumberBySaxon(ProcessorEvaluation evaluation, string location, out IXmlLineInfo info)
 {
     info = null;
     try
     {
         XmlNode node = evaluation.SelectNode(location);
         if (node == null)
         {
             throw new Exception();
         }
         string   findAt = FindAtPath(node.CreateNavigator());
         XElement find   = evaluation.XPathSelectElement(findAt);
         info = find as IXmlLineInfo;
     }
     catch { }
     return(info?.HasLineInfo() ?? false);
 }
        public ResultCollection Validation(string xmlfile)
        {
            ResultCollection    results    = new ResultCollection();
            XmlDocument         doc        = null;
            XDocument           xdoc       = null;
            ProcessorEvaluation evaluation = null;

            try
            {
                xdoc = XDocument.Load(xmlfile, LoadOptions.SetLineInfo);

                doc = _processor.Validation(xmlfile);

                if (IsDebug)
                {
                    File.WriteAllText(Path.ChangeExtension(xmlfile, ".report.xml"), doc.OuterXml, Encoding.UTF8);
                }
                XmlNodeList nodes = doc.SelectNodes("//*[local-name()='failed-assert' or local-name()='successful-report']");
                if (nodes != null)
                {
                    foreach (XmlNode node in nodes)
                    {
                        Result result = new Result();
                        result.SchFile = SchemaSrc;
                        result.XmlFile = new FileInfo(xmlfile);

                        result.Status    = node.LocalName == "failed-assert" ? ResultStatus.Assert : ResultStatus.Report;
                        result.Test      = node.Attributes["test"]?.Value ?? "";
                        result.Location  = node.Attributes["location"]?.Value ?? "";
                        result.Role.Name = node.Attributes["role"]?.Value ?? "";

                        IXmlLineInfo lineinfo = null;
                        if (!GetLineNumber(xdoc, result.Location, out lineinfo))
                        {
                            if (evaluation == null)
                            {
                                evaluation = new ProcessorEvaluation(xdoc);
                                evaluation.Compile(_processor.Processor);
                            }
                            GetLineNumberBySaxon(evaluation, result.Location, out lineinfo);
                        }
                        if (lineinfo?.HasLineInfo() ?? false)
                        {
                            result.Line = lineinfo.LineNumber;
                            result.Pos  = lineinfo.LinePosition;
                        }

                        StringBuilder sb    = new StringBuilder();
                        XmlNodeList   texts = node.SelectNodes(".//*[local-name()='text']");
                        if (texts != null)
                        {
                            foreach (XmlNode text in texts)
                            {
                                sb.AppendLine(text.InnerXml);
                            }
                        }
                        result.Message = sb.Length > 0 ? sb.ToString() : node.InnerXml;

                        results.Add(result);
                    }
                }
            }
            catch (XmlException ex)
            {
                results.Add(new Result()
                {
                    SchFile = SchemaSrc,
                    XmlFile = new FileInfo(xmlfile),
                    Status  = ResultStatus.SyntaxError,
                    Message = ex.Message,
                    Line    = ex.LineNumber,
                    Pos     = ex.LinePosition,
                });
            }
            catch (Exception ex)
            {
                results.Add(new Result()
                {
                    SchFile = SchemaSrc,
                    XmlFile = new FileInfo(xmlfile),
                    Status  = ResultStatus.SyntaxError,
                    Message = ex.Message
                });
            }
            results.TrimExcess();
            return(results);
        }