Capítulo 17. Edición de un documento XML con Revolution

Tabla de contenidos
Introducción
Conclusiones

Este capítulo se dedicará a editar el fichero, ocultando al usuario la necesidad de manejarse con las etiquetas. La solución y el comentario de la misma son fruto del trabajo realizado por Marcela Martín.

El problema planteado se ha ido abordando en base a etapas que nos permitan alcanzar el objetivo propuesto. Muchas han sido las etapas de experimentación que se han ido cubriendo y, al final, se ha ido dejando visibles únicamente los campos de interés para la interacción con el usuario. El orden ha sido:

Por la necesidad de probar trozos de código y funciones de manera aislada, se han utilzado campos de texto en lugar de variables como contenedores de información para el paso de información entre objetos. Unido esto a la utilización del evento mouseUp ha permitido, en cualquier momento del desarrollo, reiniciar las veces que hiciera falta la ejecución de las órdenenes contenidas en un botón. De esta manera se ha ido avanzando en la comprensión y verificación del código empleado.

Hay que decir que debido al gran número de nuevas funciones y a la cantidad de detalles que se abordan en este trabajo se han ido realizando una serie de etapas intermedias que nos permitan acceder a cada uno de los posibles nodos y su formato que nos pudieran aparecer en función de la DTD (en nuestro caso se ha expuesto ya en la xref linkend="seccioTrabajandoConXML">) utiilzada.

Por ello ha habido que ir abordado de manera constructiva el problema. En la Figura 17-1 se desglosa el contenido de las mismas, así que aquí me limitaré a reconstruir el planteamiento inicial y dejaré en las propias palabras de Marcela la explicación de esta solución concreta.

Figura 17-1. Ejemplos de las etapas intermedias donde primaba el aspecto de desarrollo. Se han incluido para que ser aprecie la diferencia entre la etapa de desarrollo y el resultado final.

Finalmente, al usuario le ofreceremos una manera de acceder a un fichero XML, con un formato dado y cerrado, para poder editarlo sin necesidad de implicarlo en aprender esta rígida estructua que impone XML. Le recuerdo que queremos obtener una transformación del contenido de un cierto fichero de partida, como el mostrado, con una interfaz sencilla

Figura 17-2. Ejemplos de fichero XML: contenido del mismo antes y después de la edición con la herramienta que desarrollamos aquí.

Introducción

La idea de empezar este proyecto surge con la inclusión de la librería (XML Lib.rev) para majenar XML en Revolution 2.0. Dicha librería pone a nuestra disposición una serie de funciones que permiten manipular y procesar documentos xml. Resulta muy interesante dada la importancia y auge del XML estudiar estas funciones, y aplicarlas para comprobar su funcionamiento y las posibilidades que ofrecen.

Por tanto el objetivo principal de este trabajo es estudiar un caso en concreto: procesar un documento XML con una determinada estructura y sentar las bases para que a partir de este se puedan abordar proyectos más ambiciosos y complejos. En el procesamiento del caso de estudio se pretende resolver los siguientes puntos:

Funciones de la librería XML utilizadas

