Inferindo esquemas de documentos XML
Este tópico descreve como usar a classe de XmlSchemaInference para inferir um esquema de linguagem de definição de esquema XML (XSD) da estrutura de um documento XML.
O processo de inferência de esquema
A classe de XmlSchemaInference do espaço de System.Xml.Schema é usada para gerar um ou vários esquemas do idioma da definição de esquema XML (XSD) da estrutura de um documento XML. Os esquemas gerados podem ser usados para validar o documento XML original.
Como um documento XML é processado pela classe de XmlSchemaInference , a classe de XmlSchemaInference fazer suposições sobre os componentes do esquema que descrevem os elementos e atributos no documento XML. A classe de XmlSchemaInference também infere componentes do esquema de uma maneira restrito inferindo o tipo mais restritivo para um elemento ou atributo específico. Como obter mais informações sobre o documento XML são coletadas, essas restrições são afrouxadas inferindo tipos menos restritivos. Tipo menos restritivo que pode ser inferido é xs:string
.
Veja, por exemplo, a seguinte parte de um documento XML.
<parent attribute1="6">
<child>One</child>
<child>Two</child>
</parent>
<parent attribute1="A" />
No exemplo anterior, quando o atributo de attribute1
é encontrado com um valor de 6
pelo processo de XmlSchemaInference , é assumido ser do tipo xs:unsignedByte
. Quando o segundo elemento de parent
é encontrado pelo processo de XmlSchemaInference , a restrição está afrouxada alterando tipo a xs:string
como o valor do atributo de attribute1
agora é A
. Da mesma forma, o atributo de minOccurs
para todos os elementos de child
inferidos no esquema é afrouxado a minOccurs="0"
porque o segundo elemento pai não tiver nenhum elemento filho.
Inferindo esquemas de documentos XML
A classe de XmlSchemaInference usa dois métodos sobrecarregados de InferSchema para inferir um esquema de um documento XML.
O primeiro método de XmlSchemaInference.InferSchema é usado para criar um esquema com base em um documento XML. O segundo método de XmlSchemaInference.InferSchema é usado para inferir um esquema que descreve vários documentos XML. Por exemplo, você pode alimentar vários documentos XML para o método de XmlSchemaInference.InferSchema um de cada vez para gerar um esquema que descreve o conjunto de documentos XML.
O primeiro método de XmlSchemaInference.InferSchema infere um esquema de um documento XML contido em um objeto de XmlReader , e retorna um objeto de XmlSchemaSet que contém o esquema inferido. O segundo método de XmlSchemaInference.InferSchema procura um objeto de XmlSchemaSet por um esquema com a mesma namespace de destino que o documento XML contido no objeto de XmlReader , refinar o esquema existente, e retorna um objeto de XmlSchemaSet que contém o esquema inferido.
As alterações feitas ao esquema mais aguçado são baseadas na nova estrutura encontrada no documento XML. Por exemplo, como um documento XML é transmitido, as suposições são feitas sobre os tipos de dados encontrada, e o esquema é criado com base nessas suposições. No entanto, se os dados estão localizados em uma segunda passada de inferência suposição que seja diferente do esquema original, é mais aguçado. O exemplo a seguir ilustra o processo de refinamento.
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
O exemplo a seguir utiliza o arquivo, item1.xml
, como a primeira entrada.
<?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>
O exemplo usa o arquivo de item2.xml
como sua entrada segunda:
<?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>
Quando o atributo de productID
está localizado no primeiro documento XML, o valor de 123456789
é assumido ser um tipo de xs:unsignedInt
. No entanto, quando o segundo documento XML é ler e o valor de A53-246
é encontrado, o tipo de xs:unsignedInt
não pode mais ser adotado. O esquema é mais aguçado e o tipo de productID
é alterado para xs:string
. Além disso, o atributo de minOccurs
para o elemento de supplierID
é definido como 0
, porque o segundo documento XML não contém elementos de supplierID
.
O seguinte é o esquema inferido do primeiro documento 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>
O seguinte é o esquema inferido do primeiro documento XML, mais aguçado pelo segundo documento 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>
Esquemas in-line
Se um esquema de cores do idioma da definição de esquema XML (XSD) é encontrado durante o processo de XmlSchemaInference , XmlSchemaInferenceException é lançada. Por exemplo, o seguinte esquema embutido gerencie 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>
Esquemas que não podem ser refinados
Há construções de Esquema XML do W3C que o processo de XmlSchemaInference do idioma da definição de esquema XML (XSD) não pode manipular se um determinado tipo para refinar e causar uma exceção seja lançada. Como um tipo complexo cujo compositor de nível superior é algo diferente de uma sequência. No modelo de objeto (SOM) do esquema, isso corresponde a XmlSchemaComplexType cuja propriedade de Particle não é uma instância de XmlSchemaSequence.