Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

FabianoSouza

Ler arquivo XML usando critérios

Recommended Posts

Preciso fazer algo similar a um SELECT...WHERE, mas num arquivo XML. Vejam o código.

 

set docXML = server.createObject("Microsoft.XMLDOM")
docXML.async = false

docXML.load(server.mappath("/App/CLIENTES/Menu/1002.xml"))

set registro = docXML.getElementsByTagName("permissoes_do_perfil")
set registro = docXML.getElementsByTagName("item")

for i=0 to registro.length - 1
vtitulo = registro.item(i).selectSingleNode("./modulo").text
vdescricao = registro.item(i).selectSingleNode("./codigo_modulo").text
vsistema = registro.item(i).selectSingleNode("./sistema").text
vcodsistema = registro.item(i).selectSingleNode("./cod_sistema").text
vservico = registro.item(i).selectSingleNode("./servico").text
vcodservico = registro.item(i).selectSingleNode("./cod_servico").text

response.write "Modulo: " & vtitulo & "<BR>Cod. modulo: " & vdescricao & "<BR> Sistema: " & vsistema & "<BR>Cod. sistema: " & vcodsistema & "<BR>Servico: " & vservico & "<BR>Cod. servico: " & vcodservico & ""
response.Write "<BR><BR>"
next

 

 

Preciso usar uma espécie de WHERE para que a leitura ocorra onde o nó modulo for igual a "x" e osistema for igual a "y".

 

Um help por caridade nesta madrugada de sábado heheh

Compartilhar este post


Link para o post
Compartilhar em outros sites

você quer selecionar determinado node ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Preciso fazer algo similar a um SELECT...WHERE, mas num arquivo XML. Vejam o código.

 

set docXML = server.createObject("Microsoft.XMLDOM")
docXML.async = false

docXML.load(server.mappath("/App/CLIENTES/Menu/1002.xml"))

set registro = docXML.getElementsByTagName("permissoes_do_perfil")
set registro = docXML.getElementsByTagName("item")

for i=0 to registro.length - 1
vtitulo = registro.item(i).selectSingleNode("./modulo").text
vdescricao = registro.item(i).selectSingleNode("./codigo_modulo").text
vsistema = registro.item(i).selectSingleNode("./sistema").text
vcodsistema = registro.item(i).selectSingleNode("./cod_sistema").text
vservico = registro.item(i).selectSingleNode("./servico").text
vcodservico = registro.item(i).selectSingleNode("./cod_servico").text

response.write "Modulo: " & vtitulo & "<BR>Cod. modulo: " & vdescricao & "<BR> Sistema: " & vsistema & "<BR>Cod. sistema: " & vcodsistema & "<BR>Servico: " & vservico & "<BR>Cod. servico: " & vcodservico & ""
response.Write "<BR><BR>"
next

 

 

Preciso usar uma espécie de WHERE para que a leitura ocorra onde o nó modulo for igual a "x" e osistema for igual a "y".

 

Um help por caridade nesta madrugada de sábado heheh

 

 

Este arquivo têm vários registros...como se fosse um bd. Então quero listar os registros que atenderem a certo critério (como se fosse o WHERE de uma query).

 

 

No caso seria onde o node modulo e o node sistema tiverem determinados valores (que virão de variáveis). Creio que assim o resultado final serão as "linhas" filtradas pelo critério que informei, mas com todos os nondes (que seriam os campos numa analogia com BD).

 

.

Compartilhar este post


Link para o post
Compartilhar em outros sites

faz assim:

 

  ' ################################################################################################
       ' pegaValorNode
       ' Retorna o valor específico de um Node de um XML
       Function pegaValorNode(xml, node)
               Dim objXml
               Set objXml = Server.CreateObject("MSXML2.DOMDocument")

               objXml.loadXML(xml)

               If (TypeName(objXml) = "DOMDocument") Then
                       If (objXml.GetElementsByTagName(node).length <> 0) Then
                               pegaValorNode = objXml.selectSingleNode("//" & node).text
                       Else
                               pegaValorNode = ""
                       End If
               Else
                       pegaValorNode = ""
               End If

               Set objXml = Nothing
       End Function

 

Utilizando a função:

 

'objSrvHTTP.responseText: retorno utilizando MSXML2.XMLHTTP.3.0

xml = objSrvHTTP.responseText

'nome do nó: nó a ser recuperado

retorno_codigo_erro = pegaValorNode(xml,"nome do nó")

Compartilhar este post


Link para o post
Compartilhar em outros sites

