Partilhar via


Acessando dados XML fortemente tipados usando XPathNavigator

Como uma instância do modelo de dados XPath 2.0, a XPathNavigator classe pode conter dados fortemente tipados que mapeiam para tipos CLR (Common Language Runtime). De acordo com o modelo de dados XPath 2.0, apenas elementos e atributos podem conter dados fortemente tipados. A XPathNavigator classe fornece mecanismos para acessar dados dentro de um XPathDocument ou XmlDocument objeto como dados fortemente tipados, bem como mecanismos para converter de um tipo de dados para outro.

Informações de tipo expostas pelo XPathNavigator

Os dados XML 1.0 são tecnicamente sem tipo, a menos que sejam processados com um esquema DTD, XSD (XML schema definition language) ou outro mecanismo. Há várias categorias de informações de tipo que podem ser associadas a um elemento ou atributo XML.

  • Tipos CLR simples: Nenhuma das linguagens de esquema XML suporta tipos CLR (Common Language Runtime) diretamente. Como é útil poder visualizar o conteúdo de elementos e atributos simples como o tipo CLR mais apropriado, todo o conteúdo simples pode ser digitado como String na ausência de informações de esquema com qualquer informação de esquema adicionada potencialmente refinando esse conteúdo para um tipo mais apropriado. Você pode encontrar o melhor tipo CLR correspondente de conteúdo de elemento simples e atributo usando a ValueType propriedade. Para obter mais informações sobre o mapeamento de tipos internos de esquema para tipos CLR, consulte Suporte a tipos nas classes System.Xml.

  • Listas de tipos simples (CLR): um elemento ou atributo com conteúdo simples pode conter uma lista de valores separados por espaço em branco. Os valores são especificados por um esquema XML para ser um "tipo de lista". Na ausência de um esquema XML, esse conteúdo simples seria tratado como um único nó de texto. Quando um esquema XML está disponível, esse conteúdo simples pode ser exposto como uma série de valores atômicos, cada um com um tipo simples que mapeia para uma coleção de objetos CLR. Para obter mais informações sobre o mapeamento de tipos internos de esquema para tipos CLR, consulte Suporte a tipos nas classes System.Xml.

  • Valor digitado: um atributo ou elemento validado por esquema com um tipo simples tem um valor digitado. Esse valor é um tipo primitivo, como um tipo numérico, de cadeia de caracteres ou de data. Todos os tipos simples internos no XSD podem ser mapeados para tipos CLR que fornecem acesso ao valor de um nó como um tipo mais apropriado em vez de apenas como um String. Um elemento com atributos ou elemento filhos é considerado um tipo complexo. O valor digitado de um tipo complexo com conteúdo simples (apenas nós de texto como filhos) é o mesmo que o do tipo simples de seu conteúdo. O valor digitado de um tipo complexo com conteúdo complexo (um ou mais elementos filho) é o valor da cadeia de caracteres da concatenação de todos os seus nós de texto filho retornados como um Stringarquivo . Para obter mais informações sobre o mapeamento de tipos internos de esquema para tipos CLR, consulte Suporte a tipos nas classes System.Xml.

  • Nome do tipo específico da linguagem do esquema: Na maioria dos casos, os tipos CLR, que são definidos como um efeito colateral da aplicação de um esquema externo, são usados para fornecer acesso ao valor de um nó. No entanto, pode haver situações em que você pode querer examinar o tipo associado a um esquema específico aplicado a um documento XML. Por exemplo, você pode querer pesquisar através de um documento XML, extraindo todos os elementos que são determinados como tendo conteúdo do tipo "PurchaseOrder" de acordo com um esquema anexado. Essas informações de tipo podem ser definidas somente como resultado da validação do esquema e essas informações são acessadas através XmlType das propriedades e SchemaInfo da XPathNavigator classe. Para obter mais informações, consulte a seção Post Schema Validation Infoset (PSVI) abaixo.

  • Reflexão de tipo específico da linguagem de esquema: Em outros casos, convém obter mais detalhes do tipo específico do esquema aplicado a um documento XML. Por exemplo, ao ler um arquivo XML, convém extrair o maxOccurs atributo para cada nó válido no documento XML para executar algum cálculo personalizado. Como essas informações são definidas somente por meio da validação de esquema, elas são acessadas por meio SchemaInfo da propriedade da XPathNavigator classe. Para obter mais informações, consulte a seção Post Schema Validation Infoset (PSVI) abaixo.

