开始使用.NET进行XSDvalidation

这是我第一次使用XSDvalidationXML。

要validation的XML文件:

   SampleVariant   LegendaryMode   AmazingMode   

XSD,位于“Schemas / config.xsd”中,相对于要validation的XML文件:

                  

现在,我只想准确地validation当前出现的XML文件。 一旦我更好地理解了这一点,我将进一步扩展。 对于像XML文件一样简单的东西,我真的需要这么多行吗?

C#中的validation码:

  public void SetURI(string uri) { XElement toValidate = XElement.Load(Path.Combine(PATH_TO_DATA_DIR, uri) + ".xml"); // begin confusion // exception here string schemaURI = toValidate.Attributes("xmlns").First().ToString() + toValidate.Attributes("xsi:noNamespaceSchemaLocation").First().ToString(); XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add(null, schemaURI); XDocument toValidateDoc = new XDocument(toValidate); toValidateDoc.Validate(schemas, null); // end confusion root = toValidate; } 

运行上面的代码会产生以下exception:

 The ':' character, hexadecimal value 0x3A, cannot be included in a name. 

任何照明将不胜感激。

我将使用XmlReader而不是使用XDocument.Validate扩展方法,该XmlReader可以配置为通过XmlReaderSettings处理内联架构。 您可以执行以下代码之类的操作。

 public void VerifyXmlFile(string path) { // configure the xmlreader validation to use inline schema. XmlReaderSettings config = new XmlReaderSettings(); config.ValidationType = ValidationType.Schema; config.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; config.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; config.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; config.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // Get the XmlReader object with the configured settings. XmlReader reader = XmlReader.Create(path, config); // Parsing the file will cause the validation to occur. while (reader.Read()) ; } private void ValidationCallBack(object sender, ValidationEventArgs vea) { if (vea.Severity == XmlSeverityType.Warning) Console.WriteLine( "\tWarning: Matching schema not found. No validation occurred. {0}", vea.Message); else Console.WriteLine("\tValidation error: {0}", vea.Message); } 

上面的代码假定以下using语句。

 using System.Xml; using System.Xml.Schema; 

为了保持这个简单,我没有返回boolean或validation错误集合,您可以轻松地修改它来执行此操作。

注意:我修改了config.xml和config.xsd以使其validation。 这些是我所做的改变。

config.xsd:

  

config.xml文件:

  

以下是一个工作样本:

用法:

 XMLValidator val = new XMLValidator(); if (!val.IsValidXml(File.ReadAllText(@"d:\Test2.xml"), @"D:\Test2.xsd")) MessageBox.Show(val.Errors); 

类:

 public class CXmlValidator { private int nErrors = 0; private string strErrorMsg = string.Empty; public string Errors { get { return strErrorMsg; } } public void ValidationHandler(object sender, ValidationEventArgs args) { nErrors++; strErrorMsg = strErrorMsg + args.Message + "\r\n"; } public bool IsValidXml(string strXml/*xml in text*/, string strXsdLocation /*Xsd location*/) { bool bStatus = false; try { // Declare local objects XmlTextReader xtrReader = new XmlTextReader(strXsdLocation); XmlSchemaCollection xcSchemaCollection = new XmlSchemaCollection(); xcSchemaCollection.Add(null/*add your namespace string*/, xtrReader);//Add multiple schemas if you want. XmlValidatingReader vrValidator = new XmlValidatingReader(strXml, XmlNodeType.Document, null); vrValidator.Schemas.Add(xcSchemaCollection); // Add validation event handler vrValidator.ValidationType = ValidationType.Schema; vrValidator.ValidationEventHandler += new ValidationEventHandler(ValidationHandler); //Actual validation, read conforming the schema. while (vrValidator.Read()) ; vrValidator.Close();//Cleanup //Exception if error. if (nErrors > 0) { throw new Exception(strErrorMsg); } else { bStatus = true; }//Success } catch (Exception error) { bStatus = false; } return bStatus; } } 

上面的代码validation了xml(code3)对xsd(code4)的跟随。

  
My Name 1, My Street Address Far Mali

在validation你的xml / xsd时,我会得到与你不同的错误; 我认为这可以帮助您继续(添加/删除xml元素)从这里:

错误http://sofzh.miximages.com/c%23/www.freeimagehosting.net

您也可以尝试相反的过程; 尝试从你的xml生成模式并与你的实际xsd进行比较 – 看看差异; 最简单的方法是使用VS IDE生成模式。 以下是你如何做到这一点:

从XML创建XSD http://sofzh.miximages.com/c%23/15yhto3.jpg

希望这可以帮助。

– 编辑 –

这是约翰的要求,请使用非弃用的方法查看更新的代码:

 public bool IsValidXmlEx(string strXmlLocation, string strXsdLocation) { bool bStatus = false; try { // Declare local objects XmlReaderSettings rs = new XmlReaderSettings(); rs.ValidationType = ValidationType.Schema; rs.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation | XmlSchemaValidationFlags.ReportValidationWarnings; rs.ValidationEventHandler += new ValidationEventHandler(rs_ValidationEventHandler); rs.Schemas.Add(null, XmlReader.Create(strXsdLocation)); using (XmlReader xmlValidatingReader = XmlReader.Create(strXmlLocation, rs)) { while (xmlValidatingReader.Read()) { } } ////Exception if error. if (nErrors > 0) { throw new Exception(strErrorMsg); } else { bStatus = true; }//Success } catch (Exception error) { bStatus = false; } return bStatus; } void rs_ValidationEventHandler(object sender, ValidationEventArgs e) { if (e.Severity == XmlSeverityType.Warning) strErrorMsg += "WARNING: " + Environment.NewLine; else strErrorMsg += "ERROR: " + Environment.NewLine; nErrors++; strErrorMsg = strErrorMsg + e.Exception.Message + "\r\n"; } 

用法:

 if (!val.IsValidXmlEx(@"d:\Test2.xml", @"D:\Test2.xsd")) MessageBox.Show(val.Errors); else MessageBox.Show("Success"); 

Test2.XML

    SampleVariant   LegendaryMode   AmazingMode   

Test2.XSD(从VS IDE生成)

                  

这保证有效!

提取架构位置的代码看起来很奇怪。 为什么要获取xmlns属性的值并将其与xsi:noNamespaceSchemaLocation属性的值连接? exception是由于您无法在对Attributes的调用中指定前缀; 您需要指定所需的XNamespace。

试试这个(未经测试):

 // Load document XDocument doc = XDocument.Load("file.xml"); // Extract value of xsi:noNamespaceSchemaLocation XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance"; string schemaURI = (string)doc.Root.Attribute(xsi + "noNamespaceSchemaLocation"); // Create schema set XmlSchemaSet schemas = new XmlSchemaSet(); schemas.Add("Schemas", schemaURI); // Validate doc.Validate(schemas, (o, e) => { Console.WriteLine("{0}", e.Message); });