faz assim:

 

  ' ################################################################################################
       ' pegaValorNode
       ' Retorna o valor específico de um Node de um XML
       Function pegaValorNode(xml, node)
               Dim objXml
               Set objXml = Server.CreateObject("MSXML2.DOMDocument")

               objXml.loadXML(xml)

               If (TypeName(objXml) = "DOMDocument") Then
                       If (objXml.GetElementsByTagName(node).length <> 0) Then
                               pegaValorNode = objXml.selectSingleNode("//" & node).text
                       Else
                               pegaValorNode = ""
                       End If
               Else
                       pegaValorNode = ""
               End If

               Set objXml = Nothing
       End Function

 

Utilizando a função:

 

'objSrvHTTP.responseText: retorno utilizando MSXML2.XMLHTTP.3.0

xml = objSrvHTTP.responseText

'nome do nó: nó a ser recuperado

retorno_codigo_erro = pegaValorNode(xml,"nome do nó")

 

 

Hmm..estou olhando aqui e me parece que esta função não vai atingir meu objtivo. Pois não há onde informar o valor para "filtar" os itens.

 

Por exemplo. O node servico é um dos nós que quero usar para filtrar.

vservico = registro.item(i).selectSingleNode("./servico").text

.

 

Quero que o loop leia todos os itens do arquivo XML onde o valor do node servico seja igual a "minha_variavel". Não entendi como a função fará isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

isso você consegue fazer como menos linhas de código usando ASP.Net, ele disponibiliza todas as funcionalidades necessarias para leitura e escrita de um xml de forma mais descomplicada. Basta você importar a classe System.Xml.

 

em ASP.Net uso assim:

 

private string ObterEndereco(int id)
       {
           System.Xml.XmlDocument xmlDom = new System.Xml.XmlDocument();
           xmlDom.Load(this.Page.Server.MapPath("~/XmlXPath.xml"));
           xmlDom.InnerXml = xmlDom.InnerXml.Replace(@"<kml xmlns=""http://earth.google.com/kml/2.0"">", "<kml>");

           System.Xml.XmlNode node = xmlDom.SelectSingleNode("//Placemark[@id='p" + id.ToString() + "']/address");

           string retorno = string.Empty;
           if (node != null)
           {
               retorno = node.InnerText;
           }

           return retorno;
       }

 

mas em ASP você pode usar o Xpath, XpathFilterString.value tipo:

 

Crie a seguinte página HTML para exibir dados XML:

 

<HTML>
<HEAD>
<TITLE></TITLE>

<script language="VBSCRIPT">

function  btnPlain_onClick()
   xslPeople.innerText = source.documentelement.xml 
   textarea1.innerText = xmlsource
end function 

function  btnTable_onClick()
   xslPeople.innerhtml  = source.transformnode(styletable.xmldocument)     
end function 

</script>

<xml id="xmlsource" src="xpath.asp">
</xml>

<xml id="xslsource" src="xpath.xsl">
</xml>


<script ID=clientEventHandlersVBS LANGUAGE=vbscript>
<!--

Sub applyxsl_onclick    
   dim xmldom 
   dim xsldom
   set xmldom = CreateObject("msxml2.domdocument")
   set xsldom = CreateObject("msxml2.domdocument")
   xmldom.async =false
   xsldom.async =false
   xmldom.loadXML(xmlsource.xml)    
   xsldom.loadXML(xslsource.xml)
   htmlout.innerHTML = xmldom.transformNode(xsldom)    
End Sub

Sub applyfilter_onclick    

   dim oHttp
   dim xmldom
   dim txtResult         
   dim txtRequestString 
   set oHttp = CreateObject("MSXML2.XMLHTTP")
   set xmldom = CreateObject("msxml2.domdocument")
   txtRequestString = "xpath.asp?XPathRequest=" & XpathFilterString.value         
   oHttp.open "GET",txtRequestString , false 
   oHttp.send 

   xmldom.async =false    
   xmldom.loadXML( oHttp.responseText  )
   htmlout.innerText  = xmldom.xml

End Sub

-->
</SCRIPT>
</HEAD>
<BODY>
<INPUT id="applyxsl" name="applyxsl" type="button" value="Apply XSL">
<INPUT type="text" id="XpathFilterString" name="XpathFilterString" style="width=40%" >
<INPUT id="applyfilter" name="applyfilter" type="button" value="XPath with Parameter">
<div id="htmlout"></div>
</BODY>
</HTML>

 

 

