このトピックでは、 XmlSchemaInference クラスを使用して、XML ドキュメントの構造から XML スキーマ定義言語 (XSD) スキーマを推論する方法について説明します。
スキーマ推論プロセス
XmlSchemaInference名前空間のSystem.Xml.Schema クラスは、XML ドキュメントの構造から 1 つ以上の XML スキーマ定義言語 (XSD) スキーマを生成するために使用されます。 生成されたスキーマを使用して、元の XML ドキュメントを検証できます。
XML ドキュメントが XmlSchemaInference クラスによって処理されるため、 XmlSchemaInference クラスは、XML ドキュメント内の要素と属性を記述するスキーマ コンポーネントについて想定します。 また、 XmlSchemaInference クラスは、特定の要素または属性の最も制限の厳しい型を推論することによって、制約付きの方法でスキーマ コンポーネントを推論します。 XML ドキュメントに関する詳細が収集されると、制限の緩い型を推測することで、これらの制約が緩和されます。 推論できる最も制限の厳しい型は xs:string
。
たとえば、XML ドキュメントの次の部分を見てみましょう。
<parent attribute1="6">
<child>One</child>
<child>Two</child>
</parent>
<parent attribute1="A" />
上記の例では、attribute1
プロセスによって 6
属性が XmlSchemaInference の値と検出された場合、xs:unsignedByte
型であると見なされます。
parent
プロセスで 2 番目のXmlSchemaInference要素が検出されると、xs:string
属性の値がattribute1
になったため、型をA
に変更することで制約が緩和されます。 同様に、スキーマで推論されるすべてのminOccurs
要素のchild
属性は、2 番目の親要素に子要素がないため、minOccurs="0"
に緩まれます。
XML ドキュメントからのスキーマの推論
XmlSchemaInference クラスは、2 つのオーバーロードされたInferSchema メソッドを使用して、XML ドキュメントからスキーマを推論します。
最初の XmlSchemaInference.InferSchema メソッドは、XML ドキュメントに基づいてスキーマを作成するために使用されます。 2 番目の XmlSchemaInference.InferSchema メソッドは、複数の XML ドキュメントを記述するスキーマを推論するために使用されます。 たとえば、複数の XML ドキュメントを XmlSchemaInference.InferSchema メソッドに一度に 1 つずつフィードして、XML ドキュメントのセット全体を記述するスキーマを生成できます。
最初の XmlSchemaInference.InferSchema メソッドは、 XmlReader オブジェクトに含まれる XML ドキュメントからスキーマを推論し、推論されたスキーマを含む XmlSchemaSet オブジェクトを返します。 2 番目のXmlSchemaInference.InferSchemaメソッドは、XmlSchemaSet オブジェクトに含まれる XML ドキュメントと同じターゲット名前空間を持つスキーマをXmlReader オブジェクトで検索し、既存のスキーマを絞り込み、推論されたスキーマを含むXmlSchemaSet オブジェクトを返します。
洗練されたスキーマに加えられた変更は、XML ドキュメントで見つかった新しい構造に基づいています。 たとえば、XML ドキュメントが走査されると、見つかったデータ型に関する想定が行われ、それらの前提条件に基づいてスキーマが作成されます。 ただし、元の想定とは異なる 2 番目の推論パスでデータが検出された場合、スキーマは調整されます。 次の例は、絞り込みプロセスを示しています。
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
この例では、最初の入力として、 item1.xml
次のファイルを受け取ります。
<?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>
この例では、 item2.xml
ファイルを 2 番目の入力として受け取ります。
<?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>
最初の XML ドキュメントで productID
属性が検出されると、 123456789
の値は xs:unsignedInt
型であると見なされます。 ただし、2 番目の XML ドキュメントが読み取られ、 A53-246
の値が見つかった場合、 xs:unsignedInt
型は想定されなくなります。 スキーマが調整され、 productID
の型が xs:string
に変更されます。 さらに、2 番目の XML ドキュメントにはminOccurs
要素が含まれるので、supplierID
要素の0
属性はsupplierID
に設定されます。
最初の 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>
2 番目の XML ドキュメントで絞り込まれた、最初の 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>
インライン スキーマ
XmlSchemaInference プロセス中にインライン XML スキーマ定義言語 (XSD) スキーマが検出された場合、XmlSchemaInferenceExceptionがスローされます。 たとえば、次のインライン スキーマでは、 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>
調整できないスキーマ
XML スキーマ定義言語 (XSD) スキーマ XmlSchemaInference プロセスで処理できない W3C XML スキーマ コンストラクトがあります。型が指定された場合は、絞り込んで例外がスローされます。 最上位レベルのコンポジターがシーケンス以外の複合型などです。 スキーマ オブジェクト モデル (SOM) では、これは、XmlSchemaComplexType プロパティがParticleのインスタンスではないXmlSchemaSequenceに対応します。
こちらも参照ください
.NET