FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Probelmas al recorrer un árbol XML :next()
Posts: 107
Joined: Tue Sep 15, 2009 07:52 AM
Probelmas al recorrer un árbol XML :next()
Posted: Thu Apr 29, 2010 12:27 PM
¡Hola a todos!

¿Podría alguien ayudarme con el siguiente problema que me mastica el cerebro desde hace ya varios días usando xHarbour y XML?
La categoría se muestra perfectamente pero las hojas del árbol XML no se muestran correctamente:

Usando esta esructura XML simple (el resto es lo mismo incluyendo el encabezado que es una estructura XML válida)
Code (fw): Select all Collapse
<images>
    <category name="Bowling History">
        <image>
            <description>pinsetting cirvca 1932</description>
            <imgsrc>images/album1/1.jpg</imgsrc>
        </image>
        <image>
            <description>Hand score bowler</description>
            <imgsrc>images/album1/10.jpg</imgsrc>
        </image>
    </category>
</images>

Programa que extrae (o intenta extraer) la estructura:

Code (fw): Select all Collapse
#include "fivewin.ch"
#include "hbxml.ch"

function main()
local cFile:="data.xml", cString 
LOCAL oXmlDoc := TXmlDocument():new()
LOCAL oCurrent, oScan, oCatego, oIterator, oImages, oItems

cString:=memoread( cFile )
IF !( len(cString) > 0 )
  MSGWAIT ("No hay fichero XML")
  RETURN .F.
ENDIF

oXmlDoc:=TXmlDocument( cString, HBXML_STYLE_NOESCAPE )
if !( oXmlDoc:nError==HBXML_ERROR_NONE )
  Msgwait ("XML file parsing error " + HB_XmlErrorDesc(oXmlDoc:nError))
  RETURN .F.
endif

oScan:=TXmlIteratorScan():New( oXmlDoc:oRoot )
oCatego:=oScan:find( "category" )
if oCatego == NIL
   msgwait ("no hay categorías")
   return NIL
endif

do while oCatego<>NIL

  if HHasKey( oCatego:aAttributes, "name" )
     ? "category : " + oCatego:aAttributes["name"]
  else
     ? "no hay descripción de la categoría"  &&Esto funciona bien para todas la categorías de la estructura
  endif
  
  oIterator:=TXmlIterator():New( oCatego )
  oImages:=oIterator:find("image")

  do while oImages<>NIL

     oItems:=TXmlIterator():New( oImages )
     oCurrent:=oItems:Next()
     do while oCurrent<>nil
        IF oCurrent:cName<>NIL
           IF alltrim(oCurrent:cName) == "description"
             ? oCurrent:cName  &&pasa por aquí 12 veces aunque solo tengo 5 imágenes
             ? oCurrent:cData  &&muestra datos vacíos aunque si hay datos
           ENDIF
           IF alltrim(oCurrent:cName) == "imgscr"
             ? oCurrent:cName  &&no muestra datos, pero sí que los hay
             ? oCurrent:cData  && no muestra datos, pero sí que los hay
           ENDIF
        ENDIF
       
        oCurrent:=oItems:Next()
     enddo

     oImages:=oIterator:next()
  enddo

  oCatego:=oScan:next()
  
enddo

return NIL


Las categorías se muestran correctamente pero la descripción e imagines (hojas) no (dónde reside el problema). El lazo se ejecuta por lo menos el doble+1 de veces que el número de imágenes sin mostrar resultados. Si coloco un contador el lazo <image> obtengo el número de renglones de datos que hay entra cada marcador de categoría en lugar de los marcadores <image> </image> como debería ser (¿?¿?¿error? ¿Interpreto mal las instrucciones? ¿Qué pasa con:next()?)

También he intentado:

Code (fw): Select all Collapse
    oItems  := TXmlIteratorScan():new( oItems )
    oCurrent:= oItems:find( "description" )
             ? oCurrent:cName
             ? oCurrent:cData
    oCurrent:= oItems:find( "imgscr" )
             ? oCurrent:cName
             ? oCurrent:cData


En lugar del lazo interior con casi el mismo resultado y puesto que el lazo de <category> se ejecuta una vez por cada línea de datos se obtiene una pantalla llena de datos vacíos (ni siquiera se imprime la descripción que sí existe en todos los casos.

Gracias por toda ayuda que me puedan aportar.

Emiliano Llano Díaz
Posts: 107
Joined: Tue Sep 15, 2009 07:52 AM
Re: Probelmas al recorrer un árbol XML :next()
Posted: Thu Apr 29, 2010 01:20 PM

Se mejoró un poco sustituyendo TXmlIterator con TXmlIteratorScan. Por lo menos recorre el número apropiado de veces el bucle interno aunque no muestra aún los datos.

Continue the discussion