Universidad de Costa Rica

Sede Rodrigo Facio

 

Facultad de Ingeniería

Escuela de Ciencias de la Computación e Informática

 

 

Curso: CI-1322 Autómatas y Compiladores

Grupo 002

 

 

Profesor:

Adolfo Di Mare Hering

 

Tarea#1 Traducción de avisos económicos a XML

 

Integrantes:

Manuel León Vega 896061

[email protected]

283-7405

José Andrés Romero González  A24493

[email protected]

245-3327

 

Fecha de Entrega:

09 de marzo de 2007

 

 

I Ciclo Lectivo

2007

 

 

 

 

 

 


Índice

 

 

Introducción_ 1

Metodología 1

Análisis del Problema_ 2

Abstracción_ 3

Diagrama de Clases 3

Descripción de cada clase_ 3

Clase LeerArchivo_ 3

Clase ListaClasificacion_ 4

Clase NodoClasificación_ 4

Clase ListaArticulo_ 5

Clase NodoArtículo_ 5

Eficiencia de la solución_ 6

Descripción de algoritmos complejos 6

Algoritmo Insertar En Clasificación_ 6

Compilador Usado_ 7

Manual de Usuario_ 7

Datos de Prueba_ 10

Código Fuente 11

Bibliografía_ 27


Introducción

 

Se construirá un programa "xecnx.exe" que tome páginas HTML de avisos económicos y extraigan un documento en formato XML con la información relevante al documento.

El programa debe ser capaz de extraer toda la información de cada anuncio económico. También debe manejar la codificación que es usual en este tipo de avisos.

Se utilizarán las siguientes páginas de Internet para realizar el trabajo como referencia:

http://www.4llantas.com/

http://www.CRautos.com/

http://www.economicos.com/

http://www.diarioextra.com/

Esta documentación se puede consultar vía Internet a través de la siguiente dirección:

http://www.geocities.com/mlvcr3/Tarea_Programada_01.html

Para descargar los archivos con la solución:

http://www.geocities.com/mlvcr3/896061-A24496_TP01.zip

 

 

 

Metodología

 

Análisis de los formatos de las diferentes páginas con el fin de discriminar información.

 

Trabajo de manera conjunta en la etapa de definición y estructura básica de la solución.

La etapa de integración se hará de manera conjunta al igual que la realización de las pruebas y la edición de los respectivos manuales (manual de usuario y manual de programador).

 

 

 


Análisis del Problema

 

La funcionalidad de la aplicación radica en recopilar solamente la información pertinente a los anuncios económicos, sin tomar en cuenta el formato de la página ni otros vínculos con otro tipo de importancia.

 

La extracción de la información se hará a partir de archivos guardados con extensión HTML y no propiamente leídas desde servidores. En el caso del página de clasificados del diario la extra, el código fuente es de extensión “php”, aun así el programa esta diseñado para aceptar cualquier nombre de archivo presente en la carpeta principal, pero el análisis esta orientado aun archivo de formato HTML, específicamente la del diario La Extra.

 

Los valores de entrada corresponden a los archivos HTML que se obtuvieron de la página del diario la extra de la sección de económicos.

 

La salida es un archivo XML con la estructura jerárquica. El usuario deberá incluir todos los documentos HTML que desea analizar y el programa generará un documento con la información de estos.

 

Se creará una estructura de datos que almacenará la información extraída del archivo ingresado, en dicha estructura se clasificará la información, para luego generar el archivo salida, esto mediante un diccionario construido previamente.

 


Abstracción

 

Diagrama de Clases

 

 

Descripción de cada clase

 

Clase LeerArchivo

Descripción: hace la extracción y análisis del texto solicitado para que este pueda luego ser insertado en la estructura de datos. Contiene el método principal que permite la manipulación de toda la aplicación.

Métodos:

public static void main(String[] args): manipula la construcción del diccionario que es creado a partir de un archivo llamado “TipoClasificación.txt”. Encuentra el inicio y el final del bloque de clasificados. Analiza el archivo “php”. Crea el archivo “preClasificados.txt” ya depurado. Construye el archivo XML

Requiere: que el o los archivos HTML existan.

 

Clase ListaClasificacion

Descripción: permite la creación de la estructura de datos que contendrá las clasificaciones de los anuncios.

Atributos:

primero: apuntador a la primera clasificación.

ultimo: apuntador a la última clasificación.

Métodos:

EstaVacio(): determina si la lista contiene algún anuncio o esta vacía.

Requiere: que la lista exista.

Retorna: true si la lista esta vacía y false si no.

GeneradorXMLClasificacion(): recorrer la lista de clasificaciones y la concatena a una cadena de caracteres. Hace un llamado a GeneradorXMLArticulo() de la clase ListaArticulo para obtener los anuncios asociados.

Requiere: la existencia de clasificaciones en la lista.

Retorna: la cadena de caracteres con las clasificaciones y los anuncios.

HacerClasificacion(): crea una lista de clasificaciones. Almacena el nombre de la clasificación. Almacena los descriptores de esa clasificación (diccionario).