Acessadores digitados XPathNavigator

A tabela a seguir mostra as várias propriedades e métodos da classe que podem ser usados para acessar as informações de XPathNavigator tipo sobre um nó.

Property Description
XmlType Isso contém as informações de tipo de esquema XML para o nó, se for válido.
SchemaInfo Isso contém o Infoset de Validação de Esquema de Postagem do nó que é adicionado após a validação. Isso inclui as informações de tipo de esquema XML, bem como informações de validade.
ValueType O tipo CLR do valor digitado do nó.
TypedValue O conteúdo do nó como um ou mais valores CLR cujo tipo é a correspondência mais próxima do tipo de esquema XML do nó.
ValueAsBoolean O String valor do nó atual convertido em um Boolean valor, de acordo com as regras de transmissão XPath 2.0 para xs:boolean.
ValueAsDateTime O String valor do nó atual convertido em um DateTime valor, de acordo com as regras de transmissão XPath 2.0 para xs:datetime.
ValueAsDouble O String valor do nó atual convertido em um Double valor, de acordo com as regras de transmissão XPath 2.0 para xsd:double.
ValueAsInt O String valor do nó atual convertido em um Int32 valor, de acordo com as regras de transmissão XPath 2.0 para xs:integer.
ValueAsLong O String valor do nó atual convertido em um Int64 valor, de acordo com as regras de transmissão XPath 2.0 para xs:integer.
ValueAs O conteúdo do nó é convertido para o tipo de destino de acordo com as regras de transmissão XPath 2.0.

Para obter mais informações sobre o mapeamento de tipos internos de esquema para tipos CLR, consulte Suporte a tipos nas classes System.Xml.

O Infoset de Validação de Esquema Pós (PSVI)

Um processador de esquema XML aceita um Infoset XML como entrada e o converte em um PSVI (Post Schema Validation Infoset). Um PSVI é o conjunto de informações XML de entrada original com novos itens de informação adicionados e novas propriedades adicionadas aos itens de informação existentes. Há três classes amplas de informações adicionadas ao Infoset XML no PSVI que são expostas pelo XPathNavigator.

  1. Resultados da validação: Informação sobre se um elemento ou atributo foi validado com êxito ou não. Isso é exposto pela Validity propriedade da propriedade da SchemaInfoXPathNavigator classe.

  2. Informações padrão: Indicações sobre se o valor do elemento ou atributo foi obtido por meio de valores padrão especificados no esquema ou não. Isso é exposto pela IsDefault propriedade da propriedade da SchemaInfoXPathNavigator classe.

  3. Anotações de tipo: Referências a componentes de esquema que podem ser definições de tipo ou declarações de elemento e atributo. A XmlType propriedade do XPathNavigator contém as informações de tipo específico do nó, se for válida. Se a validade de um nó for desconhecida, como quando ele foi validado e posteriormente editado. Em seguida, a XmlType propriedade é definida como null mas as informações de tipo ainda estão disponíveis nas várias propriedades da SchemaInfo propriedade da XPathNavigator classe.

O exemplo a seguir ilustra o uso de informações no Infoset de Validação de Esquema Post exposto pelo 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);  

O exemplo usa o books.xml arquivo como entrada.

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

O exemplo também usa o books.xsd esquema como entrada.

<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>  

Obter valores digitados usando propriedades ValueAs

O valor digitado de um nó pode ser recuperado acessando a TypedValue propriedade do XPathNavigator. Em certos casos, você pode querer converter o valor digitado de um nó para um tipo diferente. Um exemplo comum é obter um valor numérico de um nó XML. Por exemplo, considere o seguinte documento XML não validado e não tipado.

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

Se o XPathNavigator é posicionado price no elemento a XmlType propriedade seria null, a ValueType propriedade seria String, e a TypedValue propriedade seria a cadeia de caracteres 10.00.

No entanto, ainda é possível extrair o valor como um valor numérico usando o ValueAs, ValueAsDouble, ValueAsInt, ou ValueAsLong método e propriedades. O exemplo a seguir ilustra a execução de tal elenco usando o ValueAs método.

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));  

Para obter mais informações sobre o mapeamento de tipos internos de esquema para tipos CLR, consulte Suporte a tipos nas classes System.Xml.

Consulte também