G.Bordel >Docencia >TAP | Técnicas Actuales de Programación | (curso 2010-2011) | |||||||
|
|||||||||
tema_anterior | Tema 12: Java y XML | tema_siguiente |
|
12.4- Soporte Java para XML
La API básica de Java para el procesamiento de XML esta disponible en la edición estandar (JavaSE):
Los siguientes son algunos de los paquetes que implementan esta APIs:
El resto de APIs relacionadas con XML han ido integrandose dentro del marco de los web-services.
javax.xml javax.xml.bind javax.xml.bind.annotation javax.xml.bind.annotation.adapters javax.xml.bind.attachment javax.xml.bind.helpers javax.xml.bind.util javax.xml.crypto javax.xml.crypto.dom javax.xml.crypto.dsig javax.xml.crypto.dsig.dom javax.xml.crypto.dsig.keyinfo javax.xml.crypto.dsig.spec javax.xml.datatype javax.xml.namespace javax.xml.parsers javax.xml.soap javax.xml.stream javax.xml.stream.events javax.xml.stream.util javax.xml.transform javax.xml.transform.dom javax.xml.transform.sax javax.xml.transform.stax javax.xml.transform.stream javax.xml.validation javax.xml.ws javax.xml.ws.handler javax.xml.ws.handler.soap javax.xml.ws.http javax.xml.ws.soap javax.xml.ws.spi javax.xml.xpath ------------------- org.w3c.dom org.w3c.dom.bootstrap org.w3c.dom.events org.w3c.dom.ls org.xml.sax org.xml.sax.ext org.xml.sax.helpers
Supongamos que tenemos un fichero que describe una asignatura como es el siguiente:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE asignatura [ <!ELEMENT asignatura (titulo, titulacion, curso, cuatrimestre, creditos, caracter, itinerario, idioma, profesores, url_temario,url_contenido,inicio)> <!ELEMENT titulo (#PCDATA)> <!ELEMENT titulacion (#PCDATA)> <!ELEMENT curso (#PCDATA)> <!ELEMENT cuatrimestre (#PCDATA)> <!ELEMENT creditos (#PCDATA)> <!ELEMENT caracter (#PCDATA)> <!ELEMENT itinerario (#PCDATA)> <!ELEMENT idioma (#PCDATA)> <!ELEMENT profesores (#PCDATA)> <!ELEMENT url_temario (#PCDATA)> <!ELEMENT url_contenido (#PCDATA)> <!ELEMENT inicio (#PCDATA)> ]> <asignatura> <titulo>Técnicas actuales de programación</titulo> <titulacion>Ingeniería Electrónica</titulacion> <curso>2</curso> <cuatrimestre>2</cuatrimestre> <creditos>9</creditos> <caracter>Optativa</caracter> <itinerario>Informática</itinerario> <idioma>Español</idioma> <profesores> German Bordel Mikel Peñagarikano </profesores> <url_temario>http://www.ehu.es/p200-content/es/contenidos/asignatura/15916ingel202_310_2_2_2008/es_15916/es_fileasig_15916.html</url_temario> <url_contenido>http://gtts.ehu.es/German</url_contenido> <inicio>2 de octubre</inicio> </asignatura>
Podremos "parsearlo" -como ejemplo- para introducirlo en un objeto que recoja esta información como el siguiente:
class Asignatura { String comentario; String titulo, titulacion, caracter, itinerario = "", idioma, urlTemario = "", urlContenido = "", inicio = ""; int curso, cuatrimestre, creditos; String[] profesores; @Override public String toString() { String prof = ""; for (String p : profesores) prof = prof + ", " + p; return "---------------------------------" + "\n" + titulo + "\nProfesores: " + prof.substring(2) + "\n(" + curso + " curso, " + cuatrimestre + " cuatrimestre), (" + creditos + " creditos), [" + idioma + "]" + "\nComienzo: " + inicio + "\nTemario: " + urlTemario + "\nWeb: " + urlContenido + "\n---------------------------------"; } }
La instanciación del parser y su ejecución es extremadamente sencilla (el "truco" esta en la clase que aportamos como segundo parámetro a la acción de "parseo" y que veremos más adelante)
import javax.xml.parsers.*; import java.io.*; import org.xml.sax.*; public class SaxTest { static Asignatura asignatura = new Asignatura(); public static void main(String[] s) throws Exception { File ficheroXML = new File("Asignatura.xml"); javax.xml.parsers.SAXParserFactory pf = javax.xml.parsers.SAXParserFactory.newInstance(); pf.setValidating(true); javax.xml.parsers.SAXParser parser = pf.newSAXParser(); parser.parse(ficheroXML, new ParserDeAsignaturas(asignatura)); System.out.println(asignatura); } }
Y como decíamos, aquí está el procesamiento específico que hacemos de nuestro XML:
class ParserDeAsignaturas extends org.xml.sax.helpers.DefaultHandler { Asignatura g; StringBuffer sb = new StringBuffer(); ParserDeAsignaturas(Asignatura g) { this.g = g; } private String extraeSimple(String s) { return s.trim(); } private String[] extraeMultiple(String s) { String[] s1 = s.trim().split("\r\n|\n"); int j = 0; for (int i = 0; i < s1.length; i++) if (!s1[i].trim().equals("")) s1[j++] = s1[i]; if (j == 0) return null; String[] s2 = new String[j]; for (int i = s2.length - 1; i >= 0; i--) s2[i] = s1[i].trim(); return s2; } public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attributes) { sb = new StringBuffer(); } public void characters(char[] ch, int start, int length) { sb.append(ch, start, length); } public void endElement(String uri, String localName, String qName) { try { if (qName.equals("titulo")) g.titulo = new String(sb).trim(); if (qName.equals("titulacion")) g.titulacion = extraeSimple(new String(sb)); if (qName.equals("curso")) g.curso = Integer.parseInt(new String(sb)); if (qName.equals("cuatrimestre")) g.cuatrimestre = Integer.parseInt(new String(sb)); if (qName.equals("creditos")) g.creditos = Integer.parseInt(new String(sb)); if (qName.equals("caracter")) g.caracter = extraeSimple(new String(sb)); if (qName.equals("itinerario")) g.itinerario = extraeSimple(new String(sb)); if (qName.equals("idioma")) g.idioma = extraeSimple(new String(sb)); if (qName.equals("profesores")) g.profesores = extraeMultiple(new String(sb)); if (qName.equals("url_temario")) g.urlTemario = extraeSimple(new String(sb)); if (qName.equals("url_contenido")) g.urlContenido = extraeSimple(new String(sb)); if (qName.equals("inicio")) g.inicio = extraeSimple(new String(sb)); if (qName.equals("comentario")) g.comentario = extraeSimple(new String(sb)); } catch (Exception ex) { System.out.println("ERROR (Handler) *************************************"); ex.printStackTrace(); } } public void error(SAXParseException ex) throws SAXException { System.out.println("ERROR (Parser) *************************************"); ex.printStackTrace(); } public void fatalError(SAXParseException ex) throws SAXException { System.out.println("ERROR FATAL (Parser) ********************************"); ex.printStackTrace(); } }
El parser DOM se encarga de leer todo el XML y formar una estructura de objetos equivalente que es accesible como un "Document"
import javax.xml.parsers.*; import org.w3c.dom.*" //Cómo comenzar (ejemplo frente a un fichero) import org.w3c.dom.*; Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("elFichero")); //Ejemplos de acceso a elementos del fichero (ya objetos) String cacheUrl=((Element)doc.getElementsByTagName("source").item(0)).getAttribute("cache"); String titulo=((Element)doc.getElementsByTagName("url").item(0)).getTextContent(); /** * Ejemplo de rutina: Dado un elemento, localiza un hijo con tag dado, con un valor específico en el tributo indicado */ Element getElementByAttributeValue(Element e, String nn, String attr, String av) throws Exception{ NodeList nl=e.getElementsByTagName(nn); if (nl==null) return null; for (int i=0; i<nl.getLength(); i++) { Element nle=(Element)(nl.item(i)); String s=nle.getAttribute(attr); if (s!=null && s.equals(av)) return nle; } return null; }
El siguiente es unejemplo de una hoja de estilo XSLT:
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date"> <xsl:output method="xml" encoding="UTF-8" indent="yes" /> <!-- =============================================================================== GENERAL STRUCTURE ================================================================================ --> <xsl:template match="/"> <resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://gtts.ehu.es/Ehiztari" xsi:schemaLocation="http://gtts.ehu.es/Ehiztari http://gtts.ehu.es/Ehiztari/erd.xsd"> <xsl:call-template name="processors" /> <xsl:call-template name="source" /> <xsl:call-template name="segmentation" /> <!-- NOT APPLICABLE <xsl:call-template name="sectioning" /> --> </resource> </xsl:template> <!-- =============================================================================== PROCESSORS section ================================================================================ --> <xsl:template name="processors"> <processors> <processor> <xsl:attribute name="agent"> <xsl:value-of select="concat(/Trans/@scribe,'(Transcriber)')" /> </xsl:attribute> <xsl:attribute name="date"> <xsl:value-of select="/Trans/@version_date" /> </xsl:attribute> <xsl:attribute name="info"> <xsl:value-of select="concat('audio_filename: ',/Trans/@audio_filename,'; ')" /> <xsl:value-of select="concat('version: ',/Trans/@version,'; ')" /> <xsl:value-of select="concat('elapsed_time: ',/Trans/@elapsed_time,'; ')" /> </xsl:attribute> </processor> <processor agent="trs2erd xslt" > <xsl:attribute name="date"> <xsl:value-of select="date:date-time()" /> </xsl:attribute> </processor> </processors> </xsl:template>
Una xslt se puede aplicar con un paquete: en pricipio el mismo XALAN (xalan org.xml trans.xsl > out
), pero hay muchos más (Saxon, xray2, ...).
La siguiente clase muestra cómo actuar desde Java:
import java.io.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; public class ApplyXSLT { /** Constructor anulado */ private ApplyXSLT() {} public static void main(String[] args) throws FileNotFoundException, TransformerException, TransformerConfigurationException { if (args.length !=3) { System.out.println("Formato: java ApplyXSLT <xslt> <xml origen> <xml destino>"); System.exit(1); } Source xslt = new StreamSource(new FileInputStream(args[0])); Source xml = new StreamSource(new FileInputStream(args[1])); Result resultado = new StreamResult(new FileOutputStream(args[2])); // Me hago con una factoria de transformadores, instancio el necesario y ejecuto TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(xslt); t.transform(xml, resultado); } }
Siguiente Tema: 13- Ingeniería del Software
Plataforma de soporte a curso y contenidos (c) German Bordel 2005. |