martes, 1 de enero de 2013

Validar XML con XSD: ideas para validar el modelo 390 del IVA

Buenas en este post voy a tratar un tema de interés tanto para programadores como para contables. Se trata de cómo validar un fichero xml contra un esquema xds y como estamos casi a final de año voy a utilizar un ejemplo real que es la validación del fichero del Resumen Anual del IVA (modelo 390). Para programadores: el modelo 390 contiene la suma de los datos de las declaraciones de IVA presentadas a lo largo del año y además informa a la Agencia Tributaria sobre el importe y la naturaleza de determinadas operaciones tanto de ventas como de compras. Toda persona física o persona jurídica que ejerza una actividad profesional o empresarial y siempre y cuando sus operaciones estén sujetas (exentas o no al IVA) tendrá que presentar los correspondientes modelos 303/310/311 del IVA cada trimestre (o cada mes en el caso del modelo 303 si se dan los requisitos establecidos en la Ley) y el resumen anual de las declaraciones presentadas en el año anterior antes del 30 de enero de año siguiente. Para más información aquí hay un link donde se detalla qué es el modelo 390 y las instrucciones.

El proceso el simple se genera un fichero xml con los datos que están definidos en el diseño del registro que nos proporciona la Agencia Tributaria para la generación del modelo en papel, sólo en el caso de personas físicas, y/o para la presentación telemática del modelo a través de la subida del fichero al servidor de la Agencia Tributaria y la firma digital por el interesado o autorizado. De lo que se trata es de validar este xml contra el esquema xsd que nos ofrece la Agencia Tributaria cada año disponible en el siguiente link.

En visual basic una función interesante para validar tu archivo xml contra un esquema xsd puede ser la siguiente, donde filename es la ruta a tu archivo xml y xsd es la ruta a tu archivo con el esquema xsd:
 Dim success As Boolean

Public Function ValidarXML(filename As String, xsd As String) As Boolean

success = True
Dim ruta As String = xsd

If File.Exists(ruta) Then
'Si existe el archivo valido que cumpla el esquema xsd
Dim settings As New XmlReaderSettings()

settings.ValidationType = ValidationType.Schema
Dim schemas As XmlSchemaSet = New XmlSchemaSet()
settings.Schemas = schemas
schemas.Add(
Nothing, ruta)

settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings
AddHandler settings.ValidationEventHandler, AddressOf ValidationEventHandler
Dim validator As XmlReader = XmlReader.Create(filename, settings)

'Leemos el documento xml, si se produce un error no cumplirá el esquema
While validator.Read()

End While

Else
MessageBox.Show("No se puede validar contra el esquema xds.", "Alerta", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If

Return success
End Function

Public Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)
 'Si se ejecuta este código es porque el xml no cumple con el esquema
     success = False
End Sub

Lógicamente crear el xml del modelo 390 sería bastante laborioso pero como la idea es la misma voy a crear un programa en Visual Basic .NET con un botón que abra una caja de diálogo que nos permita seleccionar la ruta en la que se encuentra el fichero xml y una vez elegido el fichero se validará contra el esquema xsd. Así ya validaremos de una forma muy sencilla que el fichero cumple con el esquema evitando muchas líneas de código para validar cada uno de los nodos del fichero xml. Vamos podría ser un suplicio ir leyendo cada nodo e ir validando que no cambie nada.

Vamos a validar que el fichero tenga la misma estructura definida en el esquema y luego quedará por validar el tema que el contenido de los campos de campos sea el correcto. Como puede ser el NIF/NIE/CIF o los importes de bases y cuotas según la estructura del impuesto, pero esto ya es un tema más fiscal. Si de lo que preguntas es cuál es el proceso para generar el fichero xml te diré que con .NET es muy sencillo y lo más complicado es validar que los datos que entra el usuario, antes de guardarlos en la base de datos -que es de donde los coge el programa-, sean correctos. Lógicamente antes de guardar los datos comprobaríamos que los datos que usuario ha entrado en el programa son del tipo y el formato correcto, vamos con validaciones simples ya se puede conseguir lo que buscamos. Una vez tengamos todo validado creamos el xml y validamos que los datos cumplen con el esquema xsd. Lógicamente si esto no se hiciera nos podríamos encontrar luego con errores y eso es inaceptable, sobre todo si el programa lo usa un tercero.  En el mejor de los casos a la hora de subir el fichero al servidor de la Agencia Tributaria para presentarlo nos daría un error y en el peor incluso pero se podría presentar una declaración en principio se aceptarse pero los datos o las casillas informadas no fueran correctas. Bueno todo el proceso que he explicado también puede ser muy útil a la hora de guardar copias de seguridad de los datos en un fichero xml, encriptado o no,  y poder compartir datos entre varias instalaciones de tu programa en diferentes ordenadores de forma muy sencilla. Esta es una alternativa para en lugar de hacer un backup de tu base de datos local puedes guardar los datos en un fichero xml y luego recuperar los datos del xml.
Pues aquí cuelgo un vídeo donde explico un poco el proceso:

Pues bien en el siguiente post una vez acabados los exámenes de enero de la carrera actualizaré algunas aplicaciones como la del modelo 202 que quedaba pendiente porque la estoy replanteando ahora en Java. En próximos vídos quiero explorar el trabajo con bases de datos en Java. Una pincelada: si tienes una aplicación en java y quieres que pueda acceder a una base de datos hay 2 alternativas. Si trabajas con una base de datos MySQL situada en el servidor puedes escribir el código necesario para comunicarte ella y hacer operaciones con tus datos. Pero si te preguntas como puedes conseguir programar en Java lo que en .NET sería una aplicación con una base de datos local Access o SQLite o SQL compact pues la solución es muy sencilla: Apache Derby o Java DB (Embedded) y trabajar Java Persistence API o JPA. Aquí hablaré sobre un FrameWork muy interesante llamado Hibernate. Si te fijas la aplicación que distribuye la AEAT para el modelo 390 usa todo eso.