Чтение XML с правильной обработкой ошибок (номера строк, исходный текст и т. Д.) - PullRequest
1 голос
/ 09 февраля 2012

Я хочу прочитать довольно большой XML-файл.Он достаточно мал, чтобы уместиться в памяти, но все же очень большой.При чтении XML он проверяется на соответствие XSD.Это, однако, не предотвращает бизнес-ошибок при использовании прочитанных данных для дальнейшей манипуляции в системе.Когда возникают такие бизнес-ошибки (после проверки XSD), я хочу иметь возможность описать номер строки и номер столбца для начальной и конечной позиции элемента из моего xml.Кроме того, в этом контексте было бы удобно показывать input xml в том виде, как он был прочитан из файла.

Использование xsd.exe Я сгенерировал код всех классов данных, и я прочитал xml, используя

  using (var reader = new StringReader(content))
  {
    var errors = new List<string>();
    var settings = new XmlReaderSettings();
    settings.Schemas.Add("urn:import-schema", "Import.xsd");
    settings.ValidationEventHandler += (o, args) => errors.Add(args.Message);
    settings.ValidationType = ValidationType.Schema;

    using (XmlReader xr = XmlReader.Create(reader, settings))
    {
      var xs = new XmlSerializer(typeof(ImportRoot));
      var result = (ImportRoot) xs.Deserialize(xr);
      if (errors.Any())
        throw new Exception(string.Join("\n\n", errors));
      return result;
    }
  }
}

Однако я не могу найтимета-информация, которую я ищу.Я также проверил класс XDocument.Здесь элементы, кажется, имеют свойство Value, которое является строкой.Но это еще не вся информация, которую я хочу показать.

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Информация о номере строки не читается из StringReader. Если вы используете StreamReader на FileStream, вы сможете получить номер строки.

Эти дополнительные метаданные, которые вы ищете, называются "Информационный набор проверки схемы" .

0 голосов
/ 09 февраля 2012

В вашем ValidationEventHandler посмотрите на свойство args.Exception.Это тип XmlSchemaException , который содержит номер строки и т. Д.

Вы можете сохранить все ошибки, а затем проанализировать их.

var errors = new List<ValidationEventArgs>();
....
settings.ValidationEventHandler += (o, args) => errors.Add(args);

Ошибки проверки бизнеса могут бытьобрабатывается путем реализации их в качестве пользовательских функций xslt.Смотрите эту статью .Если у вас есть функция, которая реализует IXsltContextFunction , вы можете проверить XPathNavigator в методе Invoke для подсказки о том, где вы находитесь в документе.

Получив подсказку, вы можете сравнить ее с каждой строкой в ​​оригинальном документе.

Я сделал что-то подобное пару лет назад (помимо номеров строк), и это сработало очень хорошо.Даже для больших XML-документов.

...