次の方法で共有


XML ドキュメントからスキーマを推論する

このトピックでは、 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に対応します。

こちらも参照ください