Convalida XSD (XML Schema) con XmlSchemaCollection

È possibile utilizzare la proprietà XmlSchemaCollection per convalidare un documento XML rispetto a schemi del linguaggio XSD (XML Schema Definition). XmlSchemaCollection migliora le prestazioni archiviando schemi nell'insieme in modo che non vengano caricati in memoria ogni volta che avviene la convalida. Se lo schema esiste nell'insieme di schemi, l'attributo schemaLocation verrà utilizzato per cercare lo schema nell'insieme.

Nell'esempio che segue viene illustrato l'elemento principale di un file di dati.

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

Per questo esempio, il valore dell'attributo targetNamespace è urn:bookstore-schema, che è lo stesso spazio dei nomi utilizzato quando si aggiunge lo schema a XmlSchemaCollection.

Nell'esempio di codice che segue viene aggiunto uno schema XML a XmlSchemaCollection.

Dim xsc As New XmlSchemaCollection()
' XML Schema.
xsc.Add("urn:bookstore-schema", schema) 
reader = New XmlTextReader(filename)
vreader = New XmlValidatingReader(reader)
vreader.Schemas.Add(xsc)
[C#]
XmlSchemaCollection xsc = new XmlSchemaCollection();
// XML Schema.
xsc.Add("urn:bookstore-schema", schema);
reader = new XmlTextReader (filename);
vreader = new XmlValidatingReader (reader);
vreader.Schemas.Add(xsc);

L'attributo targetNamespace viene generalmente utilizzato quando si aggiunge la proprietà namespaceURI nel metodo Add per XmlSchemaCollection. È possibile specificare un riferimento null prima di aggiungere lo schema a XmlSchemaCollection. Per gli schemi senza uno spazio dei nomi è necessario utilizzare una stringa vuota (""). XmlSchemaCollection può avere solo uno schema senza uno spazio dei nomi.

Nell'esempio di codice che segue viene aggiunto uno schema XML, HeadCount.xsd, a XmlSchemaCollection e viene eseguita la convalida di HeadCount.xml.

Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.Schema

Namespace ValidationSample
   
   Class Sample
      
      Public Shared Sub Main()
         Dim tr As New XmlTextReader("HeadCount.xml")
         Dim vr As New XmlValidatingReader(tr)
         
         vr.Schemas.Add("xsdHeadCount", "HeadCount.xsd")
         vr.ValidationType = ValidationType.Schema
         AddHandler vr.ValidationEventHandler, AddressOf ValidationHandler
         
         While vr.Read()
         End While
         Console.WriteLine("Validation finished")
      End Sub
      ' Main
      
      
      Public Shared Sub ValidationHandler(sender As Object, args As ValidationEventArgs)
         Console.WriteLine("***Validation error")
         Console.WriteLine("Severity:{0}", args.Severity)
         Console.WriteLine("Message:{0}", args.Message)
      End Sub
      ' ValidationHandler
   End Class
   ' Sample
End Namespace
' ValidationSample
[C#]
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;

namespace ValidationSample
{
   class Sample
   {
      public static void Main()
      {
         XmlTextReader tr = new XmlTextReader("HeadCount.xml");
         XmlValidatingReader vr = new XmlValidatingReader(tr);

         vr.Schemas.Add("xsdHeadCount", "HeadCount.xsd");
         vr.ValidationType = ValidationType.Schema;
         vr.ValidationEventHandler += new ValidationEventHandler (ValidationHandler);

         while(vr.Read());
         Console.WriteLine("Validation finished");
      }

      public static void ValidationHandler(object sender, ValidationEventArgs args)
      {
         Console.WriteLine("***Validation error");
         Console.WriteLine("\tSeverity:{0}", args.Severity);
         Console.WriteLine("\tMessage  :{0}", args.Message);
      }
   }
}

Di seguito viene indicato il contenuto del file di input, HeadCount.xml, da convalidare.

<!--Load HeadCount.xsd in SchemaCollection for Validation-->
<hc:HeadCount xmlns:hc='xsdHeadCount'>
   <Name>Waldo Pepper</Name>
   <Name>Red Pepper</Name>
</hc:HeadCount>

Di seguito viene indicato il contenuto del file dello schema XML, HeadCount.xsd, rispetto al quale eseguire la convalida.

<xs:schema xmlns="xsdHeadCount" targetNamespace="xsdHeadCount" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:element name='HeadCount' type="HEADCOUNT"/>
   <xs:complexType name="HEADCOUNT">
      <xs:sequence>
         <xs:element name='Name' type='xs:string' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='division' type='xs:int' use='optional' default='8'/>
   </xs:complexType>
</xs:schema>

Nell'esempio di codice che segue viene creato un XmlValidatingReader che accetta un XmlTextReader. Il file di input, sample4.xml, viene convalidato rispetto allo schema XML, sample4.xsd.

Dim tr As New XmlTextReader("sample4.xml")
Dim vr As New XmlValidatingReader(tr)
vr.ValidationType = ValidationType.Schema
vr.Schemas.Add("datatypesTest", "sample4.xsd")
AddHandler vr.ValidationEventHandler, AddressOf ValidationCallBack
While vr.Read()
   Console.WriteLine("NodeType: {0} NodeName: {1}", vr.NodeType, vr.Name)
End While
[C#]
XmlTextReader tr = new XmlTextReader("sample4.xml");
XmlValidatingReader vr = new XmlValidatingReader(tr);
vr.ValidationType = ValidationType.Schema;
        vr.Schemas.Add("datatypesTest", "sample4.xsd");
vr.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
while(vr.Read()) {
    Console.WriteLine("NodeType: {0} NodeName: {1}", vr.NodeType, vr.Name);
    }

Di seguito viene indicato il contenuto del file di input, sample4.xml, da convalidare.

<datatypes xmlns="datatypesTest">
    <number>
        <number_1>123</number_1>
    </number>
</datatypes>

Di seguito viene indicato il contenuto del file dello schema XML, sample4.xsd, rispetto al quale eseguire la convalida.

<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="datatypesTest" 
    targetNamespace="datatypesTest"
    elementFormDefault="qualified">

<xs:element name = "datatypes">
  <xs:complexType>
    <xs:all>
        <xs:element name="number">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="number_1" type="xs:decimal" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:all>
  </xs:complexType>
</xs:element>
</xs:schema>

Vedere anche

XmlSchemaCollection come cache degli schemi | Convalida del linguaggio XML con schemi | Classe XmlParserContext | Evento XmlValidatingReader.ValidationEventHandler | Proprietà XmlValidatingReader.Schemas