In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Leer archivo XML (Solucionado)

Foro público de Xailer en español
ryder1912
Posts: 12
Joined: Thu Jul 09, 2015 8:17 pm

Leer archivo XML (Solucionado)

Postby ryder1912 » Sun Apr 15, 2018 5:09 am

Buenas a todos, estoy tratando de leer un archivo xml (.rta) pero no me sale, ya q no sé como recorrer el archivo. La idea es obtener los registros, insertarlos en un array, y que quede de esta manera:
ID | Bandera
11 AXION
12 BLANCA
2 ESSO
10 OIL
9 PDV SUR
4 PETROBRAS

Este es el archivo xml (es un archivo.rta q se puede abrir con el bloc de notas), en la que cada tag <BanderasDTO> representa un registro con el id de la bandera y el nombre.

Code: Select all

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfBanderasDTO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BanderasDTO>
    <IdBandera>11</IdBandera>
    <Nombre>AXION                                   </Nombre>
  </BanderasDTO>
  <BanderasDTO>
    <IdBandera>12</IdBandera>
    <Nombre>BLANCA                                  </Nombre>
  </BanderasDTO>
  <BanderasDTO>
    <IdBandera>2</IdBandera>
    <Nombre>ESSO                                    </Nombre>
  </BanderasDTO>
  <BanderasDTO>
    <IdBandera>10</IdBandera>
    <Nombre>OIL                                     </Nombre>
  </BanderasDTO>
  <BanderasDTO>
    <IdBandera>9</IdBandera>
    <Nombre>PDV SUR                                 </Nombre>
  </BanderasDTO>
  <BanderasDTO>
    <IdBandera>4</IdBandera>
    <Nombre>PETROBRAS                               </Nombre>
  </BanderasDTO>
</ArrayOfBanderasDTO>


Este es el código, q está basado en el ejemplo BTS de samples. Con el XMLReadArray puedo obtener primer registro pero no me sirve.
Con el XMLReadSection intente hacer algo parecido metiendo dos while y q recorra todo pero no me sale ya q se repite el primer el registro (o nodo), necesito una mano en ese método.

Code: Select all

#include "Xailer.ch"
#include "ExStruct.ch"
#include "hbxml.ch"

CLASS TFormPpal FROM TForm

   COMPONENT oBevel1
   COMPONENT oBevel2
   COMPONENT btAbrirArch
   COMPONENT oFileOpenDlg1
   COMPONENT oLabel1
   COMPONENT oBrw

   DATA cIniFile, cXMLFile
   DATA aHeaders, oRecord

   METHOD CreateForm()
   METHOD FormInitialize( oSender )
   METHOD btAbrirArchClick( oSender )
   METHOD XMLRestore()
   METHOD XMLReadArray( oMIter, cSection )
   METHOD XMLReadSection( oMIter, cSection )

ENDCLASS

#include "FormpPpal.xfm"

//------------------------------------------------------------------------------

METHOD FormInitialize( oSender ) CLASS TFormPpal

   STRUC ::oRecord   // Registros de BanderasDTO
         MEMBER IdBandera   AS NUMBER INIT 0
         MEMBER Nombre      AS STRING INIT ""
   END STRUC

   ::aHeaders:={'ID', 'Banderas'}

RETURN Nil

//------------------------------------------------------------------------------

METHOD btAbrirArchClick( oSender ) CLASS TFormPpal
local x
   if ::oFileOpenDlg1:Execute() .and. File(::oFileOpenDlg1:cFullFileName)
      x:=0
      ::oLabel1:cText:=::oFileOpenDlg1:cFullFileName
      ::cXMLFile :=::oFileOpenDlg1:cFullFilename()
      ::XMLRestore()
   else
      ::oLabel1:cText:=''
   endif
RETURN Nil

//------------------------------------------------------------------------------

METHOD XMLRestore() CLASS TFormPpal

   LOCAL oDoc, oMIter, oNode, n
   LOCAL aData := {}, aBanderas:={} , aSeccion:={}
   LOCAL hFile

   hFile := FOpen( ::cXMLFile )

   IF hFile > -1
      oDoc   := TXMLDocument():New( hFile )
      oMIter := TXMLIteratorScan():New( oDoc:oRoot )


      //Aadd( aBanderas, ::XMLReadArray( oMIter, "BanderasDTO" ) )
      aBanderas := ::XMLReadSection( oMIter, "BanderasDTO" )
      n:=0
      FClose( hFile )
   Endif
   ::cText := Application:cTitle + "  -  " + FileShortName( ::cXMLFile )
   ::oBrw:SetArray( aBanderas, ::aHeaders, .T. )

RETURN NIL

//------------------------------------------------------------------------------

METHOD XMLReadArray( oMIter, cSection ) CLASS TFormPpal

   LOCAL aData := {}, oIter, oNode

   oNode  := oMIter:Find( cSection )
   IF oNode != NIL
      oIter := TXMLIterator():New( oNode )
      oNode := oIter:Next()
      DO WHILE oNode != NIL
         Aadd( aData, oNode:cData )
         oNode := oIter:Next()
      ENDDO
   ENDIF

