Поделиться через


Доступ к XML-данным со строгой типизацией с помощью XPathNavigator

Класс XPathNavigator, как экземпляр модели данных XPath 2.0, может содержать данные со строгой типизацией, которые сопоставляются с типами CLR. Согласно модели данных XPath 2.0, только элементы и атрибуты могут содержать данные со строгой типизацией. Класс XPathNavigator предоставляет механизмы для доступа к данным со строгой типизацией в объектах XPathDocument и XmlDocument, а также механизмы для преобразования данных из одного типа в другой.

Информация о типах, предоставляемая XPathNavigator

Данные XML 1.0 практически не имеют типа, если они не обработаны с помощью определения DTD, схемы XSD или другим средством. Существует несколько категорий сведений о типах, которые можно связать с XML-элементом или атрибутом.

  • Простые типы CLR. Ни один из языков схемы XML не поддерживает типы CLR напрямую. Поскольку удобно иметь возможность просматривать простое содержимое элементов и атрибутов в виде соответствующих типов CLR, все простое содержимое можно типизировать как String в отсутствие данных схемы и любой добавленной информации о схеме, способной уточнить наиболее соответствующий тип этого содержимого. Наиболее совпадающий тип CLR для простого содержимого элемента или атрибута можно найти с помощью свойства ValueType. Дополнительные сведения о сопоставлении встроенных типов схемы с типами CLR см. в руководстве по поддержке типов в классах System.Xml.

  • Списки простых типов (CLR). Элемент или атрибут с простым содержимым может включать список значений, разделенных пробелом. Значения задаются XML-схемой как "тип списка". В отсутствие xml-схемы такой простой контент будет рассматриваться как один текстовый узел. При наличии схемы XML это простое содержимое может быть представлено как ряд атомарных значений, каждое из которых имеет простой тип, сопоставляемый с коллекцией объектов CLR. Дополнительные сведения о сопоставлении встроенных типов схемы с типами CLR см. в руководстве по поддержке типов в классах System.Xml.

  • Типизированное значение. Проверенный на соответствие схеме атрибут или элемент с простым типом, имеющий типизированное значение. Это значение является типом-примитивом, например типом numeric, string или date. Все встроенные простые типы в XSD могут сопоставляться с типами CLR, предоставляющими доступ к значению узла как наиболее соответствующему типу, а не просто типу String. Элемент с атрибутами или дочерними элементами рассматривается как сложный тип. Типизированное значение сложного типа с простым содержимым (только текстовые узлы в качестве дочерних элементов) - то же самое, что и значение простого типа. Типизированное значение сложного типа со сложным содержимым (один или несколько дочерних элементов) является строковым значением объединения всех его текстовых узлов, возвращенных как тип String. Дополнительные сведения о сопоставлении встроенных типов схемы с типами CLR см. в руководстве по поддержке типов в классах System.Xml.

  • Имя типа, зависящее от языка схемы. В большинстве случаев типы CLR, которые устанавливаются как результат применения внешней схемы, используются для предоставления доступа к значению узла. Однако в некоторых ситуациях нужно изучить тип, связанный с конкретной схемой, примененной к XML-документу. Например, требуется выполнить поиск в XML-документе и получить все элементы, имеющие тип содержимого «PurchaseOrder», согласно присоединенной схеме. Такие сведения о типе можно получить только в результате проверки схемы, а доступ к ним осуществляется с помощью свойств XmlType и SchemaInfo класса XPathNavigator. Дополнительные сведения см. в разделе «Набор сведений для постсхемной проверки (PSVI)» ниже.

  • Отражение типа, зависящее от языка схемы. В других случаях, возможно, потребуется получить дополнительные сведения о типе, зависящем от схемы, примененной к 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.

Информационный набор после проверки по схеме

Процессор схемы XML принимает в качестве входных данных информационный набор XML и преобразует его в информационный набор после проверки по схеме. Информационный набор после проверки по схеме является исходным информационным набором XML с новыми информационными элементами и новыми свойствами, добавленными к существующим информационным элементам. Существует три широких класса данных, которые добавляются в информационный набор XML в информационном наборе после проверки по схеме, предоставляемом классом XPathNavigator.

  1. Результаты проверки. Сведения об успешной или неуспешной проверке элемента или атрибута. Это представляется свойством Validity свойства SchemaInfo класса XPathNavigator.

  2. Сведения по умолчанию. Данные о том, было ли получено значение элемента или атрибута из заданных в схеме значений по умолчанию или из других источников. Это представляется свойством IsDefault свойства SchemaInfo класса XPathNavigator.

  3. Заметки о типе. Ссылки на компоненты схемы, которые могут быть определениями типов или объявлениями элементов и атрибутов. Свойство XmlType объекта XPathNavigator содержит конкретные сведения о типе узла, если он допустим. Если достоверность узла неизвестна, например если он после проверки подвергся изменению, то свойство XmlType имеет значение null, но информация о типе остается доступной через различные свойства SchemaInfo класса XPathNavigator.

В следующем примере демонстрируются сведения информационного набора после проверки по схеме, предоставленной объектом XPathNavigator.

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.

См. также