2009-04-15 118 views
127

我有一個指定模式位置的XML文件像這樣:驗證XML對XSD引用在C#中

xsi:schemaLocation="someurl ..\localSchemaPath.xsd" 

我想在C#中驗證。 Visual Studio,當我打開文件時,根據模式驗證它並完美地列出錯誤。但不知何故,我似乎無法在C#中自動驗證它沒有指定的模式來驗證,像這樣:

XmlDocument asset = new XmlDocument(); 

XmlTextReader schemaReader = new XmlTextReader("relativeSchemaPath"); 
XmlSchema schema = XmlSchema.Read(schemaReader, SchemaValidationHandler); 

asset.Schemas.Add(schema); 

asset.Load(filename); 
asset.Validate(DocumentValidationHandler); 

我不應該能夠與自動的XML文件中指定的架構驗證?我錯過了什麼?

+1

請參閱MSDN的示例:http://msdn.microsoft.com/en -us/library/system.xml.schema.validationeventargs.severity.aspx – 2012-01-17 13:19:38

回答

143

您需要創建一個XmlReaderSettings實例,並在創建XmlReader時將其傳遞給您的XmlReader。然後,您可以在設置中訂閱ValidationEventHandler以接收驗證錯誤。你的代碼最終會這樣看:

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

public class ValidXSD 
{ 
    public static void Main() 
    { 

     // 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.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); 

     // Create the XmlReader object. 
     XmlReader reader = XmlReader.Create("inlineSchema.xml", settings); 

     // Parse the file. 
     while (reader.Read()) ; 

    } 
    // Display any warnings or errors. 
    private static void ValidationCallBack(object sender, ValidationEventArgs args) 
    { 
     if (args.Severity == XmlSeverityType.Warning) 
      Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message); 
     else 
      Console.WriteLine("\tValidation error: " + args.Message); 

    } 
} 
+3

+1雖然應該更新爲使用`using`子句以獲得完整性:) – IAbstract 2011-12-10 02:26:39

+41

如果您希望與XSD文件進行比較,請添加以下內容g行到上面的代碼:settings.Schemas.Add(「YourDomainHere」,「yourXSDFile.xsd」); – 2012-04-14 19:05:12

+5

要獲得錯誤的行號和位置#,只需使用:args.Exception.LineNumber ... in ValidationCallBack – user610064 2012-12-21 14:29:02

13

我不得不做這樣的VB中自動驗證的,這是我是如何做到的(轉換爲C#):

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.ValidationType = ValidationType.Schema; 
settings.ValidationFlags = settings.ValidationFlags | 
          Schema.XmlSchemaValidationFlags.ProcessSchemaLocation; 
XmlReader XMLvalidator = XmlReader.Create(reader, settings); 

然後我訂閱了settings.ValidationEventHandler事件讀取文件。

15

以下example驗證XML文件並生成相應的錯誤或警告。

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

public class Sample 
{ 

    public static void Main() 
    { 
     //Load the XmlSchemaSet. 
     XmlSchemaSet schemaSet = new XmlSchemaSet(); 
     schemaSet.Add("urn:bookstore-schema", "books.xsd"); 

     //Validate the file using the schema stored in the schema set. 
     //Any elements belonging to the namespace "urn:cd-schema" generate 
     //a warning because there is no schema matching that namespace. 
     Validate("store.xml", schemaSet); 
     Console.ReadLine(); 
    } 

    private static void Validate(String filename, XmlSchemaSet schemaSet) 
    { 
     Console.WriteLine(); 
     Console.WriteLine("\r\nValidating XML file {0}...", filename.ToString()); 

     XmlSchema compiledSchema = null; 

     foreach (XmlSchema schema in schemaSet.Schemas()) 
     { 
      compiledSchema = schema; 
     } 

     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.Schemas.Add(compiledSchema); 
     settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); 
     settings.ValidationType = ValidationType.Schema; 

     //Create the schema validating reader. 
     XmlReader vreader = XmlReader.Create(filename, settings); 

     while (vreader.Read()) { } 

     //Close the reader. 
     vreader.Close(); 
    } 

    //Display any warnings or errors. 
    private static void ValidationCallBack(object sender, ValidationEventArgs args) 
    { 
     if (args.Severity == XmlSeverityType.Warning) 
      Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message); 
     else 
      Console.WriteLine("\tValidation error: " + args.Message); 

    } 
} 

上述示例使用以下輸入文件。

<?xml version='1.0'?> 
<bookstore xmlns="urn:bookstore-schema" xmlns:cd="urn:cd-schema"> 
    <book genre="novel"> 
    <title>The Confidence Man</title> 
    <price>11.99</price> 
    </book> 
    <cd:cd> 
    <title>Americana</title> 
    <cd:artist>Offspring</cd:artist> 
    <price>16.95</price> 
    </cd:cd> 
</bookstore> 

books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="urn:bookstore-schema" 
    elementFormDefault="qualified" 
    targetNamespace="urn:bookstore-schema"> 

<xsd:element name="bookstore" type="bookstoreType"/> 

<xsd:complexType name="bookstoreType"> 
    <xsd:sequence maxOccurs="unbounded"> 
    <xsd:element name="book" type="bookType"/> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="bookType"> 
    <xsd:sequence> 
    <xsd:element name="title" type="xsd:string"/> 
    <xsd:element name="author" type="authorName"/> 
    <xsd:element name="price" type="xsd:decimal"/> 
    </xsd:sequence> 
    <xsd:attribute name="genre" type="xsd:string"/> 
</xsd:complexType> 

<xsd:complexType name="authorName"> 
    <xsd:sequence> 
    <xsd:element name="first-name" type="xsd:string"/> 
    <xsd:element name="last-name" type="xsd:string"/> 
    </xsd:sequence> 
</xsd:complexType> 

</xsd:schema> 
78

更簡單的方法,如果你使用的是.NET 3.5,就是用XDocumentXmlSchemaSet驗證。

XmlSchemaSet schemas = new XmlSchemaSet(); 
schemas.Add(schemaNamespace, schemaFileName); 

XDocument doc = XDocument.Load(filename); 
string msg = ""; 
doc.Validate(schemas, (o, e) => { 
    msg += e.Message + Environment.NewLine; 
}); 
Console.WriteLine(msg == "" ? "Document is valid" : "Document invalid: " + msg); 

查看MSDN documentation尋求更多幫助。

10

我個人贊成驗證沒有回調:

public bool ValidateSchema(string xmlPath, string xsdPath) 
{ 
    XmlDocument xml = new XmlDocument(); 
    xml.Load(xmlPath); 

    xml.Schemas.Add(null, xsdPath); 

    try 
    { 
     xml.Validate(null); 
    } 
    catch (XmlSchemaValidationException) 
    { 
     return false; 
    } 
    return true; 
} 

(見Timiz0r在Synchronous XML Schema Validation? .NET 3.5後)