2014-01-15 4 views
2

я исследовал различные типы валидации XML с помощью XSD XmlDocument.Validate(ValidationEventHandler), XDocument.Validate(schemas, ValidationEventHandler) и XmlReader со схемой, переданной ему, что посылает результаты в ValidationEventHandler обратного вызова.Как улучшить проверки XSD многословие

Однако обратный вызов практически обеспечивает только серьезность и строку ошибки. Я получаю такие сообщения, как:

The 'name' attribute is invalid - The value '' is invalid according to 
its datatype 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd' - The 
Pattern constraint failed. 

Теперь это далеко не идеальные сообщения об ошибках. Аргументы обратного вызова не обеспечивают, какой родитель вызвал это, ни то, что строка XML это или что-то практическое.

В моем сценарии не все имена имеют указанный тип выше, некоторые из них просто могут быть пустыми строками (поскольку они являются необязательными).

Теперь, имея, вероятно, сотни узлов xml с именами, вызывает раздражение, чтобы найти проблему выше, так как нет никакой информации контекста о местоположении, даже не того, что представляет собой узел xml.

Как можно расширить расшифровку такой проверки? Notepad ++, например, использует плагин XML Tools, которая выводит сообщение выше, как:

Проверка текущего файла с использованием XML-схемы:

ERROR: Element 'LightSource', attribute 'name': [facet 'minLength'] The value '' has a length of '0'; this underruns the allowed minimum length of '1'. 
ERROR: Element 'LightSource', attribute 'name': [facet 'pattern'] The value '' is not accepted by the pattern '.*\S'. 
ERROR: Element 'LightSource', attribute 'name': '' is not a valid value of the atomic type 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd'. 

Это более многословным и указывает появляется по крайней мере, некоторые контекстную информацию, как вопрос на элементе LightSource и что именно wnt неправильно с базовым типом.

Существуют ли другие возможности, позволяющие проверить правильность C# XSD с расширенной информацией о контексте?

Подтверждения были выполнены в представлении XML в памяти в терминах XDocument и XmlDocument, а также читать из файла с XmlReader. Очевидно, номера строк и т. Д. Имели бы смысл только в контексте, где уже был написан xml-файл, но была бы удобна другая информация, такая как родительский элемент и т. Д., Чтобы я мог, по крайней мере, выводить контекст xml, на который нужно смотреть.


Для полноты некоторых кода:

var schemas = new XmlSchemaSet(); 
    schemas.Add("", xsdPath); 
    var doc = XDocument.Load(xmlFile); 
    doc.Validate(schemas,ValidationEventHandler); 

    public void ValidationEventHandler(object sender, ValidationEventArgs e) 
    { 
     // Not much in e 
     switch (e.Severity) 
     { 
      case XmlSeverityType.Error: 
       Console.WriteLine("Error: {0}", e.Message); 
       break; 
      case XmlSeverityType.Warning: 
       Console.WriteLine("Warning {0}", e.Message); 
       break; 
     } 

    } 

Еще одна попытка, которая была многообещающей была http://msdn.microsoft.com/en-us/library/as3tta56%28v=vs.110%29.aspx, но не увеличивал никакого многословия вообще.


Некоторые пояснения к остальной части.

У меня есть некоторый тип, который образует ограничение:

<xs:simpleType name="TNonEmptyStringNoWhitespacesAtBeginn"> 
    <xs:restriction base="xs:string"> 
     <xs:pattern value="\S.*" /> 
     <xs:minLength value="1"/> 
    </xs:restriction> 
</xs:simpleType> 

<xs:simpleType name="TNonEmptyStringNoWhitespacesAtBeginningAndEnd"> 
    <xs:restriction base="TNonEmptyStringNoWhitespacesAtBeginn"> 
     <xs:pattern value=".*\S" /> 
     <xs:minLength value="1"/> 
    </xs:restriction> 
</xs:simpleType> 

TNonEmptyStringNoWhitespacesAtBeginn Игнорируйте это помощник, чтобы AND-Инг ограничения. Поэтому, когда у меня есть атрибут name с типом выше, который является просто пустой строкой, я получаю очень разный объем информации из проверки XSD C# и из того, что делает плагин Notepads ++ XML Tools. Вот различные сообщения для полноты картины еще раз:

