好的,我们走了。我有一组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中,还是应该以另一种方式执行此操作?
答案 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验证后,架构信息应该在那里。