Está en la página 1de 7

24

<

ACCESO A DATOS

>

buffer.set],ength (10); //70 caracteres para e1 apellido file. writeChars (buffer. toString (l ) ; / / inqertar apellido /,/ insertar dePartamento file.writelnt (deP) ; file.writeDouble (sal-ario) ; / /inserLar sal-ario

file. close

,'

//

cetrar fichero

para modificar un registro determinado, accedemos a su Posicin y efectuamos las modificacioy salario del nes. El fichero debe abrirse en modo "rw'1 Por ejemplo para cambiar el dePartamento empleado con identificador 4 escribo:

/id a modificar long posicion = (registro -1 ) x 36; // (4+20+4+B) posicion:posicion+4+20; //sumo el tamao de lD+apellido fil-e. seek (posicion) ; / /nos poscionamos file.writernt(40) ; / /modif departamento fife.writeDouble (4000. 8'7) ; / /nodif safario int registro = 4
;/

Actividad 4: Crea un programa Java que reciba desde la lnea de comandos un identificador de empleado y un importe. Se debe sumar al salario del empleado el importe tecleado. El programa debe visualizar el apellido, el salario antguo y el nuevo. Si el identificador no existe se vsualzar un mensaje indicndolo.

1.7

TRABAJO CON FICHEROS XML

yyIL (eXtensible Markup Language- Lenguaje de Etiquetado Extensible) es un metalenguaje, es decir, un lenguaje para la definicin de lenguajes de marcado. Nos permite jerarquizar y estructurar son la informacin as como describir los contenidos dentro del propio documento. Los ficheros XML ficheros de texto escritos en lenguaje XML donde la informacin est organizada de forma secuencial y en orden jerrquico. Existen una serie de marcas especiales como son los smbolos menor que, < y mayor qqe , > que se usan para delimitar las marcas que dan la estructura al documento. Cada ii.rr" on nombre y puede tener 0 o ms atributos. Un fichero XML sencillo tiene la siguiente

-ur."

estrucfura:
<?xm1
<Empleados>

_,_

version:"l-.

0" ?)

<empleado)

<id>1</id>
<ape1 I ido>FERNANDE Z< / apel
1

ido>

<dep>10</deP>

<salario)100
</emPleado>

0.

45</saf ario>

(empleado)

<d>2</id> no l I ido)GIL</apeIlido>
<deP>2 0</deP>

(salario)24

00 .

6</salario>

DE FICHEROS

25

</empleado>

(ernpleado)

<id>3</id>
<ape
11

ido>LOpEZ< / apell ido>


00.

<dep>1 O</dep>

odificaciosalario del

<sal-ari_o)30 </empleado> </Ernpleados>

0</salario>

Los ficheros XML se pueden utilizar para proporcionar datos a una base de datos o para almacecopiab de partes del contenido de la base de datos. Thmbin se utilizan para escribir ficheros de acin de programas o en el protocolo SOAP (Simple Object Access Protocol), para ejecutar rdos en servidores remotos; lqg&rno.a-."l"gs al;grq{.gr remoto y el resultado de la -g.*y_rg|a in del comando se envan en cheros XML.
Para leer los ficheros XML y acceder a su contenido y estructura, se utiliza un procesador de XML : El procesador lee los documentos y proporciona acceso a su contenido y estructura. Algunos

&

hs procesadores ms empleados son: DOM: Modelo de Objetos de Documenfo y SAX: API Simpte XML Son independientes del lenguaje de programacin y existen versiones particulares para
ificador
VisualBasic, C, etc. Utilizan dos enfoques mu) diferentes:

ndo. El dor no

. DOM:

un procesador XML que utilice este planteamiento almacena toda la estructura del documento en memoria en forma de rbol con nodos padre, nodos hijo y nodos finales (que son aquellos que no tienen descendientes). Una vez creado el rbol, se van recorriendo los diferentes nodos y se analiza a qu tipo particular pertenecen. Tiene su origen en el W3C. Este tipo de procesamiento necesita ms recursos de memoria y tiempo sobre todo si los ficheros XML a procesar son bastante grandes y complejos.

Engua]e, es

estructurar

sXlLson
.secuencial

[enor

que,

ento. Cada h siguiente

SAX: un procesador que utilice este planteamienfo lee un fichero XML de forma secuencial y produce una secuencia de eventos (comienzo/fin del documento, comienzo/fin de una etiqueta, etctera) en funcin de los resultados de la lectura. Cada evento invoca a un mtodo definido por el programador. Este tipo de procesamiento prcticamente no consume memoria, pero por otra parte, impide tener una sin global del documento por el que navegar.

I.7.1

ACCESO A FICHEROS XML CON DOM

Para poder trabajar con

DOM en |ava necesitamos las clases e interfaces que componen

el

pa$r.:te

).