C#

The 'name' attribute is invalid - The value '' is invalid according to 
its datatype 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd' - The 
Pattern constraint failed. 

Notepad ++

ERROR: Element 'LightSource', attribute 'name': [facet 'minLength'] The value '' has a length of '0'; this underruns the allowed minimum length of '1'. 
ERROR: Element 'LightSource', attribute 'name': [facet 'pattern'] The value '' is not accepted by the pattern '.*\S'. 
ERROR: Element 'LightSource', attribute 'name': '' is not a valid value of the atomic type 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd'. 

С информацией, предоставленной по содержанию исключения я могу извлечь XML-элемент и отобразить его но заявив, что ограничение для TNonEmptyStringNoWhitespacesAtBeginningAndEnd оказалось неудачным, гораздо менее выразительно, чем сказать мне, какая деталь в деталях потерпела неудачу. Я знаю, что получаю подсказку, что ограничение шаблона не удалось, но любой, кто получает такое сообщение, должен найти тип и проверить его ограничения, чтобы получить информацию об ограничении. Проверяя данные из исключения, похоже, что это уровень детализации.

Плагин XML Tools, возможно, имеет возможность раскрывать каждый элемент проверки и с гораздо большей детализацией. Это ничего не вывело из XSD, скорее похоже на информацию, полученную на этапе обработки каждого ограничения.

Я надеялся, что это способ увеличить многословие валидатора, чтобы получить дополнительную информацию.

ответ

4

Re: Нумерация строк ... Для XDocument, если включить информацию линии захвата

тогда обработчик проверки будет извлечь что-то подобное в вашей публикуемую ValidationEventHandlercode (IXmlLineInfo):

IXmlLineInfo node = sender as IXmlLineInfo; 
if (node != null && node.HasLineInfo()) ... 

Это должно охватывать информацию, которую вы хотели ...

для традиционного DOM, у вас есть возможность осмотреть Exception (дает вам LineNumber и LinePosition), теоретически, по крайней мере, через свойство Exception вы также можете получить SchemaObjectProperty. Во всем моем коде я использую XDocument, и это отлично работает.

Это должно заставить вас начать, по крайней мере, обеспечить лучшее местоположение в терминах линии/положения (которое будет работать, даже если оно находится в памяти).

(Обновления на основе модифицированного вопроса)

C# не даст вам то, что вы видите с плагином вы имеете в виду ... для меня это выбор реализации. Границы XSD работают совместно; поэтому любой, кто терпит неудачу, считает все недействительным.

Встроенный в XSD-валидатор .NET является универсальным, без слишком большого количества проверок (единственное, что нужно сделать или не уникальное атрибутирование частиц). Чтобы сбалансировать производительность, вышесказанное происходит для проверки простого типа.

Плагин, кажется, предназначен для интерактивности ... это, кажется, хочет сказать, насколько это возможно, независимо от того, что он принимает ...

+0

Это highligly удовлетворение. Спасибо. Я проверил строку pos и числа на моем первом запуске, но я сделал это на недавно созданном объекте memory-dom и, очевидно, не было строки информации. IXmlLineInfo действительно помогает мне. – Samuel

+0

То, что я только что понял, по-прежнему остается открытым, - это вопрос, могу ли я получить более глубокое объяснение нарушения ограничений, с помощью которого часть ограничения не удалась. – Samuel

+0

@ Самуэль, этот последний бит ... не находится в вопросе, и ваш комментарий не ясен, как в чем вы это подразумеваете.Если в результате «какой части ограничения произошел сбой» вы имели в виду компонент XSD, который вызвал исключение ... тогда вы можете попытаться проверить объект SchemaObject в исключении. Тем не менее, я не знаю о каком-либо XSD-процессоре, который бы указывал в терминах номера/позиции строки конкретный фасет (перечисление, длина, maxLength и т. Д.), Которые не удались ... сообщение в исключении обычно помогает указать, что не удалось. .. –

Смежные вопросы