共用方式為


使用 XPathNavigator 存取強型別化的 XML 數據

作為 XPath 2.0 數據模型的實例,類別 XPathNavigator 可以包含對應至 Common Language Runtime (CLR) 類型的強型別數據。 根據 XPath 2.0 資料模型,只有元素和屬性可以包含強型定義的資料。 類別XPathNavigator提供機制,允許存取XPathDocumentXmlDocument物件中的數據為強類型資料,以及提供從一種數據類型轉換為另一種數據類型的機制。

XPathNavigator 公開的類型資訊

除非使用 DTD、XML 架構定義語言 (XSD) 架構或其他機制進行處理,否則 XML 1.0 資料在技術上沒有類型。 有多種類型資訊的類別可以與 XML 元素或屬性相關聯。

  • 簡單的 CLR 類型:XML 架構語言都不支援 Common Language Runtime (CLR) 類型。 由於能夠將簡單元素和屬性內容檢視為最適當的 CLR 類型很有用,因此所有簡單內容都可以在缺少架構資訊的情況下輸入, String 而任何新增的架構資訊都可能會將此內容精簡為更適當的類型。 您可以使用 ValueType 屬性來找到最匹配的簡單元素和屬性內容的 CLR 類型。 如需從架構內建類型對應至CLR類型的詳細資訊,請參閱 System.Xml 類別中的類型支援

  • Simple (CLR) 類型清單:具有簡單內容的元素或屬性可以包含以空格符分隔的值清單。 這些值是由 XML 架構指定為「清單類型」。如果沒有 XML 架構,這類簡單內容會被視為單一文字節點。 當 XML 架構可供使用時,此簡單內容可以公開為一系列的原子值,每個值都有映射到 CLR 物件集合的簡單類型。 如需從架構內建類型對應至CLR類型的詳細資訊,請參閱 System.Xml 類別中的類型支援

  • 具型別化值:具有簡單型別的經過架構驗證的屬性或元素具有型別化值。 這個值是基本類型,例如數值、字串或日期類型。 XSD中的所有內建簡單型別都可以對應至CLR類型,從而以更適當的類型來存取節點的值,而不是單純將其視作String。 具有屬性或子元素的元素會被視為複雜類型。 具有簡單內容的複雜類型之類型值(僅有文字節點作為其子系)與其內容的簡單類型相同。 具有複雜內容(包含一或多個子元素)的複雜類型的具型別值,是其所有子文字節點串接後的字串值,並以 String 傳回。 如需從架構內建類型對應至CLR類型的詳細資訊,請參閱 System.Xml 類別中的類型支援

  • Schema-Language 特定類型名稱:在大部分情況下,將 CLR 類型設定為套用外部架構的副作用,可用來提供節點值的存取權。 不過,在某些情況下,您可能想要檢查與套用至 XML 檔之特定架構相關聯的類型。 例如,您可能想要搜尋 XML 檔,並根據附加的架構擷取判斷為具有 「PurchaseOrder」 類型內容的所有元素。 這類類型資訊只能設定為架構驗證的結果,而且這項資訊是透過 XmlType 類別的 SchemaInfoXPathNavigator 屬性來存取。 如需詳細資訊,請參閱下面的Post Schema Validation Infoset (PSVI) 一節。

  • Schema-Language 特定類型反映:在其他情況下,您可能想要取得套用至 XML 檔案的架構特定型別的進一步詳細數據。 例如,讀取 XML 檔案時,您可能想要擷取 maxOccurs XML 檔中每個有效節點的屬性,以便執行一些自定義計算。 由於這項資訊只會透過架構驗證來設定,所以會透過 SchemaInfo 類別的 XPathNavigator 屬性來存取。 如需詳細資訊,請參閱下面的Post Schema Validation Infoset (PSVI) 一節。

XPathNavigator 型別化的存取器

下表顯示類別的各種屬性和方法 XPathNavigator ,可用來存取節點的類型資訊。

房產 說明
XmlType 如果節點有效,這包含節點的 XML 架構類型資訊。
SchemaInfo 這包含經過驗證後新增的節點的模式驗證後信息集。 這包括 XML 架構類型資訊,以及有效性資訊。
ValueType 節點之具類型值的 CLR 類型。
TypedValue 節點的內容,做為一或多個 CLR 值,其類型最符合節點的 XML 架構類型。
ValueAsBoolean 根據 XPath 2.0 的String轉換規則,目前節點的Boolean值被轉換為xs:boolean值。
ValueAsDateTime 根據 XPath 2.0 的String轉換規則,目前節點的DateTime值被轉換為xs:datetime值。
ValueAsDouble 根據 XPath 2.0 的String轉換規則,目前節點的Double值被轉換為xsd:double值。
ValueAsInt 根據 XPath 2.0 的String轉換規則,目前節點的Int32值被轉換為xs:integer值。
ValueAsLong 根據 XPath 2.0 的String轉換規則,目前節點的Int64值被轉換為xs:integer值。
ValueAs 節點的內容會根據 XPath 2.0 轉換規則轉換成目標類型。

如需從架構內建類型對應至CLR類型的詳細資訊,請參閱 System.Xml 類別中的類型支援

架構驗證後資訊集(Post Schema Validation Infoset, PSVI)

