Отъезд my answer к моему собственному вопросу.
Первый абзац после блока кода является то, что важно для вас, но в основном, SchemaInfo
будет быть там, но это не добавляется до после проверка обратного вызова.
Обходной я использовал в основном это (Примечание: этот код был протестирован и работает при загрузке XML непосредственно и вызова XDocument.Validate
на XmlSchemaSet
, но помещение должно быть таким же или с XmlReader
и встроенными схемами):
List<XElement> errorElements = new List<XElement>();
serializedObject.Validate((sender, args) =>
{
var exception = (args.Exception as XmlSchemaValidationException);
if (exception != null)
{
var element = (exception.SourceObject as XElement);
if (element != null)
errorElements.Add(element);
}
});
foreach element in errorElements
{
var si = element.GetSchemaInfo;
// do something with SchemaInfo
}
Я только пытался захватить SchemaInfo
для элементов, следовательно, as
произнесения и нулевой чек, но это должно работать для других типов узлов, как Attributes
(не тестировался, хотя, так что я мог бы быть неправильно).
Если вы хотите использовать определенный метод обратного вызова вместо анонимного делегата, то ваш errorElements
должен быть полем уровня класса, и вы можете делать то, что вам нужно сделать после завершения проверки (опять же, я добавит в непроверенный тег).
public class SomeClass
{
List<XElement> errorElements = new List<XElement>();
public void Load()
{
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("xml/note.xml", settings);
// Load the XDocument from the reader
XDocument loadedDoc = XDocument.Load(reader);
// do something with errorElements
}
public void ValidationCallBack(object sender, ValidationEventArgs e)
{
var exception = (args.Exception as XmlSchemaValidationException);
if (exception != null)
{
var element = (exception.SourceObject as XElement);
if (element != null)
errorElements.Add(element);
}
}
}
В ответ на ваш комментарий о желании в IXSchemaInfo
для всех узлов, информация схемы добавляется к XElement после проверки, независимо от того, удался или прошел узел, поэтому ваше требование фактически будет легче, так как вам не нужно сохранять список неудачных узлов. Вы должны быть в состоянии сделать это:
public void Load()
{
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("xml/note.xml", settings);
// Load the XDocument from the reader
XDocument loadedDoc = XDocument.Load(reader);
foreach (var node in loadedDoc.Descendants())
{
var si = node.GetSchemaInfo();
}
}
Приведенный выше пример будет иметь доступ только к XElement
с в вашем XDocument
, но это просто проиллюстрировать мою точку зрения. Как только загрузка будет завершена и xml будет проверяться, должна быть информация о схеме.
Спасибо за ответ, я не могу проверить, как я далеко от своей машины разработки, но сделаю это как можно скорее. Однако, глядя на код, кажется, что он будет работать только для узлов с ошибками. То, к чему я стремился, было загрузить всю информацию о схеме, желательно для документов, которые проходят проверку. Мы собираемся использовать эту информацию для некоторой динамической сериализации позже. – djstamp
Этот точный код будет работать только с узлами с ошибками, так как вы только собираете 'XElement' в обратном вызове проверки, но' SchemaInfo' должен присутствовать * после того, как * проверка завершена для всего, поэтому вы можете попробовать в этот момент (я добавлю еще один пример). – psubsee2003
К сожалению, использование GetSchemaInfo для элементов, загруженных таким образом, возвращает null. Единственный способ, которым я смог получить информацию о схеме, загруженную для всего документа, - это использовать перегруженный метод проверки, упомянутый в вопросе, на который я ссылался первоначально. Похоже, что если я хочу получить доступ ко всей информации о схеме, мне нужно будет загрузить и проверить мои документы таким образом. Не невозможно, просто не идеально. Спасибо за помощь. Любые другие идеи приветствуются! – djstamp