Requiere: que el archivo “TipoClasificacion.txt” exista.

ImprimirClasificacion(): Imprime la clasificación y sus anuncios.

Requiere: que la lista de clasificaciones exista.

InsertarClasificacion(): Inserta cada clasificación

Requiere: Requiere: que el archivo “TipoClasificacion.txt” exista.

InsertarEnClasificacion(): Inserta cada anuncio en su respectiva clasificación

Requiere: que la lista de clasificaciones exista.

ListaClasificacion(): Constructor de la clase clasificación

 

Clase NodoClasificación

Descripción: permite crear una instancia de tipo clasificación

Atributos:

listaDeArticulos: apuntador a la lista de Articulos

nombreClasificación: permite almacenar el nombre de la clasificación.

parametro: vector que almacena los descriptores de la descripción

sig: apuntador a la siguiente clasificación

 

Métodos:

NodoClasificación(string nombre, asociador): constructor de la clase clasificación cuando no hay nodos

NodoClasificación(string nombre, asociador, sigNodo): constructor de la clase clasificación cuando hay nodos insertados

ObtenerNombre(): retorna el nombre de la clasificación.

Requiere: que la clasificación exista.

Retorna: la clasificación

ObtenerParametro(): retorna el vector que contiene que contiene el diccionario de cada clasificación.

Requiere: que la descripción exista.

ObtieneSig(): retorna la siguiente Clasificación.

Requiere: que el anuncio exista.

Retorna: un puntero a la siguiente clasificación

Clase ListaArticulo

Descripción: permite la creación de la estructura de datos que contendrá los anuncios econòmicos

Atributos:

primero: apuntador al primer artículo.

ultimo: apuntador al último artículo.

 

Métodos:

EstaVacio(): determina si la lista contiene algún anuncio o esta vacía.

Requiere: que la lista exista.

Retorna: true si la lista esta vacía y false si no.

GeneradorXMLArticulo(): recorrer la lista de anuncios y la concatena a una cadena de caracteres.

Requiere: la existencia de anuncios en la lista.

Retorna: la cadena de caracteres con los anuncios.

ImprimirArticulo(): imprime toda la lista de artículos.

Requiere: la existencia de anuncios en la lista.

InsertarArticulo(): inserta un anuncio en la lista de artículos.

Requiere: que la lista exista.

ListaArticulo(): constructor de la clase.

Clase NodoArtículo

Descripción: permite crear una instancia de tipo artículo

Atributos:

nombre: permite almacenar el nombre del artículo

descripción: permite almacenar la descripción del artículo.

sigAbajo: apuntador al siguiente articulo

Métodos:

NodoArticulo(string nombre, descripcion): constructor de la clase articulo cuando no hay nodos

NodoArticulo(string nombre, descripción,sigAbajo): constructor de la clase articulo cuando hay nodos insertados

ObtenerNombre(): retorna el nombre del anuncio.

Requiere: que el anuncio exista.

Retorna: el anuncio

ObtenerSigAbajo(): retorna el siguiente anuncio.

Requiere: que el artículo exista.

Retorna: el nodo al siguiente artículo

ObtenerDescripción(): retorna la descripción del anuncio.

Requiere: que el anuncio exista.

Retorna: el anuncio

 

Eficiencia de la solución

 

La solución esta orientada a la estructura muy particular de la página del diario La Extra es eficiente para ella mas, si la estructura del código varía la aplicación no funcionaría de manera correcta, si la cantidad anuncios crece el tiempo de procesamiento aumenta. El orden de duración sería aproximadamente O(n2)

 

Descripción de algoritmos complejos

 

Algoritmo Insertar En Clasificación

 

Lee el archivo preclasificados

Mientras (existan líneas en el archivo) {

       PosicionarseEnElPrimeroDeLista

       Mientras (halla clasificacion por revisar y no pueda ubicar a anuncio en clasificacion){

            Mientras (no encuentre palabra en diccionario) {

                        Si (no encuentre la palabra) {

                        buscarSiguientePalabra

                        }Si palabra fue encontrada

indicarPalabraEncontrada

            }

          }

 

          Si (palabraEncontrada) {

                        InsertarAnuncioEnClasificacion();

          }Si no encontró palabra en diccionario

            Avanzar a la siguiente Clasificación

          }

        }

        Si (no se pudo ubicar a anuncio){

ponerAnuncioEnCategoríaGeneral();

        }

      }

      Cerrar Archivo de Preclasificados

    }

 

Compilador Usado

 

El programa fue desarrollado en lenguaje Java.

La versión del compilador utilizado es Java JBuilder Enterprise X.

Pasos para realizar el proceso de compilación:

 

  1. Descargar la aplicación desde la pagina Web:
  2. Entrar al programa JBuilder
  3. Dentro del programa de JBuilder, en el menú Archivo elegir la opción Abrir Proyecto y buscar en la carpeta Traductor el archivo “Traducto.jpx”
  4. Presione Abrir
  5. En la barra de herramientas presione el botón Ejecutar Proyecto

 