A continuación se detalla la sintáxis de las funciones utilizadas para el desarrollo de la aplicación.Para hacer referencia a un nodo, se hablará indistintamente de la `posición del nodo', `ruta del nodo', o simplemente `nodo'

  • revXMLCreateXMLTree(DatosXML, BienFormado,CrearArbol,EnvioMsgs)

    Con esta función se crea la estructura de árbol correspondiente a los datos que se indican en el primer parámetro. Es imprescindible la ejecución de esta función en primer lugar, puesto que para trabajar y procesar cualquier documento xml con Revolution 2.0 este debe estar previamente cargado en memoria.

    DatosXML: es una cadena de caracteres que indica los datos a partir de los cuales hay que crear el árbol. En nuestro caso, será el contenido de un campo de texto en el que se habrá volcado el contenido de un documento xml.

    BienFormado: es un booleano con el que se indica si queremos analizar o no la estructura del árbol. Si tiene valor "true" se comprobará que la estructura de los datos pasados en el primer parámetro está bien formada. Si tiene valor "false" se detendrá la ejecución si la estructura es incorrecta.

    CrearArbol : con este parámetro se indica si queremos que se cree efectivamente el árbol en memoria (true) o si simplemente queremos analizar la estructura (false).

    EnvioMsgs: es un booleano, si tiene valor "true" se enviarán mensajes informativos durante el análisis del documento xml. Si por el contrario tiene valor "false" no se enviarán mensajes.

    Después de la ejecución de esta función, y en el caso de que se haya creado un árbol en memoria (CrearArbol = true), se obtiene como resultado el identificador del árbol recién creado, esto es, un entero. Será importantísimo conocer el valor del identificador de un árbol para trabajar posteriormente con él.

  • revXMLRootNode(IdArbol)

    Con esta función se obtiene la ruta del nodo raíz del árbol cuyo identificador pasamos como parámetro.Este es un buen momento para indicar que para hacer referencia a cualquier nodo del árbol será de mucha ayuda tener clara cual es la ruta (secuencia de nodos) en la que se encuentra.

  • revXMLFirstChild(IdArbol, RutaNodo)

    Con esta función se obtiene la ruta del primer hijo del nodo cuya ruta se pasa como segundo parámetro, para el árbol indicado en el primer parámetro.

  • revXMLNodeContents (IdArbol, RutaNodo)

    Esta función devuelve el contenido del nodo pasado como segundo parámetro, siempre para el árbol indicado en el primer parámetro.

  • revXMLNextSibling(IdArbol, RutaNodo)

    Devuelve la posición del nodo hermano del nodo pasado como segundo parámetro, pertenecientes ambos al árbol indicado en el primer parámetro.

  • revXMLNumberOfChildren(IdArbol, RutaNodo,NombreHijo, Profundidad)

    Devuelve el número de hijos del nodo pasado como segundo parámetro, en el árbol indicado en el primer parámetro.

    NombreHijo: es una cadena de caracteres que especifica qué nodo hijo queremos contar. Es decir, si el parámetro se lo pasamos vacío, serán contados todos los nodos hijos. En cambio, si contiene una cadena de caracteres, solo serán contados los nodos hijos cuyo nombre coincida con dicha cadena.

    Profundidad:indica el nivel de profundidad que se alcanzará a la hora de contar los hijos de un nodo. Con valor 0 se cuentan los hijos del nodo indicado en RutaNodo.

    Con valores mayores que 0 se indica el número de niveles que se desea profundizar al contar. Si tiene valor-1 se contarán todos los hijos hasta llegar al último nivel.

  • revXMLAttribute(IdArbol, RutaNodo, NombreAtributo) Devuelve el valor del atributo indicado en el tercer parámetro, atributo que debe existir en el nodo indicado en el segundo parámetro, dentro del árbol indicado en el primer parámetro.

  • revDeleteXMLNode IdArbol, RutaNodo Esta función borra el nodo indicado en el segundo parámetro, como siempre, para el árbol pasado como primer parámetro de la función.

  • revAddXMLNode IdArbol, RutaNodoPadre, NombreNuevoNodo, Contenido En el árbol referenciado en el primer parámetro, esta función añade un nodo hijo al nodo indicado en el segundo parámetro, con nombre y contenido pasados como tercer y cuarto parámetros respectivamente.

  • revSetXMLAttribute IdArbol, RutaNodo, NombreAtributo, NuevoContenido Con esta función se actualiza en el nodo RutaNodo el valor del atributo (NombreAtributo) con el valor pasado en NuevoContenido.

  • revPutIntoXMLNode IdArbol, RutaNodo, NuevoContenido

    Se utilizta esta función para modificar/actualizar el contenido de un determinado nodo. Para el árbol referenciado en IdArbol, se pone el valor NuevoContenido en el nodo RutaNodo.

  • revPutXMLText (IdArbol, RutaNodo)

    Con esta función se hace posible el pasar un árbol que está en memoria a un documento de texto. La utilizaremos para guardar las modificaciones realizadas al documento cargado. Internamente se modifica el árbol creado a partir del documento, y posteriormente se vuelca el nuevo árbol a un documento de texto que al tener el mismo nombre que el inicial y ubicarse en la misma ruta, sobreescribirá al anterior.

    Como parámetros se referencia el árbol en primer lugar, y como segundo parámetro, se indica el nodo a partir del cual se quiere crear el documento de texto. Cuando este segundo argumento estávacío se toma como nodo inicial la raíz del árbol.

    En relación a esta sintaxis señalar que aunque en la ayuda se indica que se puede pasar solo el primer parámetro, en la práctica es necesario pasar ambos parámetros, y en caso de que se quiera volcar todo el árbol, simplemente dejar el segundo parámetro vacío. diseño. En el diseño de la pila ` Documento XML' se distinguen cuatro operaciones principales:

    • Cargar fichero : Cargar un documento XML y visualizar su estructutra y contenido de nodos en los correspondientes campos de la pila.

    • Modificar Resumen : procesar un conjunto de un número variable de hijos.

    • Modificar Grupo: procesar un conjunto de un número variable de hijos cuyos nodos pueden tener atributos.

    • Actualizar el título.

    Cada una de estas partes incluye la utilización de varios botones y campos de texto. En el siguiente apartado se detalla el diseño y funcionamiento.

Detalles en el diseño de la pila `Documento XML'

