Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-03-2022
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Leer un fichero XML

Buenas. Estoy implementando en una aplicación el poder cargar un fichero XML de recibos (Órdenes en formato ISO 20022 para emisión de Adeudos Directos SEPA) que se ha creado en otra máquina para mantener la BB.DD. actualizada.
El fichero tiene esta estructura:
Código:
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <CstmrDrctDbtInitn>
    <GrpHdr>
      <MsgId>8DA16A62A6954A25BBD465B830D0BD49</MsgId>
      <CreDtTm>2020-0730T09:56:43</CreDtTm>
      <NbOfTxs>15</NbOfTxs>
      <CtrlSum>580.00</CtrlSum>
      <InitgPty>
        <Nm>XXXXXXXXX</Nm>
        <Id>
          <OrgId>
            <Othr>
              <Id>XXXXXXXXXXXXX</Id>
            </Othr>
          </OrgId>
        </Id>
      </InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>15323007200955</PmtInfId>
      <PmtMtd>DD</PmtMtd>
      <NbOfTxs>15</NbOfTxs>
      <CtrlSum>580.00</CtrlSum>
      <PmtTpInf>
        <SvcLvl>
          <Cd>SEPA</Cd>
        </SvcLvl>
        <LclInstrm>
          <Cd>CORE</Cd>
        </LclInstrm>
        <SeqTp>RCUR</SeqTp>
      </PmtTpInf>
      <ReqdColltnDt>2020-08-02</ReqdColltnDt>
      <Cdtr>
        <Nm>XXXXXXXXXX</Nm>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <IBAN>ES533190XXXXXXXXXXXXX</IBAN>
        </Id>
      </CdtrAcct>
      <CdtrAgt>
        <FinInstnId>
          <BIC>BCOEESMM190</BIC>
        </FinInstnId>
      </CdtrAgt>
      <CdtrSchmeId>
        <Id>
          <PrvtId>
            <Othr>
              <Id>XXXXXXXXXXXXXXX</Id>
              <SchmeNm>
                <Prtry>SEPA</Prtry>
              </SchmeNm>
            </Othr>
          </PrvtId>
        </Id>
      </CdtrSchmeId>
      <DrctDbtTxInf>
        <PmtId>
          <EndToEndId>1150412</EndToEndId>
        </PmtId>
        [...]
      </DrctDbtTxInf>
      [...]
    </PmtInf>
    <PmtInf>
      [...]
    </PmtInf>
  </CstmrDrctDbtInitn>
</Document>
El primer trozo, entre las etiquetas <GrpHdr> y </GrpHdr>, es único para cada fichero. Luego puede haber un número indeterminado de grupos <PmtInf> - </PmtInf>. Para leer el fichero estoy haciendo esto:
Código:
XMLDocument->Active = true;
iNode0 = XMLDocument->DocumentElement;
iNode1 = iNode0->ChildNodes->FindNode("CstmrDrctDbtInitn");
if (iNode1 == NULL)
     continue;

iNode2 = iNode1->ChildNodes->FindNode("GrpHdr");
if (iNode2 == NULL)
     continue;

iNode2 = iNode1->ChildNodes->FindNode("PmtInf");
while (iNode2 != NULL)
{
     iNode3 = iNode2->ChildNodes->FindNode("PmtInfId");
     if (iNode3 != NULL && iNode3->IsTextElement)
     {
          cRefInt = (DOMString)iNode3->Text;
          etc.
     }
     iNode2 = iNode2->NextSibling();
}
La primera vez que entra encuentar correctamente la primera etiqueta PmtInf y ejecuta todo el código que sigue pero al llegar al NextSibling, aunque haya otra etiqueta PmtInf no la encuentra y se sale del bucle. Con la ayuda de Builder había entendido que NextSibling seguía ejecutándo el bucle mientars encontrara la etiqueta correspondiente y tal vez haya interpretado mal su funcionamiento.
Responder Con Cita
  #2  
Antiguo 01-03-2022
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Se me había olvidado añadir que para leer los sucesivos DrctDbtTxInf, de los que hay uno por cada recibo, estoy usando este código:
Código:
iNode3 = iNode2->ChildNodes->FindNode("DrctDbtTxInf");
while (iNode3 != NULL)
{
     iNode4 = iNode3->ChildNodes->FindNode("PmtId");
     if (iNode4 != NULL)
     {
          iNode5 = iNode4->ChildNodes->FindNode("EndToEndId");
          etc.
     }
     [Código para tratar la información del recibo]
     iNode3 = iNode3->NextSibling();
}
Y funciona a la perfección; quiero decir que lee todos los recibos que hay en el fichero.
Responder Con Cita
  #3  
Antiguo 02-03-2022
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Bueno, después de dos días dando vueltas y buscando información encontré una solución. No sé si será la mejor, pero funciona.

Hay que definir una variable IXMLNodeList y me ha quedado así:
Código:
IXMLNodeList *lstNodos;

ThousandSeparator = ',';
DecimalSeparator  = '.';

XMLDocument->Active = true;
iNode0 = XMLDocument->DocumentElement;
iNode1 = iNode0->ChildNodes->FindNode("CstmrDrctDbtInitn");
if (iNode1 == NULL)
     continue;

iNode2 = iNode1->ChildNodes->FindNode("GrpHdr");
if (iNode2 == NULL)
     continue;

lstNodos = iNode1->ChildNodes;
iNode2 = lstNodos->FindNode((DOMString)"PmtInf");
while (iNode2 != NULL)
{
     iNode3 = iNode2->ChildNodes->FindNode("PmtInfId");
     if (iNode3 != NULL && iNode3->IsTextElement)
     {
          [Código para tratar cada nodo]
     }
     iNode2 = lstNodos->FindSibling(iNode2, 1);
}
El método FindSibling lleva dos parámetros: el primero es el nodo que se está tratando en este momento (iNode2 en este caso) y el segundo es el sentido en que se quiere avanzar en la estructura (positivo hacia adelante, negativo hacia atrás) y el número de nodos que se quiere saltar (si pone uno se busca elsiguiente igual, etc.)
Responder Con Cita
  #4  
Antiguo 02-03-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.066
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Gracias por compartirlo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Leer fichero ini Angel.Matilla C++ Builder 13 21-04-2015 23:28:27
Leer fichero XML itsi Internet 1 23-10-2008 22:50:15
leer de fichero machingol Varios 7 09-05-2007 17:22:42
Leer fichero rocio84 Varios 1 21-05-2006 10:45:06
Leer un fichero .ini oesteve OOP 6 16-06-2003 16:40:20


La franja horaria es GMT +2. Ahora son las 09:15:12.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi