Udostępnij za pośrednictwem


Wnioskowanie schematów na podstawie dokumentów XML

W tym temacie opisano sposób używania XmlSchemaInference klasy do wnioskowania schematu języka definicji schematu XML (XSD) ze struktury dokumentu XML.

Proces wnioskowania schematu

Klasa XmlSchemaInferenceSystem.Xml.Schema przestrzeni nazw służy do generowania co najmniej jednego schematu języka definicji schematu XML (XSD) ze struktury dokumentu XML. Wygenerowane schematy mogą służyć do weryfikowania oryginalnego dokumentu XML.

Ponieważ dokument XML jest przetwarzany przez XmlSchemaInference klasę, XmlSchemaInference klasa przyjmuje założenia dotyczące składników schematu opisujących elementy i atrybuty w dokumencie XML. Klasa XmlSchemaInference inferuje również składniki schematu w ograniczony sposób, wnioskowając najbardziej restrykcyjny typ dla określonego elementu lub atrybutu. W miarę zbierania dodatkowych informacji o dokumencie XML te ograniczenia są luźne przez wnioskowanie mniej restrykcyjnych typów. Najmniej restrykcyjny typ, który można wywnioskować, to xs:string.

Weźmy na przykład następujący fragment dokumentu XML.

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

W powyższym przykładzie, gdy attribute1 atrybut występuje z wartością 6 procesu XmlSchemaInference , przyjmuje się, że jest typu xs:unsignedByte. Po napotkaniu drugiego parentXmlSchemaInference elementu przez proces ograniczenie jest luźne, modyfikując typ na xs:string , ponieważ wartość atrybutu attribute1 wynosi teraz A. Podobnie atrybut dla wszystkich child elementów wywnioskowanych w schemacie jest luźnyminOccurs="0", minOccurs ponieważ drugi element nadrzędny nie ma elementów podrzędnych.

Wnioskowanie schematów na podstawie dokumentów XML

Klasa XmlSchemaInference używa dwóch przeciążonych InferSchema metod do wnioskowania schematu z dokumentu XML.

Pierwsza XmlSchemaInference.InferSchema metoda służy do tworzenia schematu na podstawie dokumentu XML. Druga XmlSchemaInference.InferSchema metoda służy do wnioskowania schematu opisującego wiele dokumentów XML. Można na przykład podawać wiele dokumentów XML do XmlSchemaInference.InferSchema metody pojedynczo w celu utworzenia schematu opisującego cały zestaw dokumentów XML.

Pierwsza XmlSchemaInference.InferSchema metoda wywnioskuje schemat z dokumentu XML zawartego XmlReader w obiekcie i zwraca XmlSchemaSet obiekt zawierający wywnioskowany schemat. Druga XmlSchemaInference.InferSchema metoda wyszukuje XmlSchemaSet obiekt schematu z tą samą docelową przestrzenią nazw co dokument XML zawarty w XmlReader obiekcie, uściśli istniejący schemat i zwraca XmlSchemaSet obiekt zawierający wywnioskowany schemat.

Zmiany wprowadzone w uściśliowanym schemacie są oparte na nowej strukturze znalezionej w dokumencie XML. Na przykład w miarę przechodzenia dokumentu XML przyjmuje się założenia dotyczące znalezionych typów danych, a schemat jest tworzony na podstawie tych założeń. Jeśli jednak dane są napotykane na drugim przebiegu wnioskowania, które różni się od pierwotnego założenia, schemat jest uściśliony. Poniższy przykład ilustruje proces uściślenia.

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

W przykładzie jest pobierany następujący plik , item1.xmljako pierwsze dane wejściowe.

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

W tym przykładzie item2.xml plik jest następnie pobierany jako jego drugie dane wejściowe:

<?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 Gdy atrybut zostanie napotkany w pierwszym dokumencie XML, przyjmuje się, że wartość 123456789 jest typemxs:unsignedInt. Jednak po odczytaniu drugiego dokumentu XML i znalezieniu A53-246xs:unsignedInt wartości nie można już przyjąć typu. Schemat jest uściśliny i typ productID jest zmieniany na xs:string. Ponadto minOccurs atrybut elementu supplierID jest ustawiony na 0, ponieważ drugi dokument XML nie supplierID zawiera żadnego elementu.

Poniżej przedstawiono schemat wywnioskowany z pierwszego 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>

Poniżej przedstawiono schemat wywnioskowany z pierwszego dokumentu XML, uściśliony przez drugi dokument 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>

Schematy wbudowane

Jeśli podczas procesu napotkany XmlSchemaInference jest schemat wbudowanego języka definicji schematu XML (XSD), XmlSchemaInferenceException zgłaszany jest błąd. Na przykład następujący wbudowany schemat zgłasza błąd 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>  

Schematy, których nie można uściślić

Istnieją konstrukcje schematu XML W3C, które proces schematu XML (XSD) nie XmlSchemaInference może obsłużyć, jeśli dany typ ma zostać uściślić i spowodować zgłoszenie wyjątku. Taki jak typ złożony, którego komponator najwyższego poziomu jest czymś innym niż sekwencja. W modelu obiektów schematu (SOM) odpowiada XmlSchemaComplexType to właściwości, której Particle właściwość nie jest wystąpieniem XmlSchemaSequenceklasy .

Zobacz też