El documento cargado deberá tener las etiquetas que se detallan en el ejemplo siguiente, comentar que tanto el resumen (número de parráfos) como el grupo (número de componentes) pueden tener longitud variable, incluso quedar vacíos, con la posibilidad de añadir lineas mediante la aplicación desarrollada y Revolution 2.0. El valor incial del documento puede ser:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Trabajo>
   <Titulo>DOCUMENTO XML</Titulo>
   <Introduccion>
      <Resumen>
       <Parrafo>Parrafo numero 1.</Parrafo>
       <Parrafo>Este es el segundo parrafo de prueba.</Parrafo>
      </Resumen>
   </Introduccion>
    <Grupo>
     <Componente>
        <Nombre>Alberto   </Nombre>
        <Datos Correo="email@mimail.com"/>
       <foto Fichero=" f1.jpgt" Ancho="1" Alto="1"/>
    </Componente>
   </Grupo>
</Trabajo>
                         

Se distinguen cuatro operaciones principales lanzadas por cada uno de los botones que aparecen en la ficha:

  1. Cargar fichero. Al hacer click sobre este botón, se desencadenan una serie de acciones. En concreto el script que está asociado al evento mouseUp del botón `Cargar fichero' se detalla a continuación y a partir de este, el resto de botones implicados en la acción:

    on mouseUp
      put empty into fld "Titulo" 
      put empty into fld "Parrafos"
      put empty into fld "Componentes"
      answer file "Abrir Ficha"
      if it <> empty then
        put it into fld "NombreFichero"
        send "mouseUp" to btn "AbrirFichero"
        send "mouseUp" to btn "AbrirResumen"
        send "mouseUp" to btn "AbrirGrupo"
     end if
    end mouseUp
                         

    La finalidad de este botón es la de cargar el fichero xml que seleccione el usuario, crear su árbol asociado, y mostrar el contenido del mismo en los campos introducidos para tal fin.Incialmente se limpia el contenido de los campos que contienen el título, el resumen y los datos del grupo del archivo cargado.

    Se pide al usuario que seleccione el fichero xml que desea procesar, y se guarda la ruta de la ubicación del fichero en el campo `NombreFichero'. Esta información será útil al grabar las modificaciones para indicar la ubicación del fichero que se va a sobreescribir. El contenido del fichero XML se vuelca en el campo "FicheroActual". Si se ha seleccionado un fichero XML se lanza la ejecución de los scripts asociados al evento mouseUp de una serie de botones que permanecen ocultos y que se explican a continuación.

    Esta solución (dividir los pasos en lo que se podría asemejar a una subrutina) es necesaria puesto que en la `Free Edition' de Revolution 2.0 no está permitido escribir scripts de más de 10 instrucciones (recuerdo que estas pueden ocupar más de otras tantas líneas). De todos modos, se puede aprovechar esta limitación, pues fuerza a trabajar pensando primero y buscando la estructuración y ordenación de los pasos implicados en el desarrollo y diseño de la aplicación.

    • Abrir Fichero

      on mouseUp
        -- Crea el árbol en memoria a partir del fichero, y devuelve el identificador
        -- asignado (IdActual)
        put revCreateXMLTree(field "FicheroActual","false", true, false) into fld "IdActual"
        -- Pone la ruta del nodo raíz en el campo `Raiz'
        put revXMLRootNode(fld "IdActual" ) into fld "Raiz"
        --Vuelca la ruta del primer hijo (título) de la raíz en el campo `RutaTitulo'
        put revXMLFirstChild(fld "IdActual",  fld "Raiz") into fld "RutaTitulo"
        --Vuelca el contenido del Titulo en el campo `Titulo'
        put revXMLNodeContents(fld "IdActual",fld "RutaTitulo") into fld "Titulo"
        --Vuelca la ruta del nodo hermano del título (Introducción) en el campo `RutaIntro'
        put revXMLNextSibling(fld "IdActual",  fld "RutaTitulo" ) into fld "RutaIntro"
        --Vuelca la ruta del primer hijo de 'Introduccion' (nodo 'Resumen') en el 
        --campo `RutaResumen'
        put revXMLFirstChild(fld "IdActual",  fld "RutaIntro") into fld "RutaResumen"
      end mouseUp
                           
    • Abrir Resumen

      on mouseUp
        --Contar párrafos del resumen y almacenar el número en `NumeroDeParrafos'
        -- Si hay párrafos:
        if fld "NumeroDeParrafos" <> 0 then
          -- Almacena la ubicación del primer parrafo en `RutaParrafo1'
          put revXMLFirstChild(fld "IdActual",  fld "RutaResumen") into fld "RutaParrafo1"
          --Limpiar el contenido del campo de texto Parrafos para ir añadiendo los del documento.
          put empty into fld "Parrafos"
          --Añade al campo `Parrafos' el contenido de cada uno de los párrafos del documento
          -- Se añade el primer parrafo (RutaParrafo1)
          put revXMLNodeContents(fld "IdActual",fld "RutaParrafo1") && return after fld "Parrafos"
          put fld "RutaParrafo1" into fld "RutaParrafoAct"
          --bucle de hijos para ir añadiendo parrafos (menos el primero)
          put fld "NumeroDeParrafos"-1 into fld "Iteraciones" 
          repeat until fld "Iteraciones"=0
            put revXMLNextSibling(fld "IdActual",  fld "RutaParrafoAct" ) into fld "RutaParrafoAct"
            put revXMLNodeContents(fld "IdActual",fld "RutaParrafoAct") && return after \
                     fld "Parrafos"
            put fld "Iteraciones"-1 into fld "Iteraciones"
         end repeat
       end if
      end mouseUp
                           
    • Abrir Grupo

      on mouseUp
         -- buscar el siguiente nodo hijo de trabajo, es decir, nodo grupo(hermano de Introduccion)
         put revXMLNextSibling(fld "IdActual",  fld "RutaIntro" ) into fld "RutaGrupo"
         --Contar componentes del grupo y almacenar el numero en `NumeroDeComponentes'
         -- Si hay componentes:
          if fld "NumeroDeComponentes" <> 0 then
            --Almacena la ubicación del primer componente (RutaComponente1)
            put revXMLFirstChild(fld "IdActual",  fld "RutaGrupo") into fld "RutaComponente1"
            -- Limpia el contenido del campo que contiene los datos de los componentes del grupo.
            put empty into fld "Componentes"
            --Primer componente como componente actual
            put fld "RutaComponente1" into fld "RutaComponenteAct"
            --bucle de hijos para ir añadiendo componentes
            put fld "NumeroDeComponentes" into fld "Iteraciones" 
         end if
      end mouseUp
                           
    • Abrir Componentes

      on mouseUp
        --Para cada componente
        repeat until fld "Iteraciones"=0
          -- cada componente debe tener las etiquetas de nombre, datos y foto.
          -- busca el primer nodo hijo del componente actual (nombre)
          put revXMLFirstChild(fld "IdActual",  fld "RutaComponenteAct") into fld "RutaNombreAct"
          -- muestra el contenido del primer hijo (Nombre)
          put revXMLNodeContents(fld "IdActual",fld "RutaNombreAct") && "," after \
                  fld "Componentes"
          -- busca el siguiente hijo del componente actual
          put revXMLNextSibling(fld "IdActual",  fld "RutaNombreAct" ) into fld "RutaDatosAct"
          -- muestra el contenido del segundo hijo (Datos)
          put revXMLNodeContents(fld "IdActual",fld "RutaDatosAct") && ","after \
                 fld "Componentes"
          -- busca el tercer nodo hijo (foto)
          put revXMLNextSibling(fld "IdActual",  fld "RutaDatosAct" ) into fld "RutaFotoAct"
          -- entre las etiquetas del nodo 'foto' no hay valor (empty) pero sí hay que mostrar
          -- los atributos
          send "mouseUp" to btn "MuestraAtributos"
          -- siguiente componente como actual
          put revXMLNextSibling(fld "IdActual",  fld "RutaComponenteAct" ) into \
                 fld "RutaComponenteAct"
          put fld "Iteraciones"-1 into fld "Iteraciones"
        end repeat
      end mouseUp
                           
    • Muestra Atributos

      on mouseUp
        --muestra el primer atributo de foto: 'fichero'
        put revXMLAttribute(fld "IdActual", fld "RutaFotoAct", "Fichero")  && ","after fld "Componentes"
        -- muestra el segundo atributo de foto: 'alto'
        put revXMLAttribute(fld "IdActual", fld "RutaFotoAct", "Alto")  && ","after fld "Componentes"
        --muestra el tercer atributo de foto: 'ancho'
        put revXMLAttribute(fld "IdActual", fld "RutaFotoAct", "Ancho")  &&  return after fld "Componentes"
      end mouseUp
                           
  2. Actualizar resumen. Después de modificar el contenido del resumen: añadir, quitar o modificar párrafos (los parráfos se separan por retornos de carro), será necesario hacer click en el botón `Actualizar Resumen' para que dichos cambios se efecttúen. Como en el caso anterior, el script asociado a este botón lanza la ejecución de otros asociados a eventos mouseUp de botones ocultos.

    on mouseUp
      send "mouseUp" to btn "BorrarResumen"
      send "mouseUp" to btn "ActualizarResumen"
      send "mouseUp" to btn "Grabar"
    end mouseUp
                         

    Para guardar el resumen modificado se borrarán primero todos los nodos 'Parrafo' del árbol cargado en memoria (no actualizado) para después ir añadiendo tantos nodos `Parrafo' como líneas haya en el campo `Parrafos'. Finalmente se sobreescribirá el fichero inicial por el generado a partir del árbol recién actualizado con la función `revXMLText(Id)', es decir, la acción asociada al botón `Grabar' que se detallará más adelante.

    • Borrar Resumen

      on mouseUp
        --Contar el número de párrafos del árbol en memoria (no actualizado)
        --Borrar todos los parrafos:
        repeat until fld "Iteraciones" = 0
           revDeleteXMLNode fld "IdActual",fld "RutaParrafo1"
          put fld "Iteraciones"-1 into fld "Iteraciones"
        end repeat
      end mouseUp
                            
    • Actualizar Resumen

      on mouseUp
        --Contar el número de líneas del resumen modificado
        put the number of lines of the fld "Parrafos" into fld "NumeroLineas" 
        -- Añadir tantos parrafos como lineas hay
        put 1 into fld "Iteraciones"
        repeat until fld "Iteraciones"= fld "NumeroLineas"+1
          --ínea actual del resumen para luego añadir un nodo parrafo con dicho contenido.
          put the line(fld "Iteraciones") of the text of fld "Parrafos" into fld "NuevaLinea"
          revAddXMLNode fld "IdActual",fld "RutaResumen","Parrafo",fld "NuevaLinea"
          put fld "Iteraciones"+1 into fld "Iteraciones"
        end repeat
      end mouseUp
                            
  3. Actualiza grupo. De forma similar al procesamiento del resumen del documento, se procesan los componentes del grupo. En este caso, se añade el tratamiento de los atributos de los nodos `foto', estos atributos pueden estar vacíos. Se modificarán desde el campo `Componentes', el cual contendrá información que se debe introducir teniendo en cuenta los siguientes criterios:

    • Cada línea contiene la información de un componente del grupo.

    • Para cada línea se distinguen cinco campos que deberán separarse por comas:

      1. Nombre.

      2. Datos.

      3. Ruta del archivo que contiene la foto.

      4. Ancho de la foto.

      5. Alto de la foto.

      Como en el caso del resumen, la información sobre los componentes del grupo se guardará cuando se haga click en el botón `Actualiza Grupo'. A continuación se detalla el funcionamiento.

      on mouseUp
        send "mouseUp" to btn "BorrarComponentes"
        send "mouseUp" to btn "CrearComponentes"
        send "mouseUp" to btn "Grabar"
      end mouseUp
                            

    • Borrar Componentes

      on mouseUp
      --Contar número de componentes
        put fld "NumeroDeComponentes" into fld "Iteraciones"
      --Borrar todos los componentes:
        repeat until fld "Iteraciones" =0
          revDeleteXMLNode fld "IdActual",fld "RutaComponente1"
      put fld "Iteraciones"-1 into fld "Iteraciones"
        end repeat
      end mouseUp
                            
    • Crear Componentes

      on mouseUp
      --Contar número de líneas en el campo `Componentes'
      put the number of lines of the fld "Componentes" into fld "NumeroLineas" 
      -- Si hay líneas
      if fld "NumeroLineas"<>0 then
      -- Añadir tantos componentes como lineas hay
      put fld "NumeroLineas" into fld "Iteraciones"
      repeat until fld "Iteraciones"= 0
      -- Los nodos componente no tienen datos entre etiquetas, sino tres atributos.
            revAddXMLNode fld "IdActual",fld "RutaGrupo","Componente",""
      put fld "Iteraciones"-1 into fld "Iteraciones"
          end repeat
          send "mouseUp" to btn "ActualizaInfComponentes"
        end if
      end mouseUp
                            
    • Actualiza Componentes 2

      on mouseUp
        put 1 into fld "Iteraciones"
        -- Localiza el componente actual y repetir para cada uno:
        put revXMLFirstChild(fld "IdActual",  fld "RutaGrupo") into fld "RutaComponente1"
        put fld "RutaComponente1" into fld "RutaComponenteAct"
        repeat until fld "Iteraciones"= fld "NumeroLineas"+1
          if fld "Iteraciones"<>1 then
            put revXMLNextSibling(fld "IdActual",  fld "RutaComponenteAct" ) into \
                    fld "RutaComponenteAct"
          end if
          send "mouseUp" to btn "ActualizaComponentes3"
          put fld "Iteraciones"+1 into fld "Iteraciones"
        end repeat
      end mouseUp
      
                            
    • Actualiza Componentes 3

      on mouseUp
        -- Añadir nombre del componente
        put the item(1)of the line(fld "Iteraciones") of the text of fld "Componentes" into fld "NuevaLinea"
        revAddXMLNode fld "IdActual",fld "RutaComponenteAct","Nombre",fld "NuevaLinea"
      
        -- Añadir datos del componente
        put the item(2)of the line(fld "Iteraciones") of the text of fld "Componentes" into \
                fld "NuevaLinea"
      #  revAddXMLNode fld "IdActual",fld "RutaComponenteAct","Datos",fld "NuevaLinea"
       
        --Anadir nodo foto del componente (sin contenido)
        revAddXMLNode fld "IdActual",fld "RutaComponenteAct","Foto",""
      
        --Localiza rutas de los atributos del nodo foto para el componente actual
        put revXMLFirstChild(fld "IdActual",  fld "RutaComponenteAct") into fld "RutaNombreAct"
        put revXMLNextSibling(fld "IdActual",  fld "RutaNombreAct") into fld "RutaDatosAct"
        put revXMLNextSibling(fld "IdActual",  fld "RutaDatosAct" ) into fld "RutaFotoAct"
        send "mouseUp" to btn "AñadeAtributos"
      end mouseUp
                            
    • Añade Atributos

      on mouseUp
        -- Para el componente actual se añaden los atributos
        --Añadir atributo fichero
        put the item(3)of the line(fld "Iteraciones") of the text of fld "Componentes" into \
                fld "NuevaLinea"
        revSetXMLAttribute fld "IdActual",fld "RutaFotoAct",Fichero,fld "NuevaLinea"
        -- Añadir atributo ancho
        put the item(4)of the line(fld "Iteraciones") of the text of fld "Componentes" into \
                fld "NuevaLinea"
        revSetXMLAttribute fld "IdActual",fld "RutaFotoAct",Ancho,fld "NuevaLinea"
        --Añadir atributo alto
        put the item(5)of the line(fld "Iteraciones") of the text of fld "Componentes" into \
                fld "NuevaLinea"
        revSetXMLAttribute fld "IdActual",fld "RutaFotoAct",Alto,fld "NuevaLinea"
      end mouseUp
                            
    • Grabar

      on mouseUp
        -- Crear el archivo a partir del árbol en memoria y volcar el contenido en el
        --  campo'NuevoFichero'
        put revXMLText (tfld "IdActual",) into fld "NuevoFichero"
        -- Volvar el nuevo contenido en la ubicación del documento inicial (sobreescribir)
      end mouseUp
                            
  4. Modificar título. Para actualizar el contenido del título, se describe un script asociado al evento `ReturnInField', es decir, se ejecuta cuando se pulsa la tecla de retorno de carro después de modificar el contenido del campo `Titulo'.

    Se modifica el contenido del nodo Titulo actualizandolo al valor contenido en el campo `Titulo' y después se graban (con el procedimiento anteriormente descrito) los cambios.

    on returninfield
     revPutIntoXMLNode fld "IdActual",fld "RutaTitulo",fld "Titulo"
     send "mouseUp" to btn "Grabar"
    end returninfields
                          

Un detalle que conviene remarcar a la hora de trabajar con un documento xml, es que va a resultarmuy útil almacenar las `posiciones' de todos los nodos, puesto que en todas las llamadas a las funciones de la librería se debe pasar la referencia de los nodos que se estén procesando.

En la ficha del caso de estudio, existe un campo (oculto) para almacenar la ruta de cada uno de los nodos, y en el caso de grupo de número variable de nodos, se indica la posición del primero y a partir de este se recorre el árbol.

Para que los cambios efectuados en el documento por medio de la ficha sean efectivos es necesario hacer click en los botones de actualización. Como se ha detallado en esta memoria, todos los botones/comandos de actualización lanzan la acción `Grabar'.

Efectivamente, la librería xml introducida en Revolution 2.0 permite procesar un documento xml. En este proyecto se han utilizado muchas de las disponibles, y ha quedado comprobado su funcionamiento y buen resultado. A partir de estas es posible, combinando unas y otras, crear aplicaciones que permitan operaciones más complejas para el procesamiento de documentos XML.