开始使用.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); });