Desenvolvimento - XML
Acessando XML remoto e buscando informações com o Namespace System.Xml.XPath
Há certas ocasiões onde precisamos obter informações de um arquivo xml de outro site por exemplo e por mais que seja um XML não podemos encará-lo como um WebService, pois não foi criado com tal objetivo. Neste artigo mostro a navegação em um documento XML utilizando o Namespace XPath.
por Rodrigo GlauserHá certas ocasiões onde precisamos
obter informações de um arquivo xml de outro site por exemplo e por mais
queseja um XML não podemos encará-lo como um WebService,pois não foi
criado com tal objetivo. Esses arquivos xmlna maioria das vezes não
podemser importados para um DataSet com o Método ReadXml por sua
incompatibilidade na formalização da estrutura dodocumento e nesta
hora é necessário procurar classes específicas no Namespace System.XML. Neste
artigo mostro a navegação em um documento XML utilizando o Namespace
XPath.
No .NET framework 1.1 há um Namespace inteiro para a utilização
deste padrão, o System.XML.XPath. Entretando antes de
utilizá-lo o programador terá que saber os conceitos de um Arquivo
XML.
Estrutura de um Documento
XML
<?xml version="1.0"
encoding="ISO-8859-1"?>
<brasil>
<cidade
id="1">
<nome>Itararé</nome>
<populacao>65000</populacao>
<idade>690</idade>
</cidade>
<!--
Isto é um Comentário -->
<cidade id="2">
<nome>Ponta
Grossa</nome>
<populacao>300000<populacao>
<idade>1800</idade>
</cidade>
</brasil>
Onde:
<brasil> - é um elemento, neste caso podemos chamá-lo de elemento Pai.
<nome> - Dados em um documento XML são hierárquicos. Elementos podem conter outros elementos que são chamados de elementos filhos.O elemento nome é elemento filho do elemento cidade:
id="2" - id é um Atributo. Atributos são informações adicionais sobre um elemento.
Ponta Grossa - é o Texto ou Valor do Elemento nome.
Agora que já conhecemos os conceitos básicos do XML podemos começar a utilizar o XPath para fazer a pesquisa no documento.O Documento que iremos pesquisar será o de boletim das condições metereológicas do Paraná que está disponível em http://www.simepar.br/tempo/boletimxml.jsp
1º Passo - Fazer a solicitação do documento
Antes de tudoimporte osnamespacesSystem.Net , System.Xml e System.Xml.XPath. Como o nosso documento está em um site remoto na internet faremos a requisição com as classes WebRequest e WebResponse.
Dim myRequest As WebRequest
Dim myResponse As
WebResponse
Dim VarStream As Stream
Dim xmlreader As XmlTextReader
Dim
xpathDoc As XPathDocument
If Me.Cache("xpathDoc") Is Nothing
Then
" Verifica se objeto xpathDoc está em
Cache
myRequest =
WebRequest.Create("http://www.simepar.br/tempo/boletimxml.jsp")
" Criação do Objeto myRequest que prepara a requisição que será
enviada ao URL remoto
myResponse = myRequest.GetResponse()
" Faz a requisição
VarStream =
myResponse.GetResponseStream()
" O Conteúdo da requisição
fica armazenado no objeto VarStream
xmlreader = New
XmlTextReader(VarStream)
" O XmlTextReader é necessário
para instanciar o XPathDoc
xpathDoc = New
XPathDocument(xmlreader)
" XPathDocument é a classe que contém todo o documento
XML
" Se você desejar abrir um xml no servidor
utilize:
" xpathDoc = new
XPathDocument(Server.MapPath("arquivo.xml"))
Me.Cache.Insert("xpathDoc",
xpathDoc, Nothing, _
Now.AddMinutes(60),
Caching.Cache.NoSlidingExpiration)
" Coloca em Cache o
objeto xpathDoc para otimização da página.
" Isso porque o conteúdo do XML
não apresenta alterações frequentes,
" portanto a requisição pode ser feita
em períodos determinados.
" Neste caso60
minutos.
Else
xpathDoc = CType(Me.Cache("xpathDoc"),
XPathDocument)
" Utilização do objeto em cache otimizando
a performance.
End If
2º Passo - Utilizando o XPath
Agora com o documento requisitado no objeto Stream
já podemos iniciar a pesquisa porém antes vamos entender melhor o que é a
Tecnologia XPath.
XPath é um padrão da
W3C, lançado em 1999 como um linguagem para endereçamento de partes de um
documento XML. XPath usa expressões para localizar nós ( elementos ) em um XML.
As expressões são simples de se usar e muito ricas em
funcionalidades.
Fragmento do Documento XML da Simepar para
exemplificar as expressões:
<?xml version="1.0"
encoding="ISO-8859-1"?>
<boletim data="04/01/2005"
periodo="tarde">
<municipio id="4106902"
nome="Curitiba">
<dia1 data="04/01/2005"
diadasemana="Ter">
<tempo>
<legendanoite id="14"
icone="14.gif">nublado com chuva e
trovoadas</legendanoite>
</tempo>
</dia1>
</municipio>
</boletim>
Exemplos de expressões:
A
Expressão a seguir seleciona todos os elementos dia1 de todos os elementos
municipio:
/boletim/municipio/dia1
Resultado:
<dia1 data="04/01/2005"
diadasemana="Ter"></dia1>
A Expressão a seguir seleciona
todos os elementos dia1 e seus elementos
filhos:
/boletim/municipio/dia1/*
<dia1 data="04/01/2005"
diadasemana="Ter">
<tempo>
<legendanoite id="14"
icone="14.gif">nublado com chuva e
trovoadas</legendanoite>
</tempo>
A Expressão a Seguir seleciona todos os elementos
legendanoite que contenham o atributo
id="14"
/boletim/municipio/dia1/tempo/legendanoite[@id="14"]
<legendanoite id="14" icone="14.gif">nublado com chuva e
trovoadas</legendanoite>
As expressões são muito variadas, elas podem retornar elementos e também valores de atributos.Existem funções para as expressões e podem ser encontradas com maiores detalhes em http://www.w3schools.com/xpath/xpath_syntax.asp
Na Pratica com o XPath
"Continuando o
código
Dim xmlNav As XPathNavigator
" Cria o
Objeto da Classe Navigator que tem métodos para a navegação
"Tratamento de
Erros
Try
xmlNav =
xpathDoc.CreateNavigator()
Catch ex As XPathException
Response.Write(ex.Message)
Catch ex As Exception
Response.Write(ex.Message)
End Try
Dim xmlNI As XPathNodeIterator
" Criação do Objeto da Classe XPathNodeIterator
xmlNI =
xmlNav.Select("/boletim/municipio[@id=4106902]/dia2/@data")
" Solicitação da pesquisa, neste caso estamos solicitando o
atributo data do elemento dia2
"que é um elemento filho do elemento
municipio que tem um atributo que colocamos como
"critério
id=4106902 e é um elemento filho do elemento nó boletim.
"Obs: Os atributos são representados pelo simbolo
@.
While (xmlNI.MoveNext())
Response.Write(xmlNI.Current.Value())
End While
"
Outras expressões que poderiam ser utilizadas
seriam:
""/boletim/municipio[@id=" & id &
"]/dia2/@data"
""/boletim/municipio[@id=" & id &
"]/dia2/@diadasemana"
""/boletim/municipio[@id=" & id &
"]/dia3/tempo/legendadia/@icone"
""/boletim/municipio[@id=" & id &
"]/dia3/tempo/legendadia"
""/boletim/municipio[@id=" & id &
"]/dia3/temperatura/min"
""/boletim/municipio[@id=" & id &
"]/dia3/temperatura/max"
""/boletim/municipio[@id=" & id &
"]/dia3/vento/direcao"
""/boletim/municipio[@id=" & id &
"]/dia3/vento/intensidade"
""/boletim/municipio[@id=" & id &
"]/dia3/visibilidade"
Tudo bem, fizemos a pesquisa em um XML mas até agora a pesquisa retornou um atributo ou um valor de um elemento. Mas como fazer para buscar um elementoe seus filhos e percorrê-los??
xmlNI =
xmlNav.Select("/boletim/municipio")
"Buscamos todos os
elementos municipio
While (xmlNI.MoveNext())
"Percorremos cada um dos elementos municipio
retornados
If xmlNI.Current.HasAttributes Then
" A Propriedade
Current do objeto xmlNI é do tipo XmlPathNavigator e esta classe contém
"diversos métodos para mover em um nó e de informações. O Método
HasAttributes é do
"tipo boolean e indica se há atributos neste
elemento
xmlNI.Current.MoveToFirstAttribute()
"Se houver atributos vamos percorrer cada um deles e escrever na
tela seu valor
Do
Response.Write(xmlNI.Current.Name & ":" & xmlNI.Current.Value &
"<br>")
Loop While xmlNI.Current.MoveToNextAttribute
End If
End
While
Como foi visto acima conseguimos resgatar
informações dos atributos de um elemento.
Para percorrer um elemento filho
você terá que utilizar ós métodos próprios para
isto. Eis uma tabela com os
principais.
Método
Que Faz?
MoveToFirst()
Move ao primeiro elemento/atributo do nó
atual
MoveToFirstAttribute()
Move ao primeiro atributo do nó atual. Verifique se onó
atual tem algumatributo antes.
MoveToFirstChild()
Move ao primeiro elemento filho do nó atual. Verifique se
o nó atual tem algum elemento filho antes.
MoveToNext()
Move ao próximo elemento/atributo/valor do nó
atual
MoveToNextAttribute()
Move ao atributo seguinte.
MoveToNextChild()
Nao disponível! Use MoveToNext() preferivelmente.
MoveToParent()
Move ao pai do nó atual. Chame este método para retornar o
cursor à posição original após ter processado seus atributos ou para percorrer
elementos filhos.
MoveToPrevious()
Move ao elemento/atributo/valor precedente do nó
atual.
MoveToRoot()
Move ao nó raiz.
O XPath é
o namespace definitivoque procurávamos para fazer acesso em XML. O .NET só
facilitou as coisas mas outras linguagens também podem usufluir de suas
funcionalidades. Espero queeste artigopossaajudar à comunidade
Dotnet.
A classe completa para acesso aos dados de previsão do tempo
estão disponíveis aqui. ( Faça o download
Simepar.vb.txt )
Aguardo comentários e até o próximo artigo