XML 架構處理器接受 XML Infoset 做為輸入,並將它轉換成 Post Schema Validation Infoset (PSVI)。 PSVI 是原始輸入 XML 資訊集,當中加入了新的資訊專案,並在現有資訊專案中新增了新屬性。 在 PSVI 中,有三種廣泛的資訊類別會新增至 XML Infoset,而這些資訊是由 XPathNavigator 所揭示的。

  1. 驗證結果:元素或屬性是否成功驗證的相關資訊。 這會由 Validity 類別之 屬性的 SchemaInfoXPathNavigator 屬性公開。

  2. 默認資訊:指出元素或屬性的值是否是透過架構中指定的預設值取得。 這會由 IsDefault 類別之 屬性的 SchemaInfoXPathNavigator 屬性公開。

  3. 類型批註:可能為類型定義或元素和屬性宣告之模式元件的參考。 的 XmlTypeXPathNavigator 屬性包含節點的特定型別資訊,如果它是有效的。 如果節點的有效性未知,像是它在驗證後又被編輯過的情況。 XmlType屬性會設定為 null ,但類型資訊仍可從類別屬性SchemaInfoXPathNavigator的各種屬性取得。

以下範例說明如何利用XPathNavigator公開的 Post Schema Validation Infoset 中的資訊。

Dim settings As XmlReaderSettings = New XmlReaderSettings()  
settings.Schemas.Add("http://www.contoso.com/books", "books.xsd")  
settings.ValidationType = ValidationType.Schema  
  
Dim reader As XmlReader = XmlReader.Create("books.xml", settings)  
  
Dim document As XmlDocument = New XmlDocument()  
document.Load(reader)  
Dim navigator As XPathNavigator = document.CreateNavigator()  
navigator.MoveToChild("books", "http://www.contoso.com/books")  
navigator.MoveToChild("book", "http://www.contoso.com/books")  
navigator.MoveToChild("published", "http://www.contoso.com/books")  
  
Console.WriteLine(navigator.SchemaInfo.SchemaType.Name)  
Console.WriteLine(navigator.SchemaInfo.Validity)  
Console.WriteLine(navigator.SchemaInfo.SchemaElement.MinOccurs)  
XmlReaderSettings settings = new XmlReaderSettings();  
settings.Schemas.Add("http://www.contoso.com/books", "books.xsd");  
settings.ValidationType = ValidationType.Schema;  
  
XmlReader reader = XmlReader.Create("books.xml", settings);  
  
XmlDocument document = new XmlDocument();  
document.Load(reader);  
XPathNavigator navigator = document.CreateNavigator();  
navigator.MoveToChild("books", "http://www.contoso.com/books");  
navigator.MoveToChild("book", "http://www.contoso.com/books");  
navigator.MoveToChild("published", "http://www.contoso.com/books");  
  
Console.WriteLine(navigator.SchemaInfo.SchemaType.Name);  
Console.WriteLine(navigator.SchemaInfo.Validity);  
Console.WriteLine(navigator.SchemaInfo.SchemaElement.MinOccurs);  

此範例會採用 books.xml 檔案作為輸入。

<books xmlns="http://www.contoso.com/books">  
    <book>  
        <title>Title</title>  
        <price>10.00</price>  
        <published>2003-12-31</published>  
    </book>  
</books>  

此範例也會採用 books.xsd 架構作為輸入。

<xs:schema xmlns="http://www.contoso.com/books"
attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="http://www.contoso.com/books"
xmlns:xs="http://www.w3.org/2001/XMLSchema">  
    <xs:simpleType name="publishedType">  
        <xs:restriction base="xs:date">  
            <xs:minInclusive value="2003-01-01" />  
            <xs:maxInclusive value="2003-12-31" />  
        </xs:restriction>  
    </xs:simpleType>  
    <xs:complexType name="bookType">  
        <xs:sequence>  
            <xs:element name="title" type="xs:string"/>  
            <xs:element name="price" type="xs:decimal"/>  
            <xs:element name="published" type="publishedType"/>  
        </xs:sequence>  
    </xs:complexType>  
    <xs:complexType name="booksType">  
        <xs:sequence>  
            <xs:element name="book" type="bookType" />  
        </xs:sequence>  
    </xs:complexType>  
    <xs:element name="books" type="booksType" />  
</xs:schema>  

使用 ValueAs 屬性取得具類型的值

藉由存取TypedValueXPathNavigator屬性,可以擷取節點的具型別值。 在某些情況下,您可能會想要將節點的具型別值轉換成不同的類型。 常見的範例是從 XML 節點取得數值。 例如,請考慮下列未經驗證且不具類型的 XML 檔。

<books>  
    <book>  
        <title>Title</title>  
        <price>10.00</price>  
        <published>2003-12-31</published>  
    </book>  
</books>  

XPathNavigator如果位於 元素上priceXmlType則 屬性會是 nullValueType則 屬性會是 String,而 TypedValue 屬性會是字串 10.00

不過,仍然可以使用 ValueAsValueAsDoubleValueAsIntValueAsLong 方法和屬性,將值擷取為數值。 下列範例說明如何使用 ValueAs 方法執行這類轉換。

Dim document As New XmlDocument()  
document.Load("books.xml")  
Dim navigator As XPathNavigator = document.CreateNavigator()  
navigator.MoveToChild("books", "")  
navigator.MoveToChild("book", "")  
navigator.MoveToChild("price", "")  
  
Dim price = navigator.ValueAs(GetType(Decimal))  
Dim discount As Decimal = 0.2  
  
Console.WriteLine("The price of the book has been dropped 20% from {0:C} to {1:C}", navigator.Value, (price - price * discount))  
XmlDocument document = new XmlDocument();  
document.Load("books.xml");  
XPathNavigator navigator = document.CreateNavigator();  
navigator.MoveToChild("books", "");  
navigator.MoveToChild("book", "");  
navigator.MoveToChild("price", "");  
  
Decimal price = (decimal)navigator.ValueAs(typeof(decimal));  
  
Console.WriteLine("The price of the book has been dropped 20% from {0:C} to {1:C}", navigator.Value, (price - price * (decimal)0.20));  

如需從架構內建類型對應至CLR類型的詳細資訊,請參閱 System.Xml 類別中的類型支援

另請參閱