Manual de Usuario

 

  1. Entrar al programa JBuilder (previamente instalado en su computadora).
  2. Presione el botón Play que se encuentra en la barra de herramientas
  3. Dentro del programa de JBuilder, en el menú Archivo elegir la opción Abrir Proyecto y buscar en la carpeta Traductor el archivo “Traducto.jpx”
  4. Presione Abrir
  5. En la barra de herramientas presione el botón Ejecutar Proyecto
  6. Se le presentará la siguiente pantalla:

 

 

 

 

 

 

 

 

 

 

 

  1. Digite el nombre del archivo con su extensión que desea procesar

 

 

 

  1. Presione la tecla Enter y aguarde a que inicie el procesamiento del archivo
  2. En pantalla aparecerá un mensaje indicando que los anuncios fueron acomodados

 

 

  1. Seguidamente se mostrará la secuencia de líneas que están siendo procesadas

 

 

 

 

 

 

 

 

 

 

 

 

 

  1. Por último el programa indicará que finalizó el procesamiento

 

  1. Verifique que el archivo indicado se creó en la raíz de la carpeta Traductor

 

 


Datos de Prueba

 

La salida del programa debe ser un archivo de formato XML y que muestre los anuncios extraídos de manera clasificada.

 

A continuación se presentan el procesamiento de 3 archivos extraídos de la página del diario extra que corresponden a las fechas 2007_01_19_clasificados01.php.htm, 2007_02_19_clasificados01.php.htm y 2007_03_19_clasificados01.php.htm, que corresponden a los archivos de entrada.

 

Las salidas de acuerdo a cada archivo son:

 

 

 

 

Código Fuente

 

 

package traductor;

 

import java.io.*;

import java.util.*;

 

public class LeerArchivo {

 

  //Manipula la construcción del diccionario que es creado a partir de un archivo

  //llamado “TipoClasificación.txt” donde se encuentran las diferentes clasificaciones

  //con sus correspondientes palabras que describen cada una de ellas y que permite

  //comparar dichas palabras con cada anuncio para discernir cuales corresponden a cada uno

