Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette rubrique explique comment utiliser la XmlSchemaInference classe pour déduire un schéma XSD (XML Schema Definition Language) à partir de la structure d’un document XML.
Processus d’inférence de schéma
La XmlSchemaInference classe de l’espace System.Xml.Schema de noms est utilisée pour générer un ou plusieurs schémas XSD (XML Schema Definition Language) à partir de la structure d’un document XML. Les schémas générés peuvent être utilisés pour valider le document XML d’origine.
En tant que document XML est traité par la XmlSchemaInference classe, la XmlSchemaInference classe fait des hypothèses sur les composants de schéma qui décrivent les éléments et les attributs dans le document XML. La XmlSchemaInference classe déduit également les composants de schéma d’une manière contrainte en déduit le type le plus restrictif pour un élément ou un attribut particulier. À mesure que des informations supplémentaires sur le document XML sont collectées, ces contraintes sont assouplies en inférence des types moins restrictifs. Le type le moins restrictif qui peut être déduit est xs:string.
Prenons, par exemple, l’élément suivant d’un document XML.
<parent attribute1="6">
<child>One</child>
<child>Two</child>
</parent>
<parent attribute1="A" />
Dans l’exemple ci-dessus, lorsque l’attribut attribute1 est rencontré avec une valeur de 6 par le processus XmlSchemaInference, il est supposé être de type xs:unsignedByte. Lorsque le deuxième parent élément est rencontré par le XmlSchemaInference processus, la contrainte est relâchée en modifiant le type en xs:string, car la valeur de l’attribut attribute1 est maintenant A. De même, l’attribut minOccurs de tous les child éléments déduits dans le schéma est relâché à minOccurs="0" car le deuxième élément parent n’a pas d’éléments enfants.
Inférence de schémas à partir de documents XML
La XmlSchemaInference classe utilise deux méthodes surchargées InferSchema pour déduire un schéma à partir d’un document XML.
La première XmlSchemaInference.InferSchema méthode est utilisée pour créer un schéma basé sur un document XML. La deuxième XmlSchemaInference.InferSchema méthode est utilisée pour déduire un schéma qui décrit plusieurs documents XML. Par exemple, vous pouvez alimenter plusieurs documents XML vers la méthode une à la fois pour produire un schéma qui décrit l’ensemble des documents XML.
La première XmlSchemaInference.InferSchema méthode déduit un schéma à partir d’un document XML contenu dans un XmlReader objet et retourne un XmlSchemaSet objet contenant le schéma déduit. La deuxième XmlSchemaInference.InferSchema méthode recherche un XmlSchemaSet objet pour un schéma avec le même espace de noms cible que le document XML contenu dans l’objet XmlReader , affine le schéma existant et retourne un XmlSchemaSet objet contenant le schéma déduit.
Les modifications apportées au schéma affiné sont basées sur une nouvelle structure trouvée dans le document XML. Par exemple, comme un document XML est parcouru, les hypothèses sont faites sur les types de données trouvés et le schéma est créé en fonction de ces hypothèses. Toutefois, si des données sont rencontrées sur une deuxième passe d’inférence qui diffère de l’hypothèse d’origine, le schéma est affiné. L’exemple suivant illustre le processus d’affinement.
XmlReader reader = XmlReader.Create("item1.xml");
XmlReader reader1 = XmlReader.Create("item2.xml");
XmlSchemaSet schemaSet = new XmlSchemaSet();
XmlSchemaInference inference = new XmlSchemaInference();
schemaSet = inference.InferSchema(reader);
// Display the inferred schema.
Console.WriteLine("Original schema:\n");
foreach (XmlSchema schema in schemaSet.Schemas("http://www.contoso.com/items"))
{
schema.Write(Console.Out);
}
// Use the additional data in item2.xml to refine the original schema.
schemaSet = inference.InferSchema(reader1, schemaSet);
// Display the refined schema.
Console.WriteLine("\n\nRefined schema:\n");
foreach (XmlSchema schema in schemaSet.Schemas("http://www.contoso.com/items"))
{
schema.Write(Console.Out);
}
Dim reader As XmlReader = XmlReader.Create("item1.xml")
Dim reader1 As XmlReader = XmlReader.Create("item2.xml")
Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
Dim inference As XmlSchemaInference = New XmlSchemaInference()
schemaSet = inference.InferSchema(reader)
' Display the inferred schema.
Console.WriteLine("Original schema:\n")
For Each schema As XmlSchema In schemaSet.Schemas("http://www.contoso.com/items")
schema.Write(Console.Out)
Next
' Use the additional data in item2.xml to refine the original schema.
schemaSet = inference.InferSchema(reader1, schemaSet)
' Display the refined schema.
Console.WriteLine("\n\nRefined schema:\n")
For Each schema As XmlSchema In schemaSet.Schemas("http://www.contoso.com/items")
schema.Write(Console.Out)
Next
L’exemple prend le fichier suivant, item1.xmlcomme première entrée.
<?xml version="1.0" encoding="utf-8"?>
<item xmlns="http://www.contoso.com/items" productID="123456789">
<name>Hammer</name>
<price>9.95</price>
<supplierID>1929</supplierID>
</item>
L’exemple prend ensuite le item2.xml fichier comme deuxième entrée :
<?xml version="1.0" encoding="utf-8"?>
<item xmlns="http://www.contoso.com/items" productID="A53-246">
<name>Paint</name>
<price>12.50</price>
</item>
Lorsque l’attribut productID est rencontré dans le premier document XML, la valeur 123456789 est supposée être un type xs:unsignedInt. Toutefois, lorsque le deuxième document XML est lu et que la valeur de A53-246 est trouvée, le type xs:unsignedInt ne peut plus être supposé. Le schéma est affiné et le type de productID est changé en xs:string. En outre, l’attribut minOccurs de l’élément supplierID est défini à 0, car le deuxième document XML ne contient aucun élément supplierID.
Voici le schéma déduit du premier document XML.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/items" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="price" type="xs:decimal" />
<xs:element name="supplierID" type="xs:unsignedShort" />
</xs:sequence>
<xs:attribute name="productID" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
Voici le schéma déduit du premier document XML, affiné par le deuxième document XML.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/items" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="price" type="xs:decimal" />
<xs:element minOccurs="0" name="supplierID" type="xs:unsignedShort" />
</xs:sequence>
<xs:attribute name="productID" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
Schémas en ligne
Si un schéma XSD (XML Schema Definition Language en ligne) est rencontré pendant le processus XmlSchemaInference, une exception XmlSchemaInferenceException est levée. Par exemple, le schéma intégré suivant génère un XmlSchemaInferenceException.
<root xmlns:ex="http://www.contoso.com" xmlns="http://www.tempuri.org">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.contoso.com">
<xs:element name="Contoso" type="xs:normalizedString" />
</xs:schema>
<ex:Contoso>Test</ex:Contoso>
</root>
Schémas qui ne peuvent pas être affinés
Il existe des constructions de schéma XML W3C que le langage de définition de schéma XML (XSD) XmlSchemaInference ne peut pas gérer lorsqu’un type est affiné, ce qui peut provoquer la levée d’une exception. Tel qu'un type complexe dont le composant principal est différent d'une séquence. Dans le modèle objet de schéma (SOM), cela correspond à un XmlSchemaComplexType dont la propriété Particle n'est pas une instance de XmlSchemaSequence.