martes, 11 de julio de 2017

Carga de información de códigos postales de SEPOMEX

Muchas veces en los sistemas se necesita una forma de consultar un código postal para obtener la colonia, el municipio o el estado al que pertenece. Lo más común en este caso es usar el servicio postal (en México llamado SEPOMEX). Esta vez, hablaré sobre como tomar esa información y cargarla en una tabla de una base de datos para su fácil utilización.

Lo primero que se tiene que hacer es, claro está, descargar el archivo XML de la página de SEPOMEX:


La información que contiene el archivo es la siguiente:


Lo más conveniente es que en la tabla se tengan todos los campos para almacenar toda la información. Si se abre el archivo en un editor de texto, casi al principio se encontrará el tipo de dato y el tamaño de cada campo, por ejemplo como el siguiente:

<xsd:element name="d_codigo" minOccurs="0">
   <xsd:simpleType>
   <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="3082" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
      <xsd:maxLength value="5"/>
   </xsd:restriction>
   </xsd:simpleType>
</xsd:element>

Donde se indica que el campo d_codigo es de tipo nvarchar y tiene tamaño 5. Utilizando la información de cada campo se puede construir fácilmente una tabla en la base de datos para almacenar toda la información. A continuación se muestra un ejemplo:


Antes de realizar la carga, será necesario eliminar los registros que hubiera en la tabla si es que ya existía y ya se había usado anteriormente, para así poder cargar toda la información actualizada. Se puede hacer esto fácilmente mediante la siguiente instrucción de SQL:

  truncate table codigos_postales

Una vez que la tabla esté lista para usarse, se puede proceder a leer el archivo y grabar los registros en la misma. Para ello se utilizará LINQ, así que será necesario importar el espacio de nombres:

  Imports System.Linq

Como primer paso se necesita abrir el archivo XML:

  Dim xmlCP As XElement = XElement.Load("ruta y nombre de archivo")

La información de los códigos postales viene de la siguiente forma:


Así es que se tienen que obtener todos los elementos cuyo nombre sea "table". Con la siguiente instrucción se obtiene de una sola vez todo el contenido del archivo:

  Dim items As IEnumerable(Of XElement) =
                         From item In xmlCP.Elements
                         Select item
                         Where item.Name.LocalName = "table"

A continuación, se tiene que iterar sobre todos los elementos:

  For Each nodo In items
     ...
     ...
     ...

  Next

Lo que se tiene que hacer en cada iteración del For es tomar el valor de cada campo:

  valor1 = CType(nodo.Nodes(0), XElement).Value
  valor2 = CType(nodo.Nodes(1), XElement).Value
  valor3 = CType(nodo.Nodes(2), XElement).Value

  ... etc. ...

Y una vez que ya se tiene cada campo, solo resta hacer una inserción en la tabla. La forma de hacerla depende de la tecnología que se esté utilizando (ADO.NET, LINQ to SQL, etc.), pero de forma general, el comando SQL para realizar la inserción quedaría de la siguiente manera:

insert into codigos_postales (d_codigo, d_asenta, d_tipo_asenta, etc.) values (valor1, valor2, valor3, etc.)

Es conveniente aclarar que algunos campos pueden venir vacíos, así que para evitar errores de ejecución, se recomienda verificar cada dato para ver si viene como Nothing. Por ejemplo, podría procederse de la siguiente forma:

  If valor1 Is Nothing Then valor1 = " "
  If valor2 Is Nothing Then valor2 = " "
  If valor3 Is Nothing Then valor3 = " "

  ... etc. ...