carg:a documentos desde una (fichero, Inputstream, Contiene dos clases fundamentalest-DocumintBulderFactory y DocumentBuilder.
@"e@,-ed@

wsquetodaimplementacinDoMpara|avadebeextender.Estas

DoM

no define ningn mecanismo para

gqn-ej3ly$gtrjlgWoM.

para

eso usaremos E!_Pes.gSLe que permite speficar una fuente y un resultado. La frente y el resultado pueden ser ficheros, flujos de datos o nodos DoM entre otros.

i*g!.ryl.Wf":!!

26

<

ACCESO A DATOS

>

mA,.itiEJO D

Los programas |ava que utilicen DOM necesitan estas interfaces (no se exponen todas, solo algunas de las que usaremos en los ejemplos):

-{

;nm

finmm.l:r-y-,

. Document. .

Es un objeto que equivale a un ejemplar de un documento XML. Permite crear nuevos nodos en el documento. Element. Cada elemento del documento XML tiene un equivalente en un objeto de este tipo. Expone propiedades y mtodos para manipular los elementos del documento y sus atributos.

. Node. Representa a cualquier nodo del documento. . Nodelist. Contiene una lista con los nodos hijos de un nodo' . Attr. Permite acceder a los atributos de un nodo. . Text. Son los datos carcter de un elemento.

C.ra:g

ffiils

:a

s:,n *in
lo <sn::o:

.
.

CharacterData. Representa a los datos carcter presentes en el documento. Proporciona atributos y mtodos para manipular los datos de caracteres. DocumentType. Proporciona informacin contenida en la etiqueta <!DOCTYPE>.

krn

A continuacin vamos a cnea un fichero XML, a partir del fichero aleatorio de empleados creado en el epgrade anterior. Lo primero que hemos de hacer es importar los paquetes necesarios:

import import import import import import

org. w3c. dom. *,' j avax. xml . parsers . *,' j avax. xml. transform. * ; j avax. xml. transform. dom. *,' javax.xml .transform. stream' *,'

java. io. *;

de DocumentBuilderFactory para construir el parser (se debe encerrar entre try-cath porque se puede producir la excepcin ParserConfgurationException:

A continuacin creamos una instancia

DocumentBuilderFactory factory : DocumentBufderEactory. newlnstance

);

tty{

DocumentBuifder buifder : factory.ne\^IDocumentBuilder O ;

rta.::c

Creamos un documento vaco de nombre document con el nodo raz de nombre Empleados y asignamos la versin del XML:

DoMlmpfementation implenentation = bulder . getDoMlmplementation ( ) ; Document document = irnpfementation.createDocument(null, "Empleados", nul1); document.selXrnlVersion("1.0"); / / asignamos la version de nuestro XML El siguiente paso sera recorrer el fichero con los datos de los empleados y por cada registro crear un nodo empleado con 4 hijos (id, apellido, dep y salario). Cada nodo hijo tendr su valor (por ejemplo: 1, FEKNANDEZ, 10, 1000.45). Para crear un elemento usamos el mtodo createElement(String) llevando como parmetro el nombre que se pone entre las etiquetas menor que y mayor que. El siguiente cdigo creay aade el nodo <empleado> al documento:

En rrs
r----Se
Jl:

;ea,
-,

Element raz : document.createElement("empleado"),' // creamos ef nodo ernpleado document.getDocumentEfementO 'appendchild(raiz) ;//Io pegamos a ra raz def doc

5C

ffTN

IIANEJO DE FICHEROS

27

$, solo algu-

continuacin se aaden los hijos de ese nodo (raiz), estos se aaden en

la funcin

(searElemento0:

ermite crear
de este tipo.

atributos.

("id", fnteger.toStrng(id) , raiz, document); / /aadir ID ( "apel]ido". apellidoS. trim O , raiz, document) ; / / aadir APELLIDO OrearElemento("dep",Integer.toString(dep), raiz, document);//aadir DEP OrearElemento("salario"rDouble.toString(salario), raiz, document);//lnadir SALARIO
rearEfemento
OrearElernento

Como se puede ver la funcin recibe el nombre del nodo hljo (id, apellido, dep o salario) y sus tos o valores que tienen que estar en formato String (1, FEKNANDEZ, 10, 1000.45), el nodo al que lrva a aadir (raiz) y el documento (document). Para crear el nodo hijo (<id> o <apellido> o <dep> o <salario>) se escribe:

iona atribu-

E]ement efem

: document.createEfement (datoEmple) ;

/ /cxeamos

un hrjo

Para aadir su valor o su texto se usa el mtodo createTextNode(String):

ados creado

ios:

Text text = document.createTextNode(valor) //damos vafor


A continuacin
se aade el

nodo hijo

a la raz (empleado) y su

texto o valor al nodo hijo:

raiz.appendchild(elem) ; //peqamos el e]emento hijo a la raiz e1em. appendchil-d (text) ; / /pegamos el- val_or
Al final
el parser (se Exception:
se generara algo

similar

a esto

por cada empleado:


000 .4

<empleado><id>1</ id><apel1ido>FERNANDEz</ape1 lido><dep>1 0</dep><salario>1

5<

,lsalario>< /empleado>
La funcin es la siguiente:

Empleados

static void CrearElemento (String datoEmple, String va1or, Element raiz, Document document ) { Element efem : document.createElement(datoEnple) ; //creamos hijo Text text : document.createTextNode(val-or) ; //damos vafor raiz.appendchild(elem); //pegamos el_ efemento hijo a la raiz elem.appendchild(text) ; / /pegamos el valor
]

null);

egistro crear ,r (por ejemment(String) ayor que. El

En los ltimos pasos se crea la fuente

XML a partir del documento:


;

Source source : ner DOMSource (document)


Se crea el resultado en el

fichero Empleados.xml:
)

Result result = ner StreamResul-t(new java.io.File("Emp1eados.xml")


empleado def doc
Se obtiene

/ /fic]h XML

un TransfomerFactory:

28

<

ACCESO A DATOS

>

Trans

former trans former :

Trans formerFactory. newlnstance ( ) . newTrans


a fichero.

forner

).;

Se realiza la

transformacin del documento

transformer.lransform (source, resul-t)

Para mostrar el documento por pantalla, podemos especifrcar como resultado el canal de salida System.out:

Result console= new StreamResult (System.out) transformer.transform(source, console) ; ' --"---"'' ''.'.-,,i
El cdigo completo es el siguiente:

mport irnport import import irnport iraport

org.w3c.dom.*; javax.xml.parsers. *; j avax. xm1. transform. * ; j avax. xm1. transform. dom. * ; javax.xml. transform. stream. *; j ava. io. *;

public class CrearEmpleadoXnl { public static void main(String argv[]) throws lOException{ Fil-e fichero = new File ("c: \\EJERCICIOS\\UNI1\\AleatorioEmple.dat") RandomAccessFile file : new RandomAccessFile (ficheror "r") ; int
Double salaro;

id, dep, posicion:0;

/para situarnos al principio de} fichero

char apellido[] : new char[10], aux;


DocumentBuilderFactory factory = DocumentBuil-derFactory. nevrfnstance
(

);

try{

DocumentBuilder builder : factory - newDocumentBuilder ( ) ; DOMlmplementation implementation = builder. getDoMlmplementation Document document = implementation-createDocument (
.

);

nul1, ".Emp1eados", nutl).; do-9}L9]]!;:'e,*!mrler,s.i.sn("1.0'');//asLgnamoslaversiondenuestroXML for(;;)


