作为 XPath 2.0 数据模型的实例,XPathNavigator 类可以包含映射到公共语言运行库 (CLR) 类型的强类型数据。 根据 XPath 2.0 数据模型,只有元素和属性可以包含强类型化数据。 该XPathNavigator类提供用于将对象XPathDocumentXmlDocument中的数据作为强类型数据访问的机制,以及从一种数据类型转换为另一种数据类型的机制。
通过 XPathNavigator 公开的类型信息
XML 1.0 数据在技术上没有类型,除非使用 DTD、XML 架构定义语言(XSD)架构或其他机制进行处理。 有许多类别的类型信息可以与 XML 元素或属性相关联。
简单的 CLR 类型:XML 架构语言都不支持直接公共语言运行时 (CLR) 类型。 由于能够将简单元素和属性内容视为最合适的 CLR 类型非常有用,因此在缺少架构信息时,所有简单内容都可以被视为 String 类型,而任何添加的架构信息都可能会将此内容优化为更合适的类型。 可以使用该 ValueType 属性找到与简单元素和属性内容的最佳匹配 CLR 类型。 有关从架构内置类型到 CLR 类型的映射的详细信息,请参阅 System.Xml 类中的类型支持。
简单 (CLR) 类型列表:包含简单内容的元素或属性可以包含用空格分隔的值列表。 这些值由 XML 架构指定为“列表类型”。如果没有 XML 架构,此类简单内容将被视为单个文本节点。 当 XML 架构可用时,可以将此简单内容公开为一系列原子值,每个值都具有映射到 CLR 对象的集合的简单类型。 有关从架构内置类型到 CLR 类型的映射的详细信息,请参阅 System.Xml 类中的类型支持。
类型化值:具有简单类型的架构验证属性或元素具有类型化值。 此值是基元类型,例如数字、字符串或日期类型。 XSD 中的所有内置简单类型均可以映射到 CLR 类型,通过 CLR 类型可以以更适合的类型(而不只是以 String)访问节点的值。 具有属性或元素子级的元素被视为复杂类型。 包含简单内容(只有文本节点作为子级)的复杂类型的类型化值与其内容的简单类型的类型化值相同。 具有复杂内容的复杂类型的类型化值(一个或多个子元素)是其所有子文本节点串联后的字符串值,呈现为String。 有关从架构内置类型到 CLR 类型的映射的详细信息,请参阅 System.Xml 类中的类型支持。
Schema-Language 特定类型名称:在大多数情况下,CLR 类型由于应用外部架构而被设置,并用于提供对节点值的访问。 但是,在某些情况下,可能需要检查与应用于 XML 文档的特定架构关联的类型。 例如,可能希望搜索 XML 文档,根据附加的架构提取确定包含“PurchaseOrder”类型内容的所有元素。 此类类型信息只能通过模式验证设置结果获得,并且这些信息通过XmlType类的SchemaInfo和XPathNavigator属性访问。 有关详细信息,请参阅下面的“后置架构验证信息集”(PSVI)部分。
Schema-Language 特定类型反射:在其他情况下,你可能希望获取应用于 XML 文档的架构特定类型的详细信息。 例如,读取 XML 文件时,可能需要提取
maxOccurs
XML 文档中每个有效节点的属性,以便执行一些自定义计算。 由于此信息只能通过架构验证进行设置,因此可通过 SchemaInfo 类的属性 XPathNavigator 访问此信息。 有关详细信息,请参阅下面的“后置架构验证信息集”(PSVI)部分。
XPathNavigator 类型化访问器
下表显示了可用于访问有关节点的类型信息的类的各种属性和方法 XPathNavigator 。
资产 | DESCRIPTION |
---|---|
XmlType | 该信息包含节点的 XML 架构类型信息(如果节点有效)。 |
SchemaInfo | 此属性包含在验证之后添加的节点的后架构验证信息集。 这包括 XML 架构类型信息以及有效性信息。 |
ValueType | 节点的类型化值的 CLR 类型。 |
TypedValue | 节点的内容为一个或多个 CLR 值,其类型与节点的 XML 架构类型最接近。 |
ValueAsBoolean | 当前节点的 String 值根据 Boolean 的 XPath 2.0 强制转换规则强制转换为 xs:boolean 值。 |
ValueAsDateTime | 当前节点的 String 值根据 DateTime 的 XPath 2.0 强制转换规则强制转换为 xs:datetime 值。 |
ValueAsDouble | 当前节点的 String 值根据 Double 的 XPath 2.0 强制转换规则强制转换为 xsd:double 值。 |
ValueAsInt | 当前节点的 String 值根据 Int32 的 XPath 2.0 强制转换规则强制转换为 xs:integer 值。 |
ValueAsLong | 当前节点的 String 值根据 Int64 的 XPath 2.0 强制转换规则强制转换为 xs:integer 值。 |
ValueAs | 节点内容根据 XPath 2.0 强制转换规则强制转换为目标类型。 |
有关从架构内置类型到 CLR 类型的映射的详细信息,请参阅 System.Xml 类中的类型支持。
后架构验证信息集 (PSVI)
XML 架构处理器接受 XML 信息集作为输入,并将其转换为后模式验证信息集(PSVI)。 PSVI 是原始输入 XML 信息集,其中添加了新信息项,以及添加到现有信息项的新属性。 PSVI 向 XML Infoset 中添加了三类广泛的信息,这些信息由 XPathNavigator 显示。
验证结果:有关元素或属性是否已成功验证的信息。 此信息通过 Validity 类的 SchemaInfo 属性的 XPathNavigator 属性公开。
默认信息:指示是否通过架构中指定的默认值获取元素或特性的值。 此信息通过 IsDefault 类的 SchemaInfo 属性的 XPathNavigator 属性公开。
类型注释:对可能是类型定义或元素和属性声明的架构组件的引用。 该 XmlType 的属性 XPathNavigator 包含节点的特定类型信息(如果该节点有效)。 如果一个节点的有效性未知,例如该节点在验证后又被编辑。 然后,XmlType 属性被设置为
null
,但类型信息仍然可以从 SchemaInfo 类的 XPathNavigator 属性的各种性质中获取。
下面的示例演示了如何使用由 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 属性获取类型化值
节点的类型化值可以通过访问 TypedValue 的 XPathNavigator 属性进行检索。 在某些情况下,可能需要将节点的类型化值转换为其他类型。 一个常见示例是从 XML 节点获取数值。 例如,请考虑以下未经验证和非类型化的 XML 文档。
<books>
<book>
<title>Title</title>
<price>10.00</price>
<published>2003-12-31</published>
</book>
</books>
如果XPathNavigator位于price
元素上,则XmlType属性将是null
,ValueType属性将是String,并且TypedValue属性将是字符串10.00
。
但是,仍可以使用ValueAs、ValueAsDouble、ValueAsInt或ValueAsLong方法和属性将值提取为数值。 以下示例说明如何使用 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 类中的类型支持。