共用方式為


從 XML 文件推斷結構描述

本主題說明如何使用 XmlSchemaInference 類別,從 XML 文件結構推斷 XML 結構描述定義語言 (XSD) 結構描述。

結構描述推斷程序

XmlSchemaInference 命名空間的 System.Xml.Schema 類別,可用來從 XML 文件結構產生一或多個 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:unsignedByteparent 處理序發現第二個 XmlSchemaInference 項目時,即會將型別修改為 xs:string 而放寬條件約束,因為 attribute1 屬性的值此時為 A。 同樣地,所有 minOccurs 項目中在結構描述內進行推斷的 child 屬性,也會放寬為 minOccurs="0",因為第二個父項目沒有項目子系。

從 XML 文件推斷結構描述

XmlSchemaInference 類別可使用兩種多載 InferSchema 方法,從 XML 文件推斷結構描述。

第一種 XmlSchemaInference.InferSchema 方法可根據 XML 文件建立結構描述。 第二種 XmlSchemaInference.InferSchema 方法用來推斷可說明多個 XML 文件的結構描述。 例如,您可以逐一將多個 XML 文件傳送給 XmlSchemaInference.InferSchema 方法,以產生可說明完整 XML 文件集的結構描述。

第一種 XmlSchemaInference.InferSchema 方法會從 XmlReader 物件所含的 XML 文件推斷結構描述,並傳回含有所推斷之結構描述的 XmlSchemaSet 物件。 第二種 XmlSchemaInference.InferSchema 方法會搜尋 XmlSchemaSet 物件中是否有目標命名空間與 XmlReader 物件所含之 XML 文件相同的結構描述,然後進一步調整現有的結構描述,並傳回含有所推斷之結構描述的 XmlSchemaSet 物件。

對調整的結構描述所作的變更取決於在 XML 文件中找到的新結構。 例如,當 XML 文件周遊時,就會對找到的資料型別進行相關假設,並根據這些假設建立結構描述。 但若在第二次推斷傳遞時發現資料與原始假設不同,則會進一步調整結構描述。 下列範例將說明調整的程序。

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

此範例以下列檔案 (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 檔案做為第二個輸入:

<?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 型別。 但當讀取第二個 XML 文件並發現 A53-246 這個值時,則無法再假設 xs:unsignedInt 型別。 會調整結構描述,而 productID 的型別會變更為 xs:string。 此外,minOccurs 項目的 supplierID 屬性會設為 0,因為第二個 XML 文件中不含 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>

以下是從第一份 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>  

無法進一步調整的結構描述

有些 W3C XML 結構描述建構在指定要調整的型別時會擲回例外狀況,則 XML 結構描述定義語言 (XSD) 結構描述 XmlSchemaInference 處理序無法處理這類的結構描述。 最上層建構元不屬於序列的複雜型別即是一例。 在結構描述物件模型 (SOM) 中,它會對應至 XmlSchemaComplexType 屬性不屬於 Particle 之執行個體的 XmlSchemaSequence

另請參閱