Criar arquivo de xpath.xsl e cole o seguinte código no arquivo:

 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/TR/WD-xsl"  >
   <xsl:template match ="//" >
           <html>
               <body topmargin="3" leftmargin="3" marginheight="0" marginwidth="0" bgcolor="#ffffff">
                   <table border="0" cellpadding="1" cellspacing="1" width="100%" style="color: black; font-family: arial; font-size: 12pt.;font-weight: 500" >
                       <thead>
                           <tr bgColor="#336699" align="center">
                               <th><STRONG><FONT color="white" size="2">Customer ID</FONT></STRONG></th>
                               <th><STRONG><FONT color="white" size="2">Order ID</FONT></STRONG></th>
                               <th><STRONG><FONT color="white" size="2">Order Date</FONT></STRONG></th>                            
                           </tr>
                       </thead>
                       <xsl:apply-templates  select ="root" />
                   </table>
               </body>
           </html>
   </xsl:template>
   <xsl:template match ="root">

           <xsl:for-each select="Customers">           
               <xsl:apply-templates select ="CustOrder" />
           </xsl:for-each>
   </xsl:template>

   <xsl:template match="CustOrder">
       <tr>
           <td bgColor="#F0F0F0"><xsl:value-of select="@CustomerID" /></td>
           <td bgColor="#F0F0F0"><xsl:value-of select="@OrderID" /></td>
           <td bgColor="#F0F0F0"><xsl:value-of select="@OrderDate" /></td>
       </tr>
   </xsl:template>    
</xsl:stylesheet>

 

 

 

 

XPath filtra um ponto específico dentro do documento XML. Para testar a consulta, você pode inserir as seguintes consultas XPath na caixa de texto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hmm...bem interessante. Embora minha necessidade seja algo mais simples creio que este código será muito útil numa outra parte do site. Muito bom.

 

Entretanto neste caso imagino que um ajuste no loop do meu código deva resolver. Veja meu código.

 

'Lê arquivo XML do menu esquerdo-------------------------------------------------------------------------
Dim docXML, registro, i, vservico, vcodservico, viconeservico, vpastaservico
set docXML = server.createObject("MSXML2.DOMDocument.4.0")
docXML.async = false

docXML.load(server.mappath("CLIENTES/perfis/"&var_codconta&"/"&var_perfil&""))

set registro = docXML.getElementsByTagName("permissoes_do_perfil")
set registro = docXML.getElementsByTagName("item")

for i=0 to registro.length - 1

vservico = registro.item(i).selectSingleNode("./servico").text
vcodservico = registro.item(i).selectSingleNode("./cod_servico").text
viconeservico = registro.item(i).selectSingleNode("./icone_servico").text
vpastaservico = registro.item(i).selectSingleNode("./pasta_servico").text

response.Write "<div class=menuLtLinha onclick=goto(this.id) id=" : Response.Write(vpastaservico) :response.Write(">")  
response.Write "<div class=menuLtItem>" 
response.Write "<div class=menuLtIcone>"
response.Write("<img src=../../../../Imagens/"): response.write (viconeservico):response.Write(">")  
response.Write "<!-- fim .menuLtIcone--></div>"
response.write (vservico) 
response.Write "<!-- .fim menuLtItem--></div>" 
response.Write "<!-- .fim menuLtLinha--></div>" 

next

 

 

 

Creio que aqui

for i=0 to registro.length - 1

possa ser feito algo para que o loop leia somente onde o node servico, por exemplo, seja igual a "Cadastro de clientes." Acho que o segredo está no na forma de criar o loop. Estou tentando algumas coisas aqui...mas ainda sem sucesso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

aquele code do post #4 não faz isso...

Compartilhar este post


Link para o post
Compartilhar em outros sites

execute est função e veja o resultado que ela te traz.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Criei os dois arquivos. Mas não entendi o que deveria acontecer. O arquivo xpath.html exibe uma caixa de texto e dois botões (que ao clicar não acontece nada).

 

Este arquivo tem em seu código xpath.asp. Este arquivo ASP seria o que?

Compartilhar este post


Link para o post
Compartilhar em outros sites

acesse aqui

Compartilhar este post


Link para o post
Compartilhar em outros sites

lendo de outro server olha este post

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa! Olá pessoal.

 

Gilberto, dei uma olhada na sua sugestão. Vou testar.

 

xanburzum, desculpe meu pouco conhecimento. Veja que segui o passo a passo.

 

-Crei o arquivo ASP (xpath.asp)

-Criei um diretório e coloquei o caminho no código ASP (ficou C:\VirtualRoot\schema)

-Criei o arquivo CustomerOrder.xdr e coloquei dentro deste diretório schema. Este arquivo tem o código XML.

-Criei o HTML

-Criei o arquivo xpath.xsl.

 

Rodei a página HTML ecliquei sobre os dois botões. Era para acontecer o que? Não está acontecendo nada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

você não pode usar o System.Xml.Linq do ASP.Net ? ficaria mais simples. Mas em ASP como eu falei precisa usar o xPath

selectNodes, tipo:

xmlDoc.selectNodes("/catalogo/dvd[preco>50.80]/preco")

para um XML com essa estrutura:

 

<?xml version="1.0" encoding="ISO-8859-1"?>
 <catalogoo>
   <dvd pais="USA">
     <titulo>Empire Burlesque</titulo>
     <artista>Bob Dylan</artista>
     <preco>10.90</preco>
   </cd>
   <cd pais="UK">
     <titulo>Hide your heart</titulo>
     <artista>Bonnie Tyler</artista>
     <preco>9.90</preco>
   </dvd>
   <dvd pais="USA">
     <titulo>Greatest Hits</titulo> 
     <artista>Dolly Parton</artista> 
     <preco>9.90</preco> 
   </dvd>
 </catalogo>

Compartilhar este post


Link para o post
Compartilhar em outros sites

você não pode usar o System.Xml.Linq do ASP.Net ? ficaria mais simples. Mas em ASP como eu falei precisa usar o xPath

selectNodes, tipo:

xmlDoc.selectNodes("/catalogo/dvd[preco>50.80]/preco")

para um XML com essa estrutura:

 

<?xml version="1.0" encoding="ISO-8859-1"?>
 <catalogoo>
   <dvd pais="USA">
     <titulo>Empire Burlesque</titulo>
     <artista>Bob Dylan</artista>
     <preco>10.90</preco>
   </cd>
   <cd pais="UK">
     <titulo>Hide your heart</titulo>
     <artista>Bonnie Tyler</artista>
     <preco>9.90</preco>
   </dvd>
   <dvd pais="USA">
     <titulo>Greatest Hits</titulo> 
     <artista>Dolly Parton</artista> 
     <preco>9.90</preco> 
   </dvd>
 </catalogo>

 

Este lance do System.Xml.Linq não funciona no ASP clássico??

 

 

Tem umas coisas legais sobre XML aqui

 

To tentando isso.

 

Meu XML está assim

<ComponentesASP>
<permissoes_do_perfil>

<item>
<modulo>Desenvolvimento Organizacional</modulo>
<diretorio_modulo>/App/DO/</diretorio_modulo>
<codigo_modulo>8</codigo_modulo>
<icone_modulo>ico067.gif</icone_modulo>
<sistema>Treinamento</sistema>
<diretorio_sistema>/App/DO/treinamento/</diretorio_sistema>
<cod_sistema>53</cod_sistema>
<icone_sistema>ico264.gif</icone_sistema>
<servico>Eventos</servico>
<pasta_servico>/App/DO/treinamento/eventos/</pasta_servico>
<cod_servico>1</cod_servico>
<icone_servico>ico058.gif</icone_servico>
</item>

</permissoes_do_perfil>
</ComponentesASP>

 

Quero filtrar por

diretorio_modulo

Fiz assil

 

var_diretorio = registro.item(iLoop).selectSingleNode("./permissoes_do_perfil/item[diretorio_modulo='Administrador']").text

 

Está retornando

 

erro '800a01a8'

 

 

 

Objeto necessário: '[object]'/App/Includes/header.asp, linha 73

 

 

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boas, eu fiz algo assim e funciona muito bem.

 

Deixo aqui a ligacao com os selects, espero que possa ajudar.

 


<% Option Explicit %>
<html>
<body>
<%
'define local e ficheiro
var_fic_exc="myxls/"&ficheiro.xls


'abre o ficheiro		
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};"& "DBQ=" & Server.MapPath(""&var_fic_exc&"") & ";"

' procura os campos especificos
strSQL  = "SELECT * FROM [A17:A23]"
strSQL1 = "SELECT * FROM [E17:E23]"
strSQL2 = "SELECT * FROM [G17:G23]"
strSQL7 = "SELECT * FROM [K17:K23]"
strSQL8 = "SELECT * FROM [L17:L23]"

strSQL3  = "SELECT * FROM [A27:A130]"
strSQL4  = "SELECT * FROM [E27:E130]"
strSQL5  = "SELECT * FROM [G27:G130]"
strSQL6  = "SELECT * FROM [K27:K130]"
strSQL9  = "SELECT * FROM [L27:L130]"
strSQL10 = "SELECT * FROM [b10:B11]"

Set objRS=objConn.Execute(strSQL)
Set objRS1=objConn.Execute(strSQL1)
Set objRS2=objConn.Execute(strSQL2)
Set objRS7=objConn.Execute(strSQL7)
Set objRS8=objConn.Execute(strSQL8)

Set objRS3=objConn.Execute(strSQL3)
Set objRS4=objConn.Execute(strSQL4)
Set objRS5=objConn.Execute(strSQL5)
Set objRS6=objConn.Execute(strSQL6)
Set objRS9=objConn.Execute(strSQL9)

Set objRS10=objConn.Execute(strSQL10)



Compartilhar este post


Link para o post
Compartilhar em outros sites

não o System.Xml.Linq, só funciona em .Net

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Razs. Estou testando sua sugestão. Por hora está dando erro 500. A única alteração que fiz foi em

 

var_fic_exc="myxls/"&ficheiro.xls

para

var_fic_exc="&perfis.xls

 

Pois a planilha está no mesmo diretório que a página .asp.

 

O que acha que está faltando?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.