Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Registros de Facturacion y Eventos (XML) (https://www.clubdelphi.com/foros/forumdisplay.php?f=67)
-   -   Codigo C# Para Validar Xml Altas y Consultas (https://www.clubdelphi.com/foros/showthread.php?t=97137)

bmfranky 23-12-2024 16:32:42

Codigo C# Para Validar Xml Altas y Consultas
 
Hola, pongo el codigo que he terminadopara verificar la integridad de los registros XML antes de su envio.
Codigo para los envios.

Código:

      /// <summary>
        /// Funcion par acomprobar si el xml es correcto
        /// </summary>
        /// <param name="Xml">Xml a cotejar</param>
        /// <param name="path">Path donde estan los archivos.</param>
        /// <returns></returns>
        public bool checaXml(string Xml,string path= ".\\")
        {
            TextReader Read= new StringReader(Xml);
            var schemas = new XmlSchemaSet();
            Xml = Xml.Replace("<RegFactuSistemaFacturacion xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">", "<RegFactuSistemaFacturacion xmlns=\"https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd\">");
            //Xml = Xml.Replace(" xmlns=\"https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd\"", "");
            //Xml = Xml.Replace(" xmlns=\"https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd\"", "");
            using (FileStream stream = File.OpenRead(@path + "SuministroInformacion.xsd"))
            {
                var xsdFileR = XmlSchema.Read(stream, (s, e) =>
                {
                    var x = e.Message;
                });
                schemas.Add(xsdFileR);
            }
            using (FileStream stream = File.OpenRead(@path + "SuministroLR.xsd"))
            {
                var xsdFileR = XmlSchema.Read(stream, (s, e) =>
                {
                    var x = e.Message;
                });
                schemas.Add(xsdFileR);
            }
            using (var fs = File.OpenRead(@path + "xmldsig-core-schema.xsd"))
            using (var reader = XmlReader.Create(fs, new XmlReaderSettings()
            {
                DtdProcessing = DtdProcessing.Ignore // important
            }))
            {
                schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", reader);
            }
            bool isvalid = true;
            StringBuilder sb = new StringBuilder();
            try
            {
               
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.Schemas = schemas;
            settings.ValidationEventHandler += (s, e) =>
            {
                if (e.Severity == XmlSeverityType.Warning)
                {
                    sb.AppendLine(string.Format("WARNING: Line : {0}, Message : {1} ", e.Exception.LineNumber, e.Exception.Message));
                }
                else if (e.Severity == XmlSeverityType.Error)
                {
                    sb.AppendLine(string.Format("ERROR: Line : {0}, Message : {1} ", e.Exception.LineNumber, e.Exception.Message));
                }
              isvalid = false;
            };
            XmlReader readXml = XmlReader.Create(new StringReader(Xml), settings);
           
            while (readXml.Read()) { }
            var xdoc = XDocument.Parse(Xml);// (xmlFile);

            }
            catch (XmlSchemaValidationException val1)
            {
                isvalid = false;
            }

            var errores= sb.ToString();
            //puedes guardar la cadena errores en un log o mosrarla en pantalla.
            if (errores != "")
                MessageBox.Show(errores, "Errores");
            return isvalid;
        }

Codigo para las Consultas.
Código:

        /// <summary>
        /// Funcion par acomprobar si el xml es correcto
        /// </summary>
        /// <param name="Xml">Xml a cotejar</param>
        /// <param name="path">Path donde estan los archivos.</param>
        /// <returns></returns>
        public bool checaXml(string Xml, string path = ".\\")
        {
            TextReader Read = new StringReader(Xml);
            var schemas = new XmlSchemaSet();
            Xml = Xml.Replace("<ConsultaFactuSistemaFacturacionType xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">", "<ConsultaFactuSistemaFacturacionType xmlns=\"https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/ConsultaLR.xsd\">");
            Xml = Xml.Replace("ConsultaFactuSistemaFacturacionType", "ConsultaFactuSistemaFacturacion");
            //Xml = Xml.Replace(" xmlns=\"https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd\"", "");
            //using (FileStream stream = File.OpenRead(@path + "SuministroInformacion.xsd"))
            //{
            //    var xsdFileR = XmlSchema.Read(stream, (s, e) =>
            //    {
            //        var x = e.Message;
            //    });
            //    schemas.Add(xsdFileR);
            //}
            using (FileStream stream = File.OpenRead(@path + "ConsultaLR.xsd"))
            {
                var xsdFileR = XmlSchema.Read(stream, (s, e) =>
                {
                    var x = e.Message;
                });
                schemas.Add(xsdFileR);
            }
            using (var fs = File.OpenRead(@path + "xmldsig-core-schema.xsd"))
            using (var reader = XmlReader.Create(fs, new XmlReaderSettings()
            {
                DtdProcessing = DtdProcessing.Ignore // important
            }))
            {
                schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", reader);
            }
            bool isvalid = true;
            StringBuilder sb = new StringBuilder();
            try
            {

                XmlReaderSettings settings = new XmlReaderSettings();
                settings.ValidationType = ValidationType.Schema;
                settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
                settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
                settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
                settings.Schemas = schemas;
                settings.ValidationEventHandler += (s, e) =>
                {
                    if (e.Severity == XmlSeverityType.Warning)
                    {
                        sb.AppendLine(string.Format("WARNING: Line : {0}, Message : {1} ", e.Exception.LineNumber, e.Exception.Message));
                    }
                    else if (e.Severity == XmlSeverityType.Error)
                    {
                        sb.AppendLine(string.Format("ERROR: Line : {0}, Message : {1} ", e.Exception.LineNumber, e.Exception.Message));
                    }
                    isvalid = false;
                };
                XmlReader readXml = XmlReader.Create(new StringReader(Xml), settings);

                while (readXml.Read()) { }
                var xdoc = XDocument.Parse(Xml);// (xmlFile);

            }
            catch (XmlSchemaValidationException val1)
            {
                isvalid = false;
            }

            var errores = sb.ToString();
            //puedes guardar la cadena errores en un log o mosrarla en pantalla.
            if (errores != "")
                MessageBox.Show(errores, "Errores");
            return isvalid;
        }

Para usarlo hay que tener en el directorio que queramos o el raiz de la aplicacion los XSD y el "xmldsig-core-schema.xsd" para evitar fallos por la rapidez de acceso a la web.


Yo personalmente asigno a una variable gloval los errores devueltos, al realizar la llamada a la funcion , analizo el string devuelto en funcion de si hay errores.


En mis pruebas personales funciona correctamente, provad vosotros y me decis...

ElKurgan 26-12-2024 17:51:41

Muchas gracias por el aporte

Saludos

sglorka 26-12-2024 19:55:29

Con este control del fichero Xml se resuelven bastantes problemas tanto a nivel sintáctico como semántico. Pero hay que tener en cuenta que las reglas de validación expuestas en el documento de Errores y Validaciones quedan fuera de este tipo de validación. Los tipos de impuestos utilizados, la validación de los Nif, el régimen tributario adecuado al tipo de operación ( arrendamiento, simplificado, minorista), el sumatorio de bases imponibles y cuotas para obtener el total, las claves de las listas a utilizar en función de si el impuesto es Iva o Igic, etc, etc.... son aspectos que tenemos que validar también después de pasar por este primer filtro.

rci 27-12-2024 16:28:10

Muchas gracias bmfranky, al final me ha funcionado.

He hecho pruebas y he puesto los comentarios en el otro post:

Cita:

Empezado por rci (Mensaje 560975)
Hola bmfranky, muchas gracias por tu ayuda.

A mi no me ha funcionado pero puede ser que sea un problema mío y/o que me falte hacer algún ajuste
...
Después me he fijado que tu ejemplo es de un XML completo (con elemento base RegFactuSistemaFacturacion), listo para enviar, ya empaquetado, con una o varias facturas dentro (RegistroFactura y RegistroAlta).

En cambio el XML que intento enviar yo es de una sola factura (con elemento base RegistroFacturacionAltaType o RegistroAlta ), sin empaquetar para enviar, porque precisamente, quiero validar cada factura antes de poner dentro de un paquete para enviar, porque luego falla todo el paquete y no indica que factura está mal.

Supongo que el problema que tengo es este.
Finalmente he probado empaquetar en memoria cada factura una a una antes de validarla y validar ese XML. Creo que así ya me servirá.

Muchas gracias!

Cita:

Empezado por bmfranky (Mensaje 560910)
Hola, pongo el codigo que he terminado para verificar la integridad de los registros XML antes de su envio.
Codigo para los envios.

...

En mis pruebas personales funciona correctamente, provad vosotros y me decis...


Rja750 03-01-2025 13:21:54

esquema XSD
 
Hola, donde puedo descargarme el esquema XSD veri*factu de facturas simplificadas para cotejarlo con mi XML? quiero tenerlo en local para que no evitar problema con los tiempos del servidor de la AEAT, pero no lo encuentro

rci 03-01-2025 13:28:18

Cita:

Empezado por Rja750 (Mensaje 561036)
Hola, donde puedo descargarme el esquema XSD veri*factu de facturas simplificadas para cotejarlo con mi XML? quiero tenerlo en local para que no evitar problema con los tiempos del servidor de la AEAT, pero no lo encuentro

En la pagina de Veri*Factu para desarrolladores tienes enlaces a todos los esquemas:

https://www.agenciatributaria.es/AEA...icios_web.html

Rja750 03-01-2025 15:57:06

Muchas gracias rci.

Rja750 09-01-2025 12:53:56

Estructura de elementos
 
Estoy teniendo problemas en confeccionar el XML con la estructura que debe llevar el y los espacios de nombres según los esquemas. Intento validar el XML de una factura simplificada y me da error. Por mas que miro los esquemas SuministroInformacion.xsd y ConsultaLR.xsd que son los que necesito, no logro dar con los espacios de nombres y la estructura del XML. ¿Habría alguna plantilla actualizada que me mostrara como seria un XML para una factura simplificada?

gcqZW 09-01-2025 13:03:06

Cita:

Empezado por Rja750 (Mensaje 561104)
Estoy teniendo problemas en confeccionar el XML con la estructura que debe llevar el y los espacios de nombres según los esquemas. Intento validar el XML de una factura simplificada y me da error. Por mas que miro los esquemas SuministroInformacion.xsd y ConsultaLR.xsd que son los que necesito, no logro dar con los espacios de nombres y la estructura del XML. ¿Habría alguna plantilla actualizada que me mostrara como seria un XML para una factura simplificada?

Según entiendo, sería la misma plantilla que un alta normal, solo que tendrías que especificar en TipoFactura el tipo "F2".

Rja750 09-01-2025 20:50:15

Xml
 
Hola, no tengo claro lo siguiente. El registro de alta (Factura) se envía en formato XML, los campos necesarios del registro son de tipo RegistroFacturacionAltaType y lleva; IDVersion,IDFactura,NombreRazonEmisor,TipoFactura,DescripcionOperacion,Desglose,CuotaTotal,ImporteTo tal,Encadenamiento,SistemaInformatico,FechaHoraHusoGenRegistro,TipoHuella,Huella.
1. ¿Estos serian los necesario (sin meter los minOccurs="0") para empaquetar el XML?
2. ¿Que cabecera debo añadir al XML?
Estoy intentando organizarme pero necesito vuestra ayuda. Me podéis echar una mano? si alguien pudiera ponerme un ejemplo de como seria un fichero xml generado me ayudaría mucho. Muchas gracias

Rja750 07-02-2025 12:04:57

Cita:

Empezado por Rja750 (Mensaje 561120)
Hola, no tengo claro lo siguiente. El registro de alta (Factura) se envía en formato XML, los campos necesarios del registro son de tipo RegistroFacturacionAltaType y lleva; IDVersion,IDFactura,NombreRazonEmisor,TipoFactura,DescripcionOperacion,Desglose,CuotaTotal,ImporteTo tal,Encadenamiento,SistemaInformatico,FechaHoraHusoGenRegistro,TipoHuella,Huella.
1. ¿Estos serian los necesario (sin meter los minOccurs="0") para empaquetar el XML?
2. ¿Que cabecera debo añadir al XML?
Estoy intentando organizarme pero necesito vuestra ayuda. Me podéis echar una mano? si alguien pudiera ponerme un ejemplo de como seria un fichero xml generado me ayudaría mucho. Muchas gracias

:D:D Madre mía ¡¡que perdido estaba!!


La franja horaria es GMT +2. Ahora son las 23:33:53.

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