Odvození schémat z dokumentů XML
Toto téma popisuje, jak pomocí XmlSchemaInference třídy odvodit schéma XSD (XML Schema Definition Language) ze struktury dokumentu XML.
Proces odvození schématu
XmlSchemaInference Třída System.Xml.Schema oboru názvů se používá k vygenerování jednoho nebo více schémat jazyka XSD (XML Schema Definition Language) ze struktury dokumentu XML. Vygenerovaná schémata lze použít k ověření původního dokumentu XML.
Vzhledem k tomu, že třída zpracovává XmlSchemaInference dokument XML, XmlSchemaInference třída vytváří předpoklady o komponentách schématu, které popisují prvky a atributy v dokumentu XML. Třída XmlSchemaInference také odvodí součásti schématu omezeným způsobem odvozením nejvíce omezujícího typu pro konkrétní prvek nebo atribut. S tím, jak se shromažďují další informace o dokumentu XML, jsou tato omezení uvolněna odvozením méně omezujících typů. Nejméně omezující typ, který lze odvodit, je xs:string
.
Podívejte se například na následující část dokumentu XML.
<parent attribute1="6">
<child>One</child>
<child>Two</child>
</parent>
<parent attribute1="A" />
V příkladu výše, když attribute1
je atribut zjištěn s hodnotou 6
XmlSchemaInference procesu, se předpokládá, že je typu xs:unsignedByte
. Pokud je druhý parent
prvek zjištěn procesem XmlSchemaInference , omezení je uvolněno úpravou typu, protože xs:string
hodnota atributu attribute1
je nyní A
. minOccurs
Podobně atribut pro všechny child
prvky odvozené ve schématu jsou uvolněnyminOccurs="0"
, protože druhý nadřazený prvek nemá žádné podřízené prvky.
Odvození schémat z dokumentů XML
Třída XmlSchemaInference používá dvě přetížené InferSchema metody k odvození schématu z dokumentu XML.
První XmlSchemaInference.InferSchema metoda se používá k vytvoření schématu založeného na dokumentu XML. Druhá XmlSchemaInference.InferSchema metoda se používá k odvození schématu, které popisuje více dokumentů XML. Do metody můžete například generovat více dokumentů XmlSchemaInference.InferSchema XML po jednom, abyste vytvořili schéma, které popisuje celou sadu dokumentů XML.
První XmlSchemaInference.InferSchema metoda odvodí schéma z dokumentu XML obsaženého v objektu XmlReader a vrátí XmlSchemaSet objekt obsahující odvozené schéma. Druhá XmlSchemaInference.InferSchema metoda vyhledá XmlSchemaSet objekt pro schéma se stejným cílovým oborem názvů jako dokument XML obsažený v objektu XmlReader , zpřesní existující schéma a vrátí XmlSchemaSet objekt obsahující odvozené schéma.
Změny provedené v upřesňujícím schématu jsou založeny na nové struktuře nalezené v dokumentu XML. Například při procházení dokumentu XML se vytvoří předpoklady o nalezených datových typech a schéma se vytvoří na základě těchto předpokladů. Pokud se však data najdou při druhém odvozování, který se liší od původního předpokladu, schéma se zpřesní. Následující příklad znázorňuje proces upřesnění.
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
Příklad přebírá následující soubor , item1.xml
jako první vstup.
<?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>
Příklad pak vezme item2.xml
soubor jako druhý vstup:
<?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>
productID
Pokud je atribut zjištěn v prvním dokumentu XML, předpokládá se, že xs:unsignedInt
hodnota 123456789
je typu. Pokud je však druhý dokument XML přečtený a hodnota A53-246
nalezena, xs:unsignedInt
typ již nelze předpokládat. Schéma je upřesněno a typ productID
se změní na xs:string
. Kromě toho je minOccurs
atribut prvku supplierID
nastaven na 0
, protože druhý dokument XML neobsahuje žádný supplierID
prvek.
Následuje schéma odvozené z prvního dokumentu 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>
Následuje schéma odvozené z prvního dokumentu XML, které je upřesněno druhým dokumentem 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>
Vložená schémata
Pokud je během XmlSchemaInference procesu zjištěno schéma jazyka XSD (Inline XML Schema Definition Language), vyvolá se vyvolá XmlSchemaInferenceException chyba. Například následující vložené schéma vyvolá výjimku 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émata, která nelze upřesnit
Existují konstrukce schématu W3C, které proces schématu XmlSchemaInference XSD (XML Schema Definition Language) nemůže zpracovat, pokud je daný typ upřesněn a způsobit výjimku. Například komplexní typ, jehož kompozitor nejvyšší úrovně je cokoli jiného než sekvence. V modelu objektu schématu (SOM) to odpovídá XmlSchemaComplexType , jehož Particle vlastnost není instancí XmlSchemaSequence.