Delen via


Schema's uit XML-documenten uitstellen

In dit onderwerp wordt beschreven hoe u de XmlSchemaInference klasse gebruikt om een XSD-schema (XML Schema Definition Language) af te leiden van de structuur van een XML-document.

Het schemadeductieproces

De XmlSchemaInference klasse van de System.Xml.Schema naamruimte wordt gebruikt om een of meer XSD-schema's (XML Schema Definition Language) te genereren op basis van de structuur van een XML-document. De gegenereerde schema's kunnen worden gebruikt om het oorspronkelijke XML-document te valideren.

Omdat een XML-document door de XmlSchemaInference klasse wordt verwerkt, maakt de XmlSchemaInference klasse veronderstellingen over de schemaonderdelen die de elementen en kenmerken in het XML-document beschrijven. De XmlSchemaInference klasse afgeleid ook schemaonderdelen op een beperkte manier door het meest beperkende type voor een bepaald element of kenmerk uit te stellen. Naarmate er meer informatie over het XML-document wordt verzameld, worden deze beperkingen losgemaakt door minder beperkende typen uit te stellen. Het minst beperkende type dat kan worden afgeleid, is xs:string.

Neem bijvoorbeeld het volgende deel van een XML-document.

<parent attribute1="6">  
    <child>One</child>  
    <child>Two</child>  
</parent>  
<parent attribute1="A" />

Wanneer in het bovenstaande voorbeeld het attribute1 kenmerk wordt aangetroffen met een waarde van 6 het XmlSchemaInference proces, wordt ervan uitgegaan dat het van het type xs:unsignedByteis. Wanneer het tweede parent element door het XmlSchemaInference proces wordt aangetroffen, wordt de beperking losgemaakt door het type te xs:string wijzigen omdat de waarde van het attribute1 kenmerk nu Ais. Op dezelfde manier wordt het minOccurs kenmerk voor alle child elementen die in het schema zijn afgeleid, losgemaakt minOccurs="0" omdat het tweede bovenliggende element geen onderliggende elementen bevat.

Schema's uit XML-documenten uitstellen

De XmlSchemaInference klasse maakt gebruik van twee overbelaste InferSchema methoden om een schema uit een XML-document af te leiden.

De eerste XmlSchemaInference.InferSchema methode wordt gebruikt om een schema te maken op basis van een XML-document. De tweede XmlSchemaInference.InferSchema methode wordt gebruikt om een schema af te leiden dat meerdere XML-documenten beschrijft. U kunt bijvoorbeeld meerdere XML-documenten één voor één aan de XmlSchemaInference.InferSchema methode toevoegen om een schema te maken waarin de volledige set XML-documenten wordt beschreven.

Met de eerste XmlSchemaInference.InferSchema methode wordt een schema afgeleid van een XML-document in een XmlReader object en wordt een XmlSchemaSet object geretourneerd dat het uitgestelde schema bevat. De tweede XmlSchemaInference.InferSchema methode doorzoekt een XmlSchemaSet object naar een schema met dezelfde doelnaamruimte als het XML-document in het XmlReader object, verfijnt het bestaande schema en retourneert een XmlSchemaSet object dat het uitgestelde schema bevat.

De wijzigingen in het verfijnde schema zijn gebaseerd op nieuwe structuur die in het XML-document wordt gevonden. Als een XML-document bijvoorbeeld wordt doorkruist, worden veronderstellingen gemaakt over de gevonden gegevenstypen en wordt het schema gemaakt op basis van deze veronderstellingen. Als er echter gegevens worden aangetroffen op een tweede deductiepass die verschilt van de oorspronkelijke aanname, wordt het schema verfijnd. In het volgende voorbeeld ziet u het verfijningsproces.

XmlReader^ reader = XmlReader::Create("item1.xml");
XmlReader^ reader1 = XmlReader::Create("item2.xml");
XmlSchemaSet^ schemaSet = gcnew XmlSchemaSet();
XmlSchemaInference^ inference = gcnew XmlSchemaInference();
schemaSet = inference->InferSchema(reader);

// Display the inferred schema.
Console::WriteLine("Original schema:\n");
for each (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");
for each (XmlSchema^ schema in schemaSet->Schemas("http://www.contoso.com/items"))
{
    schema->Write(Console::Out);
}
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

In het voorbeeld wordt het volgende bestand gebruikt, item1.xmlals eerste invoer.

<?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>

In het voorbeeld wordt het item2.xml bestand vervolgens als tweede invoer gebruikt:

<?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>

Wanneer het productID kenmerk wordt aangetroffen in het eerste XML-document, wordt ervan uitgegaan dat het 123456789 een xs:unsignedInt type is. Wanneer het tweede XML-document echter wordt gelezen en de waarde ervan A53-246 wordt gevonden, kan het xs:unsignedInt type niet meer worden aangenomen. Het schema wordt verfijnd en het type productID wordt gewijzigd in xs:string. Daarnaast is het minOccurs kenmerk voor het supplierID element ingesteld op 0, omdat het tweede XML-document geen supplierID element bevat.

Hier volgt het schema dat is afgeleid van het eerste XML-document.

<?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>

Hier volgt het schema dat is afgeleid van het eerste XML-document, verfijnd door het tweede XML-document.

<?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>

Inlineschema's

Als er een XSD-schema (Inline XML Schema Definition Language) wordt aangetroffen tijdens het XmlSchemaInference proces, wordt er een XmlSchemaInferenceException gegenereerd. Het volgende inlineschema genereert bijvoorbeeld een 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>  

Schema's die niet kunnen worden verfijnd

Er zijn W3C XML-schemaconstructies die het XSD-schemaproces XmlSchemaInference (XML Schema Definition Language) niet kan verwerken als het opgegeven type voor het verfijnen en veroorzaken van een uitzondering wordt gegenereerd. Zoals een complex type waarvan compositor op het hoogste niveau iets anders is dan een reeks. In het Schema Object Model (SOM) komt dit overeen met een XmlSchemaComplexType eigenschap waarvan Particle de eigenschap geen exemplaar is.XmlSchemaSequence

Zie ook