fife. seek (posicion) ; / /nos posicionamos id=file.readlntO; // obtengo id de empleado
{

for (int i = 0; i < apellido.length; i++) { aux = fil-e,readChax(l;//recorro uno a uno 1os caracteres del apellido //Ios voy guardando en el array apeJ-lidolil = aux;
)

string apellidos=

new string(ape11ido)

;//convierto a string el array


safario
/

dep=1i1".readrnt O; / /obLengo dep salario=fife.readDoubleO ; / /obLengo


1-

if(id>O) t //id validos a partir de Efement raiz = document.createElement("empleado") ;

/nodo empleado

TIANEJO DE FICHEROS

29

:o;

document.getDocumentElement

O . appendChild (raiz) ; CrearEfemento("id", Integer. toString(id) , raiz, document); //aadir IO CrearEfemento ("apel1ido", apellidoS.trim O, ra2, document) ; //Apellido CrearEfemento ("dep", Integer .toString(dep) , r:at, document) ; //aadir DEP CrearEfemento("salario",Double.toString(sal-ario), raiz, document); //SAL
)

de salida

posicion: posicon + 36; / / me posiciono para el sig enpleado if (file. getFilePointer O :: file. lenqth O ) break; ]//fin del for que recorre ef fichero
Source source : ner DOMSource (document),. Result result : new StreamResult (new java.io.Eile ("Empfeados.xml") Transformer transformer : TransformerFactory.newlnstance transformer. transform (source, resuft.) ;
(

);

) . newTransformer ( ) ;

]catch(Exception e) {System. err.println("Error: fil-e.cfoseO ; / /cerrar fichero I//fin de main

"*e) ; i

/ /Insercn de fos datos del empleado static void CrearEfemento (String datoEmple, String valor, Element ra2, Document document) { Element elem = document. createElement (datoEmple) ; / / creamos hijo Text text : document.createTextNode (valor) ; / /damos valor raiz.appendchild(elem); //pegamos el efemento hijo a la raiz elem.appendchild(text) ; / /pegamos el valor ] /:.'_r'., i! '://fin de".'.".", fa clase

Para leer un documento XML, creamos una instancia de DocumentBuilderFactory para construir parser y cargamos el documento con el mtodo p arse0:

Document document Obtenemos la

= builder.parse (new File ("Empleados.xmf")

);

de nodos con nombre empleado de todo el documento: document . getElementsByTagName


(

\odelist ernpleados :
Se

"emp1eado" ),-

realiza un bucle para recorrer esta lista de nodos. Por cada nodo se obtienen sus etiquetas y sus rilores llamando a la funcin getNodo0. El cdigo es el siguiente:

-1ido
-oy

i-oport j ava. j-o. File,. import j avax. xml.parsers, *; i:nport org. w3c. dom. * ; public class LecturaEmpleadoXml { public static void main(String argv[])
{

DocumentBuilderFactory factory = DocumentBuifderFacLory. newlnstance O ;

30

<

ACCESO A DATOS

>

try

; DocumentBuil-der buifder = factory'nelrDocumentBuilder . xml', (''Empleados )); (new Fi]-e Document document : builder . parse

()

document. getDocumentElement System.

)' normalize
+

);

document. qetDocumentBlernent O' getNodeName O ) ; //crea una lista con todos fos nodos empleado ("empleado" ) ; Nodelist empleados : document. getElementsByTagName
/

out.println ("Elemento raz: "

/recorrer 1a lista j{ for (int i : O,' i < empleados'getl'engtho; ++) nodo un //obtener Node emple: empleados'item(i); de nodo if (emple'getNoerypeO == Node'E-LEMEN? NODE) tl/tipo elementos del nodo 1os : emple; //obtener (Element) efemento Element elemento) ); System.out'println("ID: " + getNodo("id"' -t- qetNodo("ape11ido"' elemento) ) ; " System.out.printfn("Apellido: System.out.println(''DepartamenLo;''tgretlVodo(''dep'',elemento)); System.out.println("Sa1ario""+getNodo("salario"'elemento))''
) )

] catch (Exception ]//fin de main


{

e) {e'printstackTraceO;}
elem)

nodo //obtener l-a informacin de un getNodo (String etiqueta' Element String static Ptivate

Nodelist nodo: elem.getElementsByTagName(etiqueta).item(0)-getchildNodeso; Node valornodo = (Node) nodo'iten(0); nodo return valornodo.getNodeValueo ;//devuelve el vafor deL /fin de la clase
API DOM:

tu
mm

tfttE"" ft"nl-

jIgr ry@
rmt!F-

rfr'tl"

anteriormente' crea un Actividad 5: A partir del fichero de objetos Persona utilizado


documento XML usando DOM.
ACCESO A FICHEROS XML CON SAX

ffiecm

1.7.2

e interfaces que ofrecen una herramienta SAX (APf Simple para XML) es un conjunto de clases Permite analizar los documentos de forma muy til para el procesamiento de documentos XML' memoria como hace DoM), esto implica poco consecuencial (es decir, no carga todo el f,chero en de gran tamao, en contraposicin, impide tener sumo de memoria u.rrrqo.lo, documentos sean sAX es ms complejo de programar que DOM' una visin global del documento que se va a analizar. dentro del JRE que nos permite crear nuestro propio es un ApI totalmente escrita en ava e incluida

lf

,rllr

- lCl

parserdeXML'

'rnalallamadaamtodos, loseven.^^--*^-ra\rTrrrT produce XML nrnrr eventos que ocasl( documento (startDocument) y endDocument)),la tos son encontrar Ia etiqueta de inicio y fin del
La lectura de un documento

-D[ -n -tl -IH