  public static void main(String[] args) throws IOException {

    String archivoOriginal = new String();

    //Construye el diccionario con las clasificaciones de los diversos anuncios

    //Lo llena con una jerarquía para los anuncios

    ListaClasificacion miLista = new ListaClasificacion();

    miLista.HacerClasificacion();

   

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

 

    System.out.print("\n Ingrese el nombre del archivo que desea procesar : ");

    archivoOriginal = in.readLine();

   

    //Leer el código de la página HTML que será el archivo de entrada

    BufferedReader archivoEntrada = new BufferedReader(new FileReader(archivoOriginal));

    //Variables para el manejo del contenido del archivo leído

    String archivoLeidoParcial, archivoLeidoCompleto = new String(); //

    //Determina el inicio del bloque de texto con los clasificados

    String textoInicioC ="Inicia texto noticia";

    //Determina el final del bloque de texto con los clasificados

    String textoFinalC = "Cierra Texto Noticia";

    //Verifica si se encontraron los bloques buscados

    boolean encontrarInicio=false;

    boolean encontrarFinal = false;

    //Busca el inicio de la sección de clasificados

    //Lee mientras no llegue a línea nula

    while (((archivoLeidoParcial = archivoEntrada.readLine()) != null)&& (encontrarInicio==false)) {

      //Si encuentra el bloque indicado

      if (archivoLeidoParcial.indexOf(textoInicioC) != -1){

        //Se sale del ciclo al encontrar el inicio de clasificados

        encontrarInicio = true;

      }

    }

    //Busca el final de la sección de clasificados y va concatenando la información leída

    while (((archivoLeidoParcial = archivoEntrada.readLine()) != null) && (encontrarFinal==false)) {

      //Si no ha llegado al final de los clasificados concatena la línea leída

      if (archivoLeidoParcial.indexOf(textoFinalC) == -1){

        archivoLeidoCompleto += archivoLeidoParcial;

      }else{

        //Se sale del ciclo al encontrar el final de los clasificados

        encontrarFinal = true;

      }

    }

    //Cierra el archivo que se indicó como entrada

    archivoEntrada.close();

    //Se establecen los "tokens" que contiene el archivo

    //Esto ayuda a eliminar espacios en blanco que sean innecesarios

    StringTokenizer st = new StringTokenizer(archivoLeidoCompleto);

    //Almacena el texto que se va construyendo con tildes y caracteres especiales

    //quitando espacios en blanco y etiquetas que no correspondan al formato XML

    String textoAnalizado= new String();

    //Cada hilera de caracteres o "token" identificado dentro del texto

    String tokenLeido = new String();

 

    //Variables para la manipulación y edición de tokens

    int tamanoToken=0;    // Tamaño de un token

    int posTokenInicio=0; // Inicio de un token

    String partePalInicial=""; // Prefijo de un token

    String partePalFinal="";   // Sufijo  de un token

 

    //Hacer mientras hayan palabras(tokens) que leer

    while (st.hasMoreTokens()) {

      //Leer el siguiente token  (hilera de caracteres)

      tokenLeido=st.nextToken();

      //Si dentro de la hilera leída se encuentra la hilera "0000"

      if((tokenLeido.indexOf("0000"))!=-1){

        //Si la hilera "0000" está al comienzo del token leído

        if (tokenLeido.startsWith("0000")) {

          //Se substituye la hilera leída por un salto de línea.

          textoAnalizado += '\n';

          //Si la hilera "0000" está en otra parte del token leído

        }else {

          //La hilera "0000" corresponde a un monto de dinero

          //Caso excepcional de un monto sin separador con , o .

          if((tokenLeido.indexOf("¢"))!=-1){

            posTokenInicio=tokenLeido.indexOf("¢");

            partePalInicial=tokenLeido.substring(0,posTokenInicio);

            partePalFinal=tokenLeido.substring(posTokenInicio+6);

            tokenLeido=partePalInicial+"¢"+partePalFinal;

          }

          //Caso presentado en un número telefónico contiene una hilera "0000"

          //seguido de <br> al final del token

          if(tokenLeido.endsWith("<br>")){

            tamanoToken=tokenLeido.length();

            tokenLeido=tokenLeido.substring(0,tamanoToken-4);

          }

          //La hilera leída se agrega al texto analizado dejando un espacio en blanco

          textoAnalizado += tokenLeido+" ";

        }

 

        //El token leído no contiene la hilera "0000"

      }else{

        //Si la hilera leida no es igual a "<br>" o "<BR>"

        if(!(tokenLeido.equalsIgnoreCase("<br>"))){

          //Si la hilera leida no es igual a "<p>" o "</p>" o "<P>" o "</P>"

          if(((tokenLeido.indexOf("<p>"))==-1)  && ((tokenLeido.indexOf("</p>"))==-1)) {

            //Antes de agregar la palabra verifica si termina en <br> para quitárselo

            if(tokenLeido.endsWith("<br>")){

              tamanoToken=tokenLeido.length();

              tokenLeido=tokenLeido.substring(0,tamanoToken-4);

            }

 

            //Se analizan tildes y caracteres especiales

            //Se reemplaza "&aacute;" por una a tildada

            //Busca la hilera "&aacute;" dentro del token

            while((tokenLeido.indexOf("&aacute;"))!=-1){

              //Se identifica la posicion dentro del token donde comienza la hilera buscada

              posTokenInicio=tokenLeido.indexOf("&aacute;");

              //Se extrae una sub-hilera desde el comienzo del token hasta donde comienza la hilera buscada

              partePalInicial=tokenLeido.substring(0,posTokenInicio);

              //Se extrae una sub-hilera desde el final de la hilera buscada hasta el final del token

              partePalFinal=tokenLeido.substring(posTokenInicio+8);

              //Concatena las dos sub-hileras con el caracter que substituye la hilera encontrada

              tokenLeido=partePalInicial+"á"+partePalFinal;

            }

 

            //Se reemplaza "&eacute;" por una e tildada

            //Busca la hilera "&eacute;" dentro del token

            while((tokenLeido.indexOf("&eacute;"))!=-1){

              posTokenInicio=tokenLeido.indexOf("&eacute;");

              partePalInicial=tokenLeido.substring(0,posTokenInicio);

              partePalFinal=tokenLeido.substring(posTokenInicio+8);

              tokenLeido=partePalInicial+"é"+partePalFinal;

            }

 

            //Se reemplaza "&iacute;" por una i tildada

            //Busca la hilera "&iacute;" dentro del token

            while((tokenLeido.indexOf("&iacute;"))!=-1){

              posTokenInicio=tokenLeido.indexOf("&iacute;");

              partePalInicial=tokenLeido.substring(0,posTokenInicio);

              partePalFinal=tokenLeido.substring(posTokenInicio+8);

              tokenLeido=partePalInicial+"í"+partePalFinal;

            }

 

            //Se reemplaza "&oacute;" por una o tildada

            //Busca la hilera "&oacute;" dentro del token

            while ( (tokenLeido.indexOf("&oacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&oacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "ó" + partePalFinal;

            }

 

            //Se reemplaza "&uacute;" por una u tildada

            //Busca la hilera "&uacute;" dentro del token

            while ( (tokenLeido.indexOf("&uacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&uacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "ú" + partePalFinal;

            }

 

            //Se reemplaza "&cent;" por signo de moneda

            //Busca la hilera "&cent;" dentro del token

            while ( (tokenLeido.indexOf("&cent;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&cent;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 6);

              tokenLeido = partePalInicial + "¢" + partePalFinal;

            }

 

            //Se reemplaza "&ntilde;" por signo eñe minúscula

            //Busca la hilera "&ntilde;" dentro del token

            while ( (tokenLeido.indexOf("&ntilde;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&ntilde;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "ñ" + partePalFinal;

            }

 

            //Se reemplaza "&Ntilde;" por signo eñe mayúscula

            //Busca la hilera "&Ntilde;" dentro del token

            while ( (tokenLeido.indexOf("&Ntilde;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Ntilde;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "Ñ" + partePalFinal;

            }

 

            //Se reemplaza "&iquest" por signo de interrogación de apertura

            //Busca la hilera "&iquest;" dentro del token

            while ( (tokenLeido.indexOf("&iquest;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&iquest;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "¿" + partePalFinal;

            }

 

            //Se reemplaza "&Egrave;" por E mayúscula

            //Busca la hilera "&Egrave;" dentro del token

            while ( (tokenLeido.indexOf("&Egrave;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Egrave;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "E" + partePalFinal;

            }

 

            //Se reemplaza "&Agrave;" por  A mayúscula

            //Busca la hilera "&Agrave;" dentro del token

            while ( (tokenLeido.indexOf("&agrave;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&agrave;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "á" + partePalFinal;

            }

 

            //Se reemplaza "&igrave;" por una i tildada

            //Busca la hilera "&igrave;" dentro del token

            while ( (tokenLeido.indexOf("&igrave;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&igrave;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "í" + partePalFinal;

            }

 

            //Se reemplaza "&ograve;" por una o tildada

            //Busca la hilera "&ograve;" dentro del token

            while ( (tokenLeido.indexOf("&ograve;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&ograve;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "ó" + partePalFinal;

            }

 

            //Se reemplaza "&Iacute;" por I mayúscula

            //Busca la hilera "&Iacute;" dentro del token

            while ( (tokenLeido.indexOf("&Iacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Iacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "I" + partePalFinal;

            }

 

            //Se reemplaza "&Uacute;" por U mayúscula

            //Busca la hilera "&Uacute;" dentro del token

            while ( (tokenLeido.indexOf("&Uacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Uacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "U" + partePalFinal;

            }

 

            //Se reemplaza "&Aacute;" por A mayúscula

            //Busca la hilera "&Aacute;" dentro del token

            while ( (tokenLeido.indexOf("&Aacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Aacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "A" + partePalFinal;

            }

 

            //Se reemplaza "&Eacute;" por E mayúscula

            //Busca la hilera "&Eacute;" dentro del token

            while ( (tokenLeido.indexOf("&Eacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Eacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "E" + partePalFinal;

            }

 

            //Se reemplaza "&iexcl;" por signo de exclamación de apertura

            //Busca la hilera "&iexcl;" dentro del token

            while ( (tokenLeido.indexOf("&iexcl;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&iexcl;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 7);

              tokenLeido = partePalInicial + "¡" + partePalFinal;

            }

 

            //Se reemplaza "&rsquo;" por comilla simple

            //Busca la hilera "&rsquo;" dentro del token

            while ( (tokenLeido.indexOf("&rsquo;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&rsquo;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 7);

              tokenLeido = partePalInicial + "'" + partePalFinal;

            }

 

            //Se reemplaza "&ldquo;" por comillas dobles

            //Busca la hilera "&ldquo;" dentro del token

            while ( (tokenLeido.indexOf("&ldquo;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&ldquo;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 7);

              tokenLeido = partePalInicial + '\"' + partePalFinal;

            }

 

            //Se reemplaza "&rdquo;" por comillas dobles

            //Busca la hilera "&rdquo;" dentro del token

            while ( (tokenLeido.indexOf("&rdquo;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&rdquo;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 7);

              tokenLeido = partePalInicial + '\"' + partePalFinal;

            }

 

            //Se reemplaza "&uuml;" por diéresis

            //Busca la hilera "&uuml;" dentro del token

            while ( (tokenLeido.indexOf("&uuml;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&uuml;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 6);

              tokenLeido = partePalInicial + "ü" + partePalFinal;

            }

 

            //Se reemplaza "&ordm;" por signo de grados

            //Busca la hilera "&ordm;" dentro del token

            while ( (tokenLeido.indexOf("&ordm;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&ordm;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 6);

              tokenLeido = partePalInicial + "º" + partePalFinal;

            }

 

            //Se reemplaza "&Oacute;" por O mayúscula

            //Busca la hilera "&Oacute;" dentro del token

            while ( (tokenLeido.indexOf("&Oacute;")) != -1) {

              posTokenInicio = tokenLeido.indexOf("&Oacute;");

              partePalInicial = tokenLeido.substring(0, posTokenInicio);

              partePalFinal = tokenLeido.substring(posTokenInicio + 8);

              tokenLeido = partePalInicial + "O" + partePalFinal;

            }

 

            //Después de substituir caracteres especiales

            //La hilera leída es una palabra válida dentro de un anuncio

            textoAnalizado += tokenLeido + " ";

          } //Final if de la hilera leida no es igual a "<p>" o "</p>" o "<P>" o "</P>"

        } //Final if de Si la hilera leida no es igual a "<br>" o "<BR>"

      } //Cierra elseif de búsqueda de hilera "0000"

    } //Final de while de tokenizar

 

    System.out.println("Finalizo acomodo de anuncios\n");

 

    //Se reutiliza variable para realizar concatenación para crear archivo XML

    archivoLeidoCompleto = "";

    //Escribe en un archivo de texto los anuncios clasificados parcialmente analizados

    PrintWriter escribirAcomodado = new PrintWriter(new BufferedWriter(new

        FileWriter("preClasificados.txt")));

    //Graba en el archivo de salida el contenido del texto analizado (anuncios publicitarios)

    escribirAcomodado.println(textoAnalizado);

    //Cierra el archivo que contiene los anuncios clasificados

    escribirAcomodado.close();

 

    //Leer el archivo que contiene el listado de los anuncios clasificados

    BufferedReader preClasif = new BufferedReader(new FileReader(

        "preClasificados.txt"));

    //Mientras lee el archivo con los clasificados, crea estructura XML agregando etiquetas correspondientes

    //Reutilizando la variable de archivoLeidoParcial

 

    while ( (archivoLeidoParcial = preClasif.readLine()) != null) {

      //Cada anuncio lo delimita dentro de la etiqueta de anuncio

      archivoLeidoCompleto += "<anuncio>" + archivoLeidoParcial + "</anuncio>" +

          '\n';

    }

    //Cierra el archivo XML que se ha generado

    preClasif.close();

 

    System.out.println("Se graba archivo de preClasificados.txt");

 

    miLista.InsertarEnClasificacion();

    //miLista.ImprimirClasificacion();

 

    try {

      textoAnalizado = "";

      //Encabezado característico de un archivo XML

      String archivoXMLinicio = "<?xml version=" + '\"' + "1.0" + '\"' +

          " encoding=" + '\"' + "iso-8859-1" + '\"' + "?>" + '\n'

          + "<!-- Anuncios clasificados del Diario Extra -->" + '\n'

          + "<Clasificados>" + '\n'

          + "<Listado_General>" + '\n';

 

      //Cierre del archivo XML

      String archivoXMLfinal = "</Listado_General>" + '\n'

          + "<Listado_Especifico>" + '\n' + "Todavía no catalogado" +

          "</Listado_Especifico>" + '\n' + "</Clasificados>" + '\n';

      //Crea el archivo XML

      PrintWriter escribirXML = new PrintWriter(new BufferedWriter(new FileWriter(archivoOriginal+".xml")));

      //Graba en el archivo de salida el contenido del texto analizado (anuncios publicitarios)

      textoAnalizado = archivoXMLinicio + miLista.GeneradorXMLClasificacion() + archivoXMLfinal;

      //Escribe en el archivo XML el resultado de todas las concatenaciones

      escribirXML.println(textoAnalizado);

      //Cierra el archivo que contiene los anuncios publicitarios

      escribirXML.close();

      System.out.println("Se graba archivo "+archivoOriginal+".xml");

    }

    catch (EOFException e) {

      System.out.println("Final de Stream");

    }

  } //Fin de main

}

 

 

package traductor;

 

//Clase que permite manipular la lista de anuncios (articulos) economicos

public class ListaArticulo {

  private NodoArticulo primero; //apuntador al primer elemento de la lista

  private NodoArticulo ultimo;  //apuntador al ultimo elemento de la lista

 

  //Constructo de la clase artìculo

  public ListaArticulo() {

    primero = ultimo = null; //Como no hay elementos primero y ultimo apuntan a null

  }

 

  //Permite insertar un elemento en la lista de artìculos al inicio de la lista

  //Recibe el nombre del articulo y la descripcion

  public void InsertarArticulo (String nombreA, String descripcionA) {

    if (EstaVacio()) { //si no hay elementos

      primero = new NodoArticulo(nombreA, descripcionA);

      ultimo = primero;

    }else { //si hay elementos en la lista

      primero = new NodoArticulo(nombreA, descripcionA,primero); //inserta al inicio

    }

  }

 

  //Imprime la lista de articulos en la lista tanto el nombre como la descripcion

  public void ImprimirArticulo() {

    NodoArticulo temp = primero; //temp es un puntero que permite moverse por la lista

    while (temp != null) { //Mientra no encuentre el final de la lista

      System.out.print(temp.ObtenerNombre() + "\n"); //despliega el nombre

      System.out.print(temp.ObtenerDescripcion() + "\n"); //despliega la descripcion

      temp = temp.sigAbajo; //Se mueve al siguiente articulo

    }

  }

 

  public String GeneradorXMLArticulo() {

    NodoArticulo temp = primero; //temp es un puntero que permite moverse por la lista

    String cadenaArticulos = "";

    while (temp != null) { //Mientra no encuentre el final de la lista

      cadenaArticulos += "\t<anuncio>"+"\n\t"+temp.ObtenerNombre()+"\n</anuncio>\n";

//      System.out.print(temp.ObtenerDescripcion() + "\n"); //despliega la descripcion

      temp = temp.sigAbajo; //Se mueve al siguiente articulo

    }

    return cadenaArticulos;

  }

 

  //Verifica si la lista esta vacia, si es asì retorna true sino false

  public boolean EstaVacio() {

    return primero == null;

  }

}

 

 

package traductor;

import java.io.*;

import java.util.*;

 

//Clase que permite incluir en una lista las clasificaciones de los anuncios

//y procesar dicha lista para poder insertar los anuncios en las clasificaciones

public class ListaClasificacion {

  int TAM_DICCIONARIO = 25;

  private NodoClasificacion primero; //apuntador al primer nodo de la lista

  private NodoClasificacion ultimo;  //apuntador al ultimo nodo de la lista

 

  //Constructor de la clase

  public ListaClasificacion() {

    primero = ultimo = null; //No hay elementos en la lista

  }

 

  //Crea un nodo donde inserta el nombre de la clasificacion y su correspondiente

  //diccionario (asociacion)

  //La asociacion son un conjunto de palabras que describen a la Clasificacion

  public void InsertarClasificacion (String nombreC, String asociacion[]) {

    if (EstaVacio()) {  //Si no hay elementos en la lista

      primero = new NodoClasificacion(nombreC, asociacion); //Inserta al inicio

      ultimo = primero;

    }else {  //Si hay elementos en la lista

      primero = new NodoClasificacion(nombreC, asociacion,primero);

    }

  }

 

  //Imprime la Clasificacion con sus correspondientes anuncios

  public void ImprimirClasificacion() {

    NodoClasificacion temp = primero;

    while (temp != null) {

      System.out.print(temp.ObtenerNombre() + "\n");

      temp.listaDeArticulos.ImprimirArticulo();

      temp = temp.sig;

    }

  }

 

  //Genera la clasificacion del XML

  public String GeneradorXMLClasificacion() {

    NodoClasificacion temp = primero;

    String clasificacionGenerada = "";

    while (temp != null) {

      clasificacionGenerada += "<"+temp.ObtenerNombre()+">"+"\n"+temp.listaDeArticulos.GeneradorXMLArticulo()+"</"+temp.ObtenerNombre()+">\n";

      temp = temp.sig;

    }

    return clasificacionGenerada;

  }

 

  //Verifica si la lista esta vacia

  public boolean EstaVacio() {

    return primero == null;

  }

 

  //Lee desde un archivo llamado "TipoClasificacion.txt" las diferentes

  //clasificaciones y sus descriptores y los inserta en una lista

  public void HacerClasificacion() throws IOException {

    //Lee el archivo y lo asigna a la variable "archivo"

    BufferedReader archivo = new BufferedReader(new FileReader("TipoClasificacion.txt"));

    //Variables para el manejo del contenido del archivo leído

    String clasificacionLeida = new String();

    String nombreClasificacion;

 

    String parametro[] = new String[TAM_DICCIONARIO];

 

    //Limpia vector

    for (int i = 0; i<TAM_DICCIONARIO;i++) {

      parametro[i] = "ñññññññññññññññ";

    }

 

    //Recorre cada linea del "archivo" para poder extraer la clasificacion

    //y sus descriptores

    while ((clasificacionLeida = archivo.readLine()) != null) {

      StringTokenizer token = new StringTokenizer(clasificacionLeida);

//      token.countTokens();

      nombreClasificacion = token.nextToken();

      int palabra = 0;

      //Mientras existan palabras en el diccionario

      while (token.hasMoreTokens()) {

        parametro[palabra]= token.nextToken();

        palabra++;

      }

      //Inserta la clasificacion y los descriptores en una lista

      //los descriptores se insertan en un vector

      InsertarClasificacion(nombreClasificacion,parametro);

      //Limpia vector, se asume que no hay descriptores que sean lineas de letra ñ

      for (int i = 0; i<TAM_DICCIONARIO;i++) {

        parametro[i] = "ñññññññññññññññ";

      }

    }

    archivo.close();  //cierra el archivo

  }

 

  //A la lista de clasificaciones inserta una nueva lista que almacena por cada clasificacion

  //los anuncios que correspondan a esta comparandola con el diccionario que tiene cada

  //clasificacion

  public void InsertarEnClasificacion() throws IOException {

    //Lee el archivo preclasificados

    BufferedReader archivoPreclasificado = new BufferedReader(new FileReader("preClasificados.txt"));

    //Representa a los anuncios publicados

    String anuncioLeido = new String();

    int lin=1;

    //Se comienza a revisar a partir del primer nodo de la lista de Clasificacion

      //asignandolo a un nodo que permita moverse por la lista

    NodoClasificacion nodoTemporal = primero;

 

    while ((anuncioLeido = archivoPreclasificado.readLine()) != null) {

      System.out.print("Anuncio procesado "+lin+'\n');

      lin++;

 

      //Si el anuncio se incluye en una clasificacion se inicializa de nuevo

      //el apuntador al primer elemento para que revise si el siguiente anuncio

      //tambien se encuentra en esa clasificacion

      nodoTemporal = primero;

      //Indice que permite moverse por el vector que se encuentra en la lista de clasificaciones

      //para poder compararse con alguna palabra que se encuentra en el anuncio

      int palabraIndice = 0;

      //Dice si el anuncio pertenece a una clasificacion

      boolean encontrado = false;

      //Permite recorrer cada una de las clasificaciones

      while ((nodoTemporal!=ultimo)&&(encontrado==false)){

        //Permite recorrer el diccionario

        while ((palabraIndice < TAM_DICCIONARIO) && (encontrado == false)) {

          //Revisa si alguna de las palabras del anuncio están en el diccionario

          //de la clasificacion que se esta revisando

          if (anuncioLeido.indexOf(nodoTemporal.parametro[palabraIndice])==-1) {

            //System.out.print("Revisando clasificacion: "+nodoTemporal.nombreClasificacion+'\n');

            //System.out.print("         comparando con: "+nodoTemporal.parametro[palabraIndice]+'\n');

            palabraIndice++;  //Si no corresponde a la primera palabra del diccionario avanza a la siguiente

            }else {  //Si alguna palabra del anuncio corresponde a alguna del diccionario

              encontrado = true;

            }

          }

          // Si no termino de recorrer el arreglo de palabras para hacer la clasificacion

          // quiere decir que si se puede clasificar el anuncio

          if (encontrado==true) {

            nodoTemporal.listaDeArticulos.InsertarArticulo(anuncioLeido,"");

          }else{  //Si el anuncio no corresponde a la actual Clasificacion

            nodoTemporal=nodoTemporal.sig;

          }

          //Se inicializa el indice del arreglo para reiniciar la busqueda

          palabraIndice=0;

        }

        // Si el aviso clasificado no se pudo insertar en una categoría específica.

        // Se inserta en una denominada "VARIOS"

        if(nodoTemporal==ultimo){

          nodoTemporal.listaDeArticulos.InsertarArticulo(anuncioLeido,"");

        }

      }

      archivoPreclasificado.close();  //cierra el archivo de PreClasificados

    }

}

 

 

package traductor;

 

//Clase que contiene la definicion y manipulacion de los nodos de la Lista

//de Articulos

public class NodoArticulo {

  protected String nombreArticulo = new String();  //almacena el nombre del anuncio

  protected String descripcionArticulo = new String();  //almacena la descripcion del anuncio

  protected NodoArticulo sigAbajo;  //apuntador al siguiente anuncio

 

  //constructores

  public NodoArticulo(String nombreA, String descripcionA) {

    this.nombreArticulo = nombreA;

    this.descripcionArticulo = descripcionA;

    sigAbajo = null;

  }

 

  //Constructor que para asignar un articulo si la lista tiene elementos

  public NodoArticulo(String nombreA, String descripcionA,NodoArticulo sigNodoAbajo) {

    this.nombreArticulo = nombreA;

    this.descripcionArticulo = descripcionA;

    this.sigAbajo = sigNodoAbajo;

  }

 

  //Devuelve el nombre del anuncio

  public String ObtenerNombre() {

    return nombreArticulo;

  }

 

  //Devuelve la descripcion del anuncio

  public String ObtenerDescripcion() {

    return descripcionArticulo;

  }

 

  //Devuelve el siguiente anuncio

  public NodoArticulo ObtieneSigAbajo() {

    return sigAbajo;

  }

}

 

 

package traductor;

 

//Clase que manipula las clasificaciones

public class NodoClasificacion {

  int TAM_DICCIONARIO = 25;

  protected String nombreClasificacion;  //almacena el nombre de la clasificacion

  protected String parametro[] = new String[TAM_DICCIONARIO];  //almacenael diccionario

  protected NodoClasificacion sig;  //apuntador a la siguiente clasificacion

  protected ListaArticulo listaDeArticulos;  //apuntador a la lista de articulos

 

  //constructores

  public NodoClasificacion(String nombreC, String asociador[]) {

    this.nombreClasificacion = nombreC;

 

    for (int i=0;i<TAM_DICCIONARIO;i++)

      this.parametro[i] = asociador[i];

 

    sig = null;

    //Por cada clasificacion crea su correspondiente lista de articulos

    ListaArticulo unaLista = new ListaArticulo();

    this.listaDeArticulos = unaLista;

  }

 

  //Constructor que sirve cuando hay mas clasificaciones

  public NodoClasificacion(String nombreC, String asociador[],NodoClasificacion sigNodo) {

    this.nombreClasificacion = nombreC;

    for (int i = 0; i<TAM_DICCIONARIO;i++) {

      this.parametro[i] = asociador[i];

    }

    this.sig = sigNodo;

    //Por cada clasificacion crea su correspondiente lista de articulos

    ListaArticulo unaLista = new ListaArticulo();

    this.listaDeArticulos = unaLista;

  }

 

  //Devuelve el nombre de la clasificacion

  public String ObtenerNombre() {

    return nombreClasificacion;

  }

 

  //Devuelve el diccionario de la clasificacion

  public String ObtenerParametro() {

    String hilera = "";

    for (int i = 0; i<TAM_DICCIONARIO;i++) {

      hilera += parametro[i]+", ";

    }

    return hilera;

  }

 

    //Devuelve la siguiente clasificacion

  public NodoClasificacion ObtieneSig() {

    return sig;

  }

}


Bibliografía

 

Deitel & Deitel. ¿Cómo Programar en Java?, 5th Edición. McGraw Hill Año de publicación: 2003

 

Aho, Alfred. Hopocroft, John, Ullman Jeffrey. Estructuras de datos y algoritmos. 1era Edición. Addison Wesley. 1998

Hosted by www.Geocities.ws

1