在C#中单次读取和validationXML与引用的XSD

我正在尝试从XML文件中读取数据,并根据它建议的XSD将其validation到单个数据结构(例如XmlDocument)中。 我有一个解决方案,但它需要2次通过文件,我想知道是否有单程解决方案。

MyBooks.xml:

 Book A Book B  

Books.xsd:

           

假设MyBooks.xml和Books.xsd位于同一目录中。

validation:

 //Given a filename pointing to the XML file var settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; settings.CloseInput = true; settings.ValidationEventHandler += new ValidationEventHandler(ValidationCB); //eg: //private static void ValidationCB(object sender, ValidationEventArgs args) //{ throw new ApplicationException(args.Message); } using(var reader = XmlReader.Create(filename, settings)) { while(reader.Read()) ; } 

阅读XmlDocument:

 XmlDocument x = new XmlDocument(); x.Load(filename); 

当然,我可以收集节点,因为XmlReader正在进行读取,但如果可能的话,我宁愿不必自己做。 有什么建议吗?

提前致谢

你的解决方案非常接近; 你需要做的是使用validation阅读器来加载你的XML; 这样,validation就可以通过一次加载来完成; validation错误不会阻止您加载文档。

这些是我通常与ValidateXml辅助函数一起使用的高级步骤; 一切都从编译的XmlSchemaSet开始:

 public bool ValidateXml(XmlSchemaSet xset) 

我设置了读卡器设置(你也做过):

 XmlReaderSettings settings = new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = xset, ConformanceLevel = ConformanceLevel.Document }; settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; // Use your helper class that collects validation events. XsdUtils.Utils.SmartValidationHandler svh = new XsdUtils.Utils.SmartValidationHandler(Paschi.Xml.DefaultResolver.Instance); settings.ValidationEventHandler += svh.ValidationCallbackOne; 

然后我找了一个读者:

 XmlReader xvr = XmlReader.Create(filename, settings); 

然后我读了文件,它带来了validation:

 XmlDocument xdoc = new XmlDocument(); xdoc.Load(xvr); 

你的validation处理程序现在有结果; 我还要做的一件事是确保加载的文档元素实际上在xml架构集中具有相应的全局元素定义。

 XmlQualifiedName qn = XmlQualifiedName.Empty; if (xdoc.DocumentElement != null) { if (string.IsNullOrEmpty(xdoc.DocumentElement.NamespaceURI)) { qn = new XmlQualifiedName(xdoc.DocumentElement.LocalName); } else { qn = new XmlQualifiedName(xdoc.DocumentElement.LocalName, xdoc.DocumentElement.NamespaceURI); } } return !(svh.HasError || qn.IsEmpty || (!xset.GlobalElements.Contains(qn)));