具有内联架构的XDocument。 SchemaInfo为null

时间:2012-08-09 21:21:05

标签: c# xml xsd linq-to-xml

好的,我们走了。我有一组XML文档,我正在加载到我的应用程序中。在我的小测试中,我创建了一个能够验证XML文档指定的模式的阅读器。使用以下代码可以很好地工作。

// 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);

现在我的XML文档被正确加载,并且发生的任何验证错误都由回调处理。

但是,如果我想通过在所述元素上调用GetSchemaInfo()来获取有关元素的模式信息,那么我将获得null。 This question here讨论了使用重载的Validate方法,但这并不适用于这种情况,除非我遗漏了一些东西。

是否可以使用内联架构将架构信息加载到XDoc中,还是应该以另一种方式执行此操作?

1 个答案:

答案 0 :(得分:0)

查看my answer我自己的问题。

代码块之后的第一段对您来说很重要,但基本上SchemaInfo 存在,但直到之后才会添加 >验证回调。

我使用的解决方法基本上是这样的(注意:此代码已经过测试,在直接加载XML并在XDocument.Validate上调用XmlSchemaSet时有效,但前提应与{相同或相似} { {1}}和内联架构:

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强制转换和null检查,但这应该适用于其他节点类型,如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); } } } 的评论时,无论节点是否失败或通过,都会在验证后将架构信息添加到XElement,因此您的要求实际上会更容易,因为您不需要保留失败节点的列表。你应该能够做到这一点:

IXSchemaInfo

以上示例只会访问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,但这只是为了说明我的观点。加载完成并且xml验证后,架构信息应该在那里。