![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|||||||
| Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
![]() |
|
|
Herramientas | Buscar en Tema | Desplegado |
|
|
|
#1
|
|||
|
|||
|
Gracias por la respuesta. Efectivamente, empezó a generar los XML así cuando cambié la forma de generar y enviar los RF, para que la aplicación solo generara los XML pero otra aplicación los enviara. Para ello, necesito primero generarlos y guardarlos y luego abrirlos desde la otra app (que puede estar en otro PC incluso).
Confirmo que funciona, incluso con esos <item>. Actualmente lo que hago es modificarlo a mano antes de guardarlo, detectando si existen esos nodos y poniéndoles el nombre correcto |
|
#2
|
||||
|
||||
|
El "problema" viene desde el WSDL, todos los que usen la funcion ObjectToSOAP obtendran el mismo resultado.
En principio no estamos haciendo nada mal, si la definicion del WSDL viniera de otra forma, la funcion ObjectToSOAP lo haria "correcto". Manipular el XML cuando ha salido me da un poco de mal rollo, he probado distintas alternativas y manipular el XML con funciones de nodos, etc... no funciona bien. Lo mejor a mi parecer es directamente manipular el archivo de texto: Código:
function ReemplazarItemEnSeccion(const XMLText, Seccion, NombreViejo, NombreNuevo: string): string;
var
Inicio, Fin, PosActual: Integer;
ParteAntes, ParteMedia, ParteDespues: string;
begin
Result := XMLText;
PosActual := 1;
while True do
begin
// Buscar apertura de sección
Inicio := PosEx('<' + Seccion + '>', Result, PosActual);
if Inicio = 0 then
Break;
// Buscar cierre de sección
Fin := PosEx('</' + Seccion + '>', Result, Inicio);
if Fin = 0 then
Break;
// Extraer contenido dentro de la sección
ParteAntes := Copy(Result, 1, Inicio + Length(Seccion) + 1);
ParteMedia := Copy(Result, Inicio + Length(Seccion) + 2, Fin - (Inicio + Length(Seccion) + 2));
ParteDespues := Copy(Result, Fin, Length(Result) - Fin + 1);
// Reemplazar solo en la parte media
ParteMedia := StringReplace(ParteMedia,
'<' + NombreViejo + '>', '<' + NombreNuevo + '>', [rfReplaceAll, rfIgnoreCase]);
ParteMedia := StringReplace(ParteMedia,
'</' + NombreViejo + '>', '</' + NombreNuevo + '>', [rfReplaceAll, rfIgnoreCase]);
// Reconstruir XML
Result := ParteAntes + ParteMedia + ParteDespues;
// Mover posición para siguiente búsqueda (evitar ciclo infinito)
PosActual := Fin + Length(Seccion) + 2;
end;
end;
Código:
xmlText := ReemplazarItemEnSeccion(xmlText, 'Destinatarios', 'item', 'IDDestinatario'); Sinceramente no se que hacer, esto funciona. pero como digo me da "mal rollo" tocar un XML que ha salido limpio. Tengo que recopilar que arrays existen y colocarlo, quizas como opcion. Pero como digo no se si tocarlo o no. Porque en modo verifactu, no hay que enviar el RF, y tenerlo como esta ahora, no creo que sea problema. Maximo cuando la AEAT ya lo tiene. Saludos ! Pienso que no vas a tener problemas en enviar los RF, mientras no toquen el WSDL para cambiar la generacion de las etiquetas de los arrays. Y creo que eso no lo van a tocar. Es mas yo creo que ni se han preocupado de ello. Me gustaria tener alguna opinion. Última edición por seccion_31 fecha: 21-10-2025 a las 08:19:20. |
|
#3
|
|||
|
|||
|
Por lo pronto, Hacienda acepta el XML aunque ponga <item> en vez de <DetalleDesglose>. También ocurre en el nodo <Destinatarios>. Pero lo dicho, se lo traga como si estuviera bien.
En nuestro caso, nosotros guardamos el RF en la BD, porque luego otra aplicación se encarga de hacer los envíos a Hacienda desde el Servidor, así que hay que "leer" ese XML y volver a convertirlo en objeto, para poder firmarlo y enviarlo. Nosotros hemos optado por modificar el texto a mano, por si acaso algún día se pongan tiquismiquis con los nombres de esos nodos y deje de funcionar. Concretamente hacemos esto: Código:
// Reemplazamos el nodo raíz con el generado
MyXML.DocumentElement := NewNode;
MyXML.XML.Text := stringreplace(MyXML.XML.Text,'<Desglose><item>','<Desglose><DetalleDesglose>',[rfReplaceAll]);
MyXML.XML.Text := stringreplace(MyXML.XML.Text,'</item></Desglose>','</DetalleDesglose></Desglose>',[rfReplaceAll]);
MyXML.XML.Text := stringreplace(MyXML.XML.Text,'<Destinatarios><item>','<Destinatarios><IDDestinatario>',[rfReplaceAll]);
MyXML.XML.Text := stringreplace(MyXML.XML.Text,'</IDDestinatario></item>','</IDDestinatario></Destinatarios>',[rfReplaceAll]);
MyXML.XML.Text := FormatXMLData(MyXML.XML.Text);
MyXML.XML.SaveToFile(extractfilepath(application.exename)+'VeriFactu/RF'+RegistroFactura.RegistroAlta.RefExterna+'.xml',TEncoding.UTF8); // Provisional
O eso, o usar la función ReemplazarItemEnSeccion() que has facilitado, que es más genérica y servirá para cualquier otra incidencia que pueda surgir. Nosotros guardamos el XML/RF de cada factura en disco, pero solo por tener más seguridad y que en caso de algún error poder revisarlo todo más cómoda y rápidamente. En realidad el RF se guarda en la BD también, así que los archivos "sobran", pero es más rápido buscar/abrir un archivo en el disco que hacerlo en la BD. |
|
#4
|
||||
|
||||
|
Ok. entiendo tu proceso para que te veas un poco obligado a ese cambio
la verdad me ha sorprendido tu forma de reemplazo: por cierto, tengo una duda: ¿ con varios desgloses funcionara ? Saludos ! en el caso del componente, lo dejare tal cual esta, sin reemplazo, aunque guardare el código comentado en la DLL por si acaso. |
|
#5
|
|||
|
|||
|
Probablemente haya otra forma mejor de hacer el reemplazo, pero me vi apurado ayer y lo hice así en plan rápido porque si no no dormía
![]() Creo que hay un error aquí: MyXML.XML.Text := stringreplace(MyXML.XML.Text,'</IDDestinatario></item>','</IDDestinatario></Destinatarios>',[rfReplaceAll]); Debería ser así. me equivoqué al copiar/pegar: MyXML.XML.Text := stringreplace(MyXML.XML.Text,'</item></Destinatarios>','</IDDestinatario></Destinatarios>',[rfReplaceAll]); Esto solo funciona si el XML generado antes de llamar a FormatXMLData contiene todo el XML en una sola línea, porque es la única forma de que se encuentre esa cadena exacta a reemplazar. Si ya estuviera formateado, con cada nodo en una línea del archivo, el reemplazo no funciona (no existe esa cadena seguida tal cual), y habría que usar la función comentada anteriormente, que está más currada. Ojo, yo he detectado lo de <item> solo en estos dos nodos, pero puede que ocurra también en otros y habrá que estar atentos. |
![]() |
| Herramientas | Buscar en Tema |
| Desplegado | |
|
|
Temas Similares
|
||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| Restar Campo Generados de SQL | kurono | Varios | 15 | 23-06-2013 09:35:10 |
| Archivos _XXXX.DBF generados por consulta sql | klionsis | Varios | 1 | 08-09-2008 18:05:43 |
| Ficheros generados por delphi.NET | Mariolarr | .NET | 1 | 29-10-2007 19:59:41 |
| Archivos .MAP generados por Delphi | Ana Tudela | Varios | 2 | 26-10-2005 18:44:48 |
| Archivos temporales generados por TQuerys | Balda | Conexión con bases de datos | 0 | 14-04-2005 14:18:29 |
|