RETURN aData

//------------------------------------------------------------------------------

METHOD XMLReadSection( oMIter, cSection ) CLASS TFormPpal
 LOCAL oXmlNode, oXmlIter1, oNode1, oXmlIter2, oNode2
 LOCAL aData := {}, aReg:={}
 
    oXmlNode := oMIter:Find( cSection )
   oXmlIter1 := TXmlIterator():new( oXmlNode )
        oNode1    := oXmlIter1:getNode()
   
   While oNode1 != NIL
          oXmlIter2 := TXmlIteratorScan():new( oNode1 )
          oNode2    := oXmlIter2:Next()
               While  oNode2 != NIL
                  ::oRecord:SetValue( oNode2:cName, oNode2:cData )
                  Aadd( aReg, oNode2:cData)
                  oNode2 := oXmlIter2:Next()
       EndDo
           Aadd( aData, ::oRecord:GetValues() )
           oNode1    := oXmlIter1:Next()
      EndDo

RETURN aData


Bueno adjunto el ejemplo con el archivo .rta, por si alguien quiere probarlo, saludos.
Attachments
prueba XML.zip
(2.8 KiB) Downloaded 16 times
Last edited by ryder1912 on Tue Apr 17, 2018 7:32 pm, edited 1 time in total.
ftwein
Posts: 29
Joined: Mon Oct 22, 2007 5:17 pm

Re: Leer archivo XML

Postby ftwein » Tue Apr 17, 2018 3:24 pm

Buenas,

Por favor intente con el código abajo.

Note oDoc en lugar de oMIter.

Fausto Di Creddo Trautwein

Code: Select all

METHOD XMLRestore() CLASS TFormPpal

   LOCAL oDoc, oMIter, oNode, n
   LOCAL aData := {}, aBanderas:={} , aSeccion:={}
   LOCAL hFile

   hFile := FOpen( ::cXMLFile )

   IF hFile > -1
      oDoc   := TXMLDocument():New( hFile )
      //oMIter := TXMLIteratorScan():New( oDoc:oRoot )

      //Aadd( aBanderas, ::XMLReadArray( oMIter, "BanderasDTO" ) )
      aBanderas := ::XMLReadSection( oDoc, "BanderasDTO" )
      n:=0
      FClose( hFile )
   Endif
   ::cText := Application:cTitle + "  -  " + FileShortName( ::cXMLFile )
   ::oBrw:SetArray( aBanderas, ::aHeaders, .T. )
RETURN NIL

METHOD XMLReadSection( oDoc, cSection ) CLASS TFormPpal

   LOCAL oXmlNode, oXmlIter1, oNode1
   LOCAL aData := {}, aReg:={}

   oXmlNode := oDoc:FindFirst( cSection )
     
      While oXmlNode != Nil
   
         oXmlIter1 := TXmlIterator():new( oXmlNode )
         oNode1    := oXmlIter1:Next()
   
         While oNode1 != NIL
   
            ::oRecord:SetValue( oNode1:cName, oNode1:cData )
            Aadd( aReg, oNode1:cData)
            oNode1 := oXmlIter1:Next()

         EndDo
     
         Aadd( aData, ::oRecord:GetValues() )
         oXmlNode    := oDoc:FindNext()
      
      EndDo

RETURN aData
ryder1912
Posts: 12
Joined: Thu Jul 09, 2015 8:17 pm

Re: Leer archivo XML (Solucionado)

Postby ryder1912 » Tue Apr 17, 2018 7:30 pm

Buenas, funcionó. Ya lo habia hecho funcionar pero con 3 whiles, sin modificar el metodo restoreXML, y era medio engorroso.
Por las dudas dejo el codigo abajo. La alternativa del amigo ftwein es mejor, gracias y saludos.

Code: Select all

// Sin modificar el metodo RestoreXML
METHOD XMLReadSection( oMIter, cSection ) CLASS TFormPpal
LOCAL oXmlNode, oXmlIter1, oNode1, oXmlIter2, oNode2
LOCAL aData := {}, aReg:={}

   oXmlNode := oMIter:Find( cSection )

   While oXmlNode != NIL
      oXmlIter1 := TXmlIterator():new( oXmlNode )
      oNode1    := oXmlIter1:getNode()

      While oNode1 != NIL

         oXmlIter2 := TXmlIteratorScan():new( oNode1 )
         oNode2    := oXmlIter2:Next()
         While oNode2 != NIL
            ::oRecord:SetValue( oNode2:cName, oNode2:cData )
            Aadd( aReg, oNode2:cData)
            oNode2 := oXmlIter2:Next()
         EndDo
         Aadd( aData, ::oRecord:GetValues() )
         oNode1:=Nil

      EndDo
      oXmlNode:= oXmlNode:oNext()
    EndDo

RETURN aData

Return to “Spanish”

cron