Aquí tenéis el código fuente del script realizado en python que convierte el fichero txt a xml de una remesa sepa del cuaderno 19.
import sys,os, os.path, shutil, time
from lxml import etree
#------------------------------------------------------
#
# Función que devuelve el importe sin separación decimal.
#
#------------------------------------------------------
def conviertenumero(numero,decimales):
if str.isnumeric(str(decimales)) == 'False':
decimales = 0
# convierte el importe en float sin decimales
importe = "{:.0f}".format(float(numero))
# calcula la longitud del importe
limporte = len(importe)
# dos ultimas posiciones para los decimales, el resto parte entera y . decimal
if decimales != 0:
importe = importe[0:limporte-decimales] + "." + importe[limporte-decimales:limporte]
return importe
def cargararraycabecera01(t):
cabecera[0] = t[123:158] # Identificacion del mensaje
cabecera[1] = t[115:123] # Fecha y hora de creacion
cabecera[4] = t[45:115] # Nombre
cabecera[6] = t[10:26] # Identificacion
cabecera[8] = t[166:177] # IBAN
if not cabecera[8].strip():
cabecera[8] = "NOTPROVIDED"
def cargararraycabecera02(t):
cabecera[7] = t[265:290] # IBAN Empresa emite remesa
def parseartotal99(t):
cabecera[2] = t[19:27] # Numero de operaciones
cabecera[3] = t[2:19] # Control de suma
def parsearcabecera01():
fecha = time.strftime("%Y-%m-%dT%H:%M:%S")
GrpHdr = etree.SubElement(CstmrPmtRvsl, "GrpHdr")
MsgId = etree.SubElement(GrpHdr, "MsgId")
CreDtTm = etree.SubElement(GrpHdr, "CreDtTm")
NbOfTxs = etree.SubElement(GrpHdr, "NbOfTxs")
CtrlSum = etree.SubElement(GrpHdr, "CtrlSum")
InitgPty = etree.SubElement(GrpHdr, "InitgPty")
Nm = etree.SubElement(InitgPty, "Nm")
Id = etree.SubElement(InitgPty, "Id")
OrgId = etree.SubElement(Id, "OrgId")
Othr = etree.SubElement(OrgId, "Othr")
Id = etree.SubElement(Othr, "Id")
MsgId.text = cabecera[0].strip()
CreDtTm.text = fecha
NbOfTxs.text = conviertenumero(cabecera[2].strip(),0)
CtrlSum.text = conviertenumero(cabecera[3].strip(),2)
Nm.text = cabecera[4].strip()
Id.text = cabecera[6].strip()
def parseardetalle03(t):
PmtInf = etree.SubElement(CstmrPmtRvsl, "PmtInf")
PmtInfId = etree.SubElement(PmtInf, "PmtInfId")
PmtMtd = etree.SubElement(PmtInf, "PmtMtd")
#BtchBookg = etree.SubElement(PmtInf, "BtchBookg") se elimino para que haga un apunte por el total en nuestra cuenta
PmtInfId.text = t[10:45].strip()
PmtMtd.text = "DD"
#BtchBookg.text = "true" se elimino para que haga un apunte por el total en nuestra cuenta
PmtTpInf = etree.SubElement(PmtInf, "PmtTpInf")
SvcLvl = etree.SubElement(PmtTpInf, "SvcLvl")
Cd = etree.SubElement(SvcLvl,"Cd")
Cd.text ="SEPA"
LclInstrm = etree.SubElement(PmtTpInf, "LclInstrm")
Cd = etree.SubElement(LclInstrm, "Cd")
if t[2:7] == "19143":
Cd.text ="CORE"
else:
Cd.text = "COR1"
SeqTp = etree.SubElement(PmtTpInf, "SeqTp")
SeqTp.text = t[80:84].strip()
ReqdColltnDt = etree.SubElement(PmtInf, "ReqdColltnDt")
ReqdColltnDt.text = t[26:30] + "-" + t[30:32] + "-" + t[32:34]
Cdtr = etree.SubElement(PmtInf, "Cdtr")
Nm = etree.SubElement(Cdtr, "Nm")
Nm.text = cabecera[4].strip()
#----------------------------------------------------------
# deshabilitado pq no quiero que pase la dirección
#Nm.text = t[118:188].strip()
#PstlAdr = etree.SubElement(Cdtr, "PstlAdr")
#Ctry = etree.SubElement(PstlAdr, "Ctry")
#Ctry.text = t[328:330]
#AdrLine = etree.SubElement(PstlAdr, "AdrLine")
#AdrLine.text = t[188:238].strip()
#-----------------------------------------------------------
CdtrAcct = etree.SubElement(PmtInf, "CdtrAcct")
Id = etree.SubElement(CdtrAcct, "Id")
IBAN = etree.SubElement(Id, "IBAN")
IBAN.text = cabecera[7].strip()
#------------------------------------------------------------
# solo si tiene más de una moneda la cuenta
#IBAN.text = t[403:437].strip()
#Ccy = etree.SubElement(CdtrAcct, "Ccy")
#Ccy.text = "EUR"
#------------------------------------------------------------
CdtrAgt = etree.SubElement(PmtInf, "CdtrAgt")
FinInstnId = etree.SubElement(CdtrAgt, "FinInstnId")
BIC = etree.SubElement(FinInstnId, "BIC")
BIC.text = cabecera[8].strip()
#ChrgBr = etree.SubElement(PmtInf, "ChrgBr")
#ChrgBr.text = "SLEV"
CdtrSchmeId = etree.SubElement(PmtInf, "CdtrSchmeId")
Id = etree.SubElement(CdtrSchmeId, "Id")
PrvtId = etree.SubElement(Id, "PrvtId")
Othr = etree.SubElement(PrvtId, "Othr")
Id = etree.SubElement(Othr, "Id")
Id.text = cabecera[6].strip()
SchmeNm = etree.SubElement(Othr, "SchmeNm")
Prtry = etree.SubElement(SchmeNm, "Prtry")
Prtry.text = "SEPA"
DrctDbtTxInf = etree.SubElement(PmtInf, "DrctDbtTxInf")
PmtId = etree.SubElement(DrctDbtTxInf, "PmtId")
InstrId = etree.SubElement(PmtId, "InstrId")
InstrId.text = t[26:40] + "-" + t[40:45]
EndToEndId = etree.SubElement(PmtId, "EndToEndId")
EndToEndId.text = t[10:45].strip()
InstdAmt = etree.SubElement(DrctDbtTxInf, "InstdAmt") # Anyadir Ccy = "EUR"
InstdAmt.set("Ccy","EUR")
InstdAmt.text = conviertenumero(t[88:99].strip(),2)
DrctDbtTx = etree.SubElement(DrctDbtTxInf, "DrctDbtTx")
MndtRltdInf = etree.SubElement(DrctDbtTx, "MndtRltdInf")
MndtId = etree.SubElement(MndtRltdInf,"MndtId")
MndtId.text = t[45:54].strip()
DtOfSgntr = etree.SubElement(MndtRltdInf, "DtOfSgntr")
DtOfSgntr.text = t[99:103]+"-"+t[103:105]+"-"+t[105:107]
AmdmntInd = etree.SubElement(MndtRltdInf, "AmdmntInd")
AmdmntInd.text = "false"
DbtrAgt = etree.SubElement(DrctDbtTxInf, "DbtrAgt")
FinInstnId = etree.SubElement(DbtrAgt, "FinInstnId")
BIC = etree.SubElement(FinInstnId, "BIC")
vbic = t[581:592]
if not vbic.strip():
vbic = "NOTPROVIDED"
BIC.text = vbic
Dbtr = etree.SubElement(DrctDbtTxInf, "Dbtr")
Nm = etree.SubElement(Dbtr, "Nm")
Nm.text = t[118:188].strip()
#--------------------------------------------------------------
# DESACTIVADO PARA QUE NO CARGUE LA DIRECCION
#PstlAdr = etree.SubElement(Dbtr, "PstlAdr")
#Ctry = etree.SubElement(PstlAdr, "Ctry")
#Ctry.text = t[328:330].strip()
#AdrLine = etree.SubElement(PstlAdr, "AdrLine")
#AdrLine.text = t[188:238].strip()
#---------------------------------------------------------------
DbtrAcct = etree.SubElement(DrctDbtTxInf, "DbtrAcct")
Id = etree.SubElement(DbtrAcct, "Id")
IBAN = etree.SubElement(Id, "IBAN")
IBAN.text = t[403:437].strip()
RmtInf = etree.SubElement(DrctDbtTxInf, "RmtInf")
Ustrd = etree.SubElement(RmtInf, "Ustrd")
Ustrd.text = t[441:581].strip()
print ("==============================================================")
print ("== Aplicacion creada por Antonio Vila Juan en Python 3.40 ==")
print ("== INICIO APLICACION PARA GENERAR FICHERO XML A PARTIR ==")
print ("== DE UN TXT (TEXTO PLANO) ==")
print ("== Lee el fichero de remesa sepa en txt y lo convierte ==")
print ("== segun disenyo de BCE a xml ==")
print ("== Si tienes alguna duda visita www.avjsite.com ==")
print ("== encontraras tutoriales de como funciona el pgm ==")
print ("==============================================================")
# Cargo el nombre del fichero txt
fichero = sys.argv[1]
# Inicializo el array
cabecera = [""] * 17
# Inicializo la variable root que es la que almacenara todo el xml
xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02"
ns = {"xsi": xsi}
root=etree.Element("Document", nsmap=ns)
#root = etree.Element("Document",)
#root.set('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance')
root.set('xmlns','urn:iso:std:iso:20022:tech:xsd:pain.008.001.02')
CstmrPmtRvsl = etree.SubElement(root, "CstmrDrctDbtInitn")
# Abro el fichero para leer la primera vez
f = open(fichero)
lines = f.readlines()
#------------------------------------------------------------------------------
# Leo las lineas una a una la primera vez para cargar la cabecera
#------------------------------------------------------------------------------
for l in lines:
if l[:2] == "01":
cargararraycabecera01(l)
elif l[:2] == '02':
cargararraycabecera02(l)
elif l[:2] == '99':
parseartotal99(l)
# Leo las lineas una a una la primera vez para cargar la cabecera
# Muevo los datos del array a xml
parsearcabecera01()
# Abro el fichero para leer la segunda vez
f = open(fichero)
lines = f.readlines()
#------------------------------------------------------------------------------
# Leo las lineas una a una la segunda vez para grabar el detalle
#------------------------------------------------------------------------------
for l in lines:
if l[:2] == '03':
parseardetalle03(l)
# Leo las lineas una a una la segunda vez para grabar el detalle
# Grabar el fichero de salida xml
tree = etree.ElementTree(root)
# Creo el nombre del fichero de salida.
t = fichero.split(os.sep)
fset = t[len(t)-1].split('.')
fse = fset[0]
ruta_salida = ""
for i in range(len(t)-1):
ruta_salida = ruta_salida + t[i] + chr(92)
salida = ruta_salida + fse + ".xml"
tree.write(salida, pretty_print=True , encoding='utf-8', xml_declaration=True)
ruta_temporal = ruta_salida + "Tmp" + chr(92)
# Se crea el directorio para almacenar los ficheros en texto plano.
if (os.path.isdir(ruta_temporal)):
print ("exite tmp")
else:
print ("no existe el directorio tmp")
os.mkdir(ruta_temporal)
# Cerramos el fichero f.
f.close()
# mueve el fichero txt a tmp
shutil.move(fichero, ruta_temporal + t[len(t)-1])
Puedes descargar el código desde nuestra tienda.