Leer nodo xml MSXML2.DomDocument

HMG en Español

Moderator: Rathinagiri

jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Leer nodo xml MSXML2.DomDocument

Post by jparada »

Estoy intentando leer nodos de un xml (factura electrónica México), lo estoy intentando con DocumentoXML := Win_oleCreateObject( "MSXML2.DomDocument" )

pero no sé cómo manejar los namespace, he buscado ejemplos con vba pero no logro encontrar mucha información, alguna sugerencia?.

Saludos,
Javier
martingz
Posts: 402
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico

Re: Leer nodo xml MSXML2.DomDocument

Post by martingz »

desarrolle un lector de xml de nominas, si te sirve te lo envio


saludos
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: Leer nodo xml MSXML2.DomDocument

Post by jparada »

Gracias Martín, creo que lo solucioné, eso sí, sin utilizar namespace en la declaración, porque no he sabido cómo implementar esa parte, tu visor incluye los namespace?, lo programaste con MSXML2.DomDocument o con alguna lib?.

Saludos,
Javier
martingz
Posts: 402
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico

Re: Leer nodo xml MSXML2.DomDocument

Post by martingz »

Utilizo la lib hbxml, me lee el xml completo de la nomina y con esta informacion genero los pdf's de la misma,



saludos
User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: Leer nodo xml MSXML2.DomDocument

Post by andyglezl »

Hola Javier
EDK puso un excelente ejemplo general, tal vez te sirva.
*-----------------------------------------------------------------------------
Hello
EDK put an excellent general example, maybe it will help you.


https://hmgforum.com/viewtopic.php?f=5& ... edk#p67951
Andrés González López
Desde Guadalajara, Jalisco. México.
User avatar
IMATECH
Posts: 188
Joined: Sun May 27, 2012 9:33 pm
Location: Brazil: Goiânia-GO.

Re: Leer nodo xml MSXML2.DomDocument

Post by IMATECH »

M., Ronaldo

By: IMATECH

Imation Tecnologia
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: Leer nodo xml MSXML2.DomDocument

Post by jparada »

Regreso con este tema porque para un proceso requiero leer muchos archivos xml, el tema es el siguiente:

con COM MSXML2.DomDocument tarda en leer poco más de 8000 archivos 1hora 20minutos aproximado, esto es parte del código:

Code: Select all

  oCFDI := Win_OleCreateObject( "MSXML2.DomDocument" )
  
  FOR EACH archivo IN hb_vfDirectory( rutaBase + "*.xml" )
    i++
       
    IF hb_vfExists( archivoXML := rutaBase + archivo[ F_NAME ] )         
      oCFDI:Load( archivoXML )

      ? "Procesando archivo: " + archivoXML + "  " + hb_NtoS(i) + " de " + hb_NtoS( Len( hb_vfDirectory( rutaBase + "*.xml" ) ) )
   
      olNode := oCFDI:selectSingleNode("//cfdi:Comprobante/cfdi:Complemento/tfd:TimbreFiscalDigital")
      IF hb_IsNil( olNode )
        ? hb_Utf8ToStr( "No se encontro el nodo TimbreFiscalDigital" )
      ELSE
        cUUID := olNode:getAttribute("UUID")

        hb_fNameSplit( archivoXML, NIL, @cName, @cExt )
        cXML  := cName + cExt        
      
        cQry := "INSERT INTO ArchivosXML (Archivo, UUID) " + ;
                "VALUES (" + ;                 
                convertToSQL( cXML ) + ", " + ;
                convertToSQL( cUUID ) + " )"

        BEGIN SEQUENCE WITH {|oError| BREAK( oError ) }
          oConnection:Execute( cQry )
        RECOVER USING oError
          ? "Error al actualizar datos en la tabla" +  E"\n" + oError:Description
          RETURN NIL
        END SEQUENCE

      ENDIF
        
    ENDIF
  
  NEXT  
Después de leer algunos artículos que mencionan que hay algunos problemas en el uso de memoria con createobject, pasé a la segunda opción que es utilizar la lib miniXML

Perooo para mi sorpresa utiliza más tiempo en leer la misma cantidad de archivos, el tiempo de lectura es de 2horas 20minutos :o, este es parte del código utilizando miniXML:

Code: Select all

FOR EACH cFile IN aDir
      IF hb_fileExists( cFileName := cPath + cFile[ F_NAME ]  )
        ? "Procesando archivo: " + cFileName + "  " + hb_NtoS( nFile ) + " de " + hb_NtoS( nLenDir )
    
        xmlBuffer := hb_memoRead( cFileName )
        body := mxmlLoadString( NIL, xmlBuffer, MXML_OPAQUE_CALLBACK )
    
        IF Empty( hTimbreFiscal := mxmlFindElement( body, body, "tfd:TimbreFiscalDigital",,, MXML_DESCEND ) )
          ? "Unable to find <tfd:TimbreFiscalDigital> elment in XML!" + hb_eol()        
          crearLogArchivo( cArchivoLog, "Archivo XML sin complemento! " + cFileName + hb_Eol(), @lNuevo )

          mxmlDelete( body )
        ELSE
          mxmlGetElement( hTimbreFiscal )
          cUUID := mxmlElementGetAttr( hTimbreFiscal, "UUID" )

          IF hb_IsNIl( cUUID )
            mxmlDelete( body )
            ? "No existe el atributo UUID!!!" + hb_eol()
          ELSE
            ? "UUID: " + cUUID
            ?
            hb_fNameSplit( cFileName, NIL, @cName, @cExt )
            cXMLFile  := cName + cExt

            cQry := "INSERT INTO ArchivosXML (Archivo, UUID) " + ;
                    "VALUES (" + ;
                    convertToSQL( cXMLFile ) + ", " + ;
                    convertToSQL( cUUID ) + " )"

            BEGIN SEQUENCE WITH {|oError| BREAK( oError ) }
              oConn:Execute( cQry )
            RECOVER USING oError
              ? "Error al actualizar datos en la tabla" + E"\n" + oError:Description
              RETURN NIL
            END SEQUENCE

            mxmlDelete( body )
          ENDIF
        ENDIF
  
      ENDIF   
  
      ++nFile
NEXT
Así que no como no estoy conforme con los resultados obtenidos, realicé un pequeño programa en el lenguaje C# y mi SORPRESA es que con la misma cantidad de archivos tarda el proceso SÓLO 20 segundos :o :o :o ... y la locura es que corrí el proceso para que leyera más de 150mil archivos y SÓLO tardó 5 minutos.

Así que tengo algunas preguntas:
- En los fragmentos de códigos de mis soluciones con Harbour, hay forma de refactorizar para obtener mejores resultados.
- Es justo comparar la velocidad de los procesos entre los lenguajes Harbour y C#.

Agradezco sus comentarios.

Saludos,
Javier
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: Leer nodo xml MSXML2.DomDocument

Post by jparada »

martingz wrote: Fri Apr 08, 2022 12:08 am Utilizo la lib hbxml, me lee el xml completo de la nomina y con esta informacion genero los pdf's de la misma,
Hola Martín, puedes compartir el código que utilizas para generar el pdf en base a la lectura del xml.

Saludos,
Javier
martingz
Posts: 402
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico

Re: Leer nodo xml MSXML2.DomDocument

Post by martingz »

Javier comparto el codigo, espero que te sea de utilidad


https://mega.nz/file/FoRG1IaY#sy6an4Sow ... hIFCk_G_nM


saludos
p.d. quedo pendiente ante cualquier comentario
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: Leer nodo xml MSXML2.DomDocument

Post by jparada »

Te agradezco Martín, he editado tu programa simplemente para correrlo, pero en mi caso ni siquiera encuentra el nodo comprobante

Code: Select all

archiv:= "C:\LeerNominaXML\nomina.xml"
hFile:=FOpen(archiv)
nvoarch:=hb_memoread(archiv)
oDocXML := TXmlDocument():New( nvoarch, HBXML_STYLE_NOESCAPE )
	
nHandle := FCREATE(archiv)
oNodo := oDocXML:FindFirst( "cfdi:Comprobante" )
tipocfd:="cfdi:"			
if oNodo == NIL
  ? "Error: el tipo de XML no es CFDI"
  return
endif
Alguna idea por qué?, es un xml nómina timbrado esta quincena.

Saludos,
Javier
Post Reply