11. XML
11.1 Introducción
11.1.1 Definición
Qué es XML ?
Extensible Markup Language XML 1.0 1998
Es un subconjunto de SGML (Standard Generalized Markup Language)
XML es un lenguaje de marcado basado en texto
Estándar para el intercambio de datos en la web
Conjunto de reglas para el diseño semántico de tags
Lenguaje de Meta-markup para definir otros lenguajes
La especificación oficial la da el W3C
http://www.w3.org/TR/REC-xml
HTML y XML
- HTML es una aplicación de SGML
- XML es un subconjunto de SGML
- XHTML es una aplicación de XML
XML Archivo Ejemplo
<?xml version="1.0"?>
<dining-room>
<manufacturer>The Wood Shop</manufacturer>
<table type="round" wood="maple">
<price>$199.99</price>
</table>
<chair wood="maple">
<quantity>6</quantity>
<price>$39.99</price>
</chair>
</dining-room>XML describe Estructura y Semántica, NO Formato
Ejemplo HTML
<DL>Ejemplo XML
<DT>Mambo
<DD>by Enrique Garcia
</DL>
<UL>
<LI>Producer: Enrique Garcia
<LI>Publisher: Sony Music Entertainment
<LI>Length: 3:46
<LI>Written: 1991
<LI>Artist: Azucar Moreno
</UL>
<SONG>
<TITLE>Mambo</TITLE>
<COMPOSER>Enrique Garcia</COMPOSER>
<PRODUCER>Enrique Garcia</PRODUCER>
<PUBLISHER>Sony Music Entertainment</PUBLISHER>
<LENGTH>3:46</LENGTH>
<YEAR>1991</YEAR>
<ARTIST>Azucar Moreno</ARTIST>
</SONG>Por qué es conveniente usar XML?
Facilita el Intercambio de Datos
- Crecimiento de formatos propietarios
- Programas de Conversión (Aplicaciones, versiones, etc)
- Tantos los datos como las marcas son almacenados en modo texto
- Evita almacenar datos simples en archivos enormes
Hacer lenguajes a la medida de las necesidades
Datos auto-descriptivos
- Banking Industry Technology Secretariat (BITS)
- Financial Exchange (IFX)
- Schools Interoperability Framework (SIF)
- Common Business Library (CBL)
- Electronic Business XML Initiative (ebXML)
- Text Encoding Initiative (TEI)
<?xml version="1.0" encoding="UTF-8"?>Datos organizados (semi-estructurados) e integrados
<DOCUMENT>
<GREETING>Hello from XML</GREETING>
<MESSAGE>Welcome to Programing XML in Java</MESSAGE>
</DOCUMENT>
<?xml version="1.0"?>
<SCHOOL>
<CLASS type="seminar">
<CLASS_TITLE>XML In The Real World</CLASS_TITLE>
<CLASS_NUMBER>6.031</CLASS_NUMBER>
<SUBJECT>XML</SUBJECT>
<START_DATE>6/1/2002</START_DATE>
<STUDENTS>
<STUDENT status="attending">
<FIRST_NAME>Edward</FIRST_NAME>
<LAST_NAME>Samson</LAST_NAME>
</STUDENT>
<STUDENT status="withdrawn">
<FIRST_NAME>Ernestine</FIRST_NAME>
<LAST_NAME>Johnson</LAST_NAME>
</STUDENT>
</STUDENTS>
</CLASS>
</SCHOOL>
11.1.2 Tipos de Documentos XML
Documentos XML Bien-Formados (Well-Formed)
Son aquellos documentos XML que:
- Siguen las reglas de sintáxis establecidad por el W3C en:
- XML 1.0 (www.w3.org/TR/REC-xml)
- Contienen uno o más elementos
- Poseen un elemento Root que contiene dentro de él los demás elementos
- Cada elemento debe anidarse dentro de otro correctamente (uno dentro de otro)
Documentos XML Válidos (Valid)
- Asociación con un DTD (Document Type Definition)
- Cumplir con la especificación del DTD
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="first.css"?>
<!DOCTYPE DOCUMENT [
<!ELEMENT DOCUMENT (GREETING, MESSAGE)>
<!ELEMENT GREETING (#PCDATA)>
<!ELEMENT MESSAGE (#PCDATA)>
]>
<DOCUMENT>
<GREETING>Hello from XML</GREETING>
<MESSAGE>Welcome to Programing XML in Java</MESSAGE>
</DOCUMENT>Hypertext Markup Language
Tecnologías Relacionadas
- HTML es el formato de salida más común para XML
- Navegadores: Internet Explorer 5.0, Netscape 6.0
- Una manera diferente de diseñar sitios web
Cascading Style Sheets (CSS)
- Definir propiedades de formato
- Font Size
- Font family
- Font weight
- Paragraph indentation
- Paragraph alignment
- Múltiples hojas de estilo pueden ser aplicadas a un mismo documento
- Múltiples estilos pueden aplicarse a un sólo elemento
URLs and URIs
- Uniform Resource Locator (URL)
http://www.udlap.mx
Actualmente ya no son utilizados
- Uniform Resource Name (URN)
urn:issn:1011.-911.3
http://purl.oclc.org/OCLC/PURL/FAQ- Uniform Resource Identifier (URI)
The Unicode Character Set
- American Standard Code for Information Interchange (ASCII) 0-255 'A' - 65
- XML brinda soporte para el Unicode de 2 bytes. 0-65,535
http://www.unicode.org- XML acepta documentos escritos en:
- ASCII
- UTF-11.Compressed version of Unicode (utiliza 11.bits para representar)
<?xml version="1.0" encoding="UTF-8"?>
- XML define un referencia para codificar caracteres Unicode
© < π
- Universal Character System (UCS ISO 10646)
- 4 bytes por symbol
- Codificación UCS-2 y UCS-4
11.1.3 Utilización de documentos XML
Cómo se utiliza ?
- El documento XML es parseado (analizado sintáctica y gramaticalmente)
- Los datos son manipulados
- APIs disponibles en Java, C, C++, Perl, etc
Para hacer este "parsing" se utilizan 2 técnicas
- SAX (Simple API for XML)
- DOM (Document Object Model)
Simple API for XML - SAX
- Sistema basado en eventos (event-based) para el análisis de los datos
- Métodos como startDocument(), endElement()
- Conjunto de Errores y Warnings
- http://www.megginson.com/SAX
- Muchos analizadores están basadon en el SAX API
Document Object Model - DOM
- Manipulación de datos XML
- Brinda una representación del documento a manera de árbol
- Lee todo el documento XML en memoria
- http://www.w3.org/DOM
Sun's Java API for XML Parsing - JAXP
- Mzcla de SAX y DOM APIs
- Algunos métodos adicionales
- http://java.sun.com/xml
Java y XML: La pareja ideal
- Java es código portable, XML son datos portables
- Aplicaciones completamente portables
- Java Virtual Machine (JVM)
- Capas de datos basadas en estándares
- Java provee el más robusto conjunto de:
- APIs - JAXP
- Parsers - XP
- Processors - Saxon
- Publishing Frameworks - Cocoon
- Tools for XML - XML Pro
El ciclo original de un documento XML
Editores de XML
Sirven para crear documentos XML
- Editores de Texto - vi, emacs, notepad
- Editores de XML
- Adobe FrameMaker, www.adobe.com
- XML Pro, www.vervet.com
- XML Writer, xmlwriter.net
- XML Notepad, msdn.microsoft.com/xml/notepad/intro.asp
- XMetal from SoftQuad, xmetal.com
- XML Spy, www.xmlspy.com
Editores de XML (XML Spy)
XML Parsers
- Leen el documento XML
- Verifican si el documento XML está bien-formado (well formed)
- Verifican si el documento es válido
- expat, parser escrito en C por James Clark (www.jclark.com)
- XML for Java (XML4J), IBM Alphaworks
(www.alphawors.ibm.com/tech/xml4j)- Lark, escrito en Java (www.textuality.com/Lark/)
- Apache Xerces (www.apache.org)
- XP por James Clark (www.jclark.com)
- Oracle XML Parser (technet.oracle.com/tech/xml)
- Sun Microsystems Project X (java.sun.com/products/xml)
XML Validators
Unicamente verifican si un documento es válido
- XML.com's Validador basado en Lark (xml.com)
- Language Technology Group en la Universidad of Edinburgo validador basado en el RXP Parser
www.ltg.ed.ac.uk/~richard/xml-check.html- Scholarly Technology Group en la Universidad Brown
www.stg.brown.edu/service/xmlvalid/
XML Browsers
Despliegan los datos al usuario
- Internet Explorer 5
- Despliega directamente Documentos XML
- Manipula XML en lenguajes de scripting (JScript, VBScript)
- Liga XML con registros de bases de datos a través de ActiveX Data Object (ADO)
- XML integrado como parte de las aplicaciones del Office 2000 y superiores
- Netscape Navigator 6
- Despliega directamente Documentos XML
- Manipula XML en lenguajes de scripting (Javascript 1.5)
- Soporta el XML-based User Interface Language (XUL). XUL permite configurar los controles del navegador
- Jumbo
- Despliega XML
- Usa CML para dibujar moléculas
Recursos disponibles en el web acerca de XML
- XML en W3C (http://www.w3.org/xml/)
- XML.com (http://www.xml.com/
- XML.org Registry (http://www.xml.org/)
- XML Cover Pages (http://xml.coverpages.org/)
- Java and XML (http://java.sun.com/xml/)
Aplicaciones XML
Lenguajes basados en XML
- Chemical Markup Language (CML)
- Mathematical Markup Language (MathML)
- Channel Definition Format (CDF)
- Synchronized Multimedia Integration Language (SMIL)
- XHTML
- Scalable Vector Graphics (SVG)
- MusicML
- VoxML
11.2 Documentos XML
11.2.1 Creando Documentos XML
Documentos XML
- HTML, posee cerca de 100 elementos
- XML, cada quien define sus propios elementos
- HTML Browsers intentan arreglar código HTML inválido
- XML Processors no hacen ninguna averiguación acerca de la estructura del documento
- Un documento bien-formado es lo mínimo que debe cumplir un documento para ser XML
- Mejor aún si es un documento XML válido (DTD o XML Schema)
- World Wide Web Consortium (http://www.w3.org/)
Qué es un documento XML bien-formado ?
Es un documento de texto está bien-formado si:
- tomado como un todo, coinciden las etiquetas del documento
- Cumple con las reglas de formación mencionadas en la especificación:
http://www.w3.org/TR/REC-xml- Cada una de las entidades analizadas o parseadas que se encuentran referenciadas directa o indirectamente en el documento están bien formadas
Componentes de un documento XML
document ::= prolog element Misc*
- Prolog:
<?xml version="1.0"?>
- Comentarios ->
<!-- This is a Comment -->
- Instrucciones de Procesamiento:
<?xml-stylesheet href="JavaXML.html.xsl" type="text/xsl"?>
<?xml-stylesheet href="greeting.css" type="text/css"?>- Element:
- Elemento raíz (root), que a su vez contiene más elementos
- Exactamente una sola raíz
- Misc:
- Comentarios
- Instrucciones de Procesamiento
- Espacios
Tags y Elements
- Un elemento XML consiste de un tag de inicio y un tag de terminación
<document> ... </document>
- Reglas de nombres de Tag
- Deben empezar con una letra
<document>
, un guión bajo<_record>
o bien 2 puntos (aunque no se recomienda)- Los siguientes caracteres pueden ser: letra, número, guión, guión bajo, punto, dos puntos, pero NO espacios es blanco
- Los procesadores de XML y en consecuencia los documentos son "case sensitive"
Los siguientes tags son diferentes:<document>
,<DOCUMENT>
,<Document>
- Elementos Vacíos tienen únicamente un tag:
HTML : <img>, <li>, <hr>
XHTML : <img/>, <li/>, <hr/>
Attributes
- Parejas nombre-valor: {STATUS, "Good Credit"}
- Información adicional del elemento, especificada en los tags de inicio
<CUSTOMER STATUS="Good credit">
- Los nombres sigues las mismas reglas que los los nombres de tags
- Los valores de los atributos son cadenas encerradas en comillas " "
Elements vs Attributes
- Demasiados atributos hacen que los documentos sean más difíciles de leer
Ejemplo 1:
<CUSTOMER LAST_NAME="Smith" FIRST_NAME="Sam"
DATE="October 15, 2001" PURCHASE="Tomatoes"
PRICE="$1.25" NUMBER="8" />
Ejemplo 2:
<CUSTOMER>
<NAME>
<LAST_NAME>Smith</LAST_NAME>
<FIRST_NAME>Sam</FIRST_NAME>
</NAME>
<DATE>October 15, 2001</DATE>
<ORDERS>
<ITEM>
<PRODUCT>Tomatoes</PRODUCT>
<NUMBER>8</NUMBER>
<PRICE>$1.25</PRICE>
</ITEM>
</ORDERS>
</CUSTOMER>
- No se puede representar una estructura sólo con atributos
- Atributos son buenos para información sencilla
<BOOK ID="B1">
Construyendo la estructura de un Documento XML Bien-Formado
- Debe comenzar con una declaración
<?xml version="1.0" standalone="yes"?>
<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT>
<GREETING>Hello from XML</GREETING>
<MESSAGE>Welcome to Programing XML in Java</MESSAGE>
</DOCUMENT>
- Incluir ambos tags (inicio y terminación) para aquellos elementos que no están vacíos
<GREETING>Hello from XML</GREETING>
- Cerrar los tags vacíos con />
<SUBJECT name="XML"/>
- Se debe establecer un elemento raíz que debe contener a todos los demás elementos
<DOCUMENT> ..... </DOCUMENT>
Mezclar los elementos de manera correcta:
<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT>
<GREETING>Hello from XML</MESSAGE> <--- error end tag
<MESSAGE>
Welcome to Programing XML in Java
</GREETING> <--- error end tag
</DOCUMENT>
- Utilizar nombres únicos para los atributos:
<PERSON LAST_NAME="Smith" LAST_NAME="Punin"> <--- error mismo nombre
- Utilizar las 5 referencias ya existentes de entidades:
& &
< <
> >
' `
" "
<TOUR CAPTION="The S&O Railway"/>
<IMG SRC="image.jpg"/>
CDATA Sections
- Son secciones que contienen datos que permanecen intactos al ser analizados por un Procesador XML
- Comienzan con:
<![CDATA[
- Terminan con:
]]>
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Using The if Statement In JavaScript</title>
</head>
<body>
<script language="javascript">
<![CDATA[
var budget
budget = 234.77
if (budget < 0){
document.writeln("Uh oh.")}
]]>
</script>
<center> <h1>Using The if Statement In JavaScript</h1> </center>
</body>
</html>
11.2.2 Creación de DTDs (Document Type Definitions)
- Document Type Definition:
- Especifica la estructura y sintáxis de un documento XML
<!ELEMENT DOCUMENT (CUSTOMER)*>
<!ELEMENT CUSTOMER (NAME,DATE,ORDERS)>
<!ELEMENT NAME (LAST_NAME,FIRST_NAME)>
<!ELEMENT LAST_NAME (#PCDATA)>
<!ELEMENT FIRST_NAME (#PCDATA)>
<!ELEMENT DATE (#PCDATA)>
<!ELEMENT ORDERS (ITEM)*>
<!ELEMENT ITEM (PRODUCT,NUMBER,PRICE)>
<!ELEMENT PRODUCT (#PCDATA)>
<!ELEMENT NUMBER (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>Mini Ejemplo de un documento válido y un DTD
<?xml version="1.0"?>
<!DOCTYPE BOOK [
<!ELEMENT BOOK (P*)>
<!ELEMENT P (#PCDATA)>
]>
<BOOK>
<P>chapter 1 - Intro</P>
<P>chapter 2 - Conclusion</P>
<P>Index</P>
</BOOK>
Sintáxis de DTDs
Document Type Declaration (declaración del DTD)
<!DOCTYPE rootname [DTD]>
<!DOCTYPE rootname SYSTEM URL>
<!DOCTYPE rootname SYSTEM URL [DTD]>
<!DOCTYPE rootname PUBLIC identifier URL>
<!DOCTYPE rootname PUBLIC identifier URL [DTD]>
Ejemplo de DTD
<?xml version="1.0"?>
<!DOCTYPE BOOK [
<!ELEMENT p (#PCDATA)>
<!ELEMENT BOOK (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION | PART)+)>
<!ELEMENT OPENER (TITLE_TEXT)*>
<!ELEMENT TITLE_TEXT (#PCDATA)>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT INTRODUCTION (HEADER, p+)+>
<!ELEMENT PART (HEADER, CHAPTER+)>
<!ELEMENT SECTION (HEADER, p+)>
<!ELEMENT HEADER (#PCDATA)>
<!ELEMENT CHAPTER (CHAPTER_NUMBER, CHAPTER_TEXT)>
<!ELEMENT CHAPTER_NUMBER (#PCDATA)>
<!ELEMENT CHAPTER_TEXT (p)+>
]>
<BOOK>
<OPENER>
<TITLE_TEXT>All About Me</TITLE_TEXT>
</OPENER>
<PART>
<HEADER>Welcome To My Book</HEADER>
<CHAPTER>
<CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>
<CHAPTER_TEXT>
<p>Glad you want to hear about me.</p>
<p>There's so much to say!</p>
<p>Where should we start?</p>
<p>How about more about me?</p>
</CHAPTER_TEXT>
</CHAPTER>
</PART>
</BOOK>External DTDs (Privates)
- Nombre del archivo:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE BOOK SYSTEM "book.dtd">
<BOOK>
......
</BOOK>URL: <?xml version="1.0" standalone="no"?>
<!DOCTYPE BOOK SYSTEM "http://www.library.org/book.dtd">
<BOOK>
......
</BOOK>External DTDs (Publics)
<!DOCTYPE name PUBLIC "FPI" "URL">
Formal Public Identifier (FPI)
- Primer campo: no standard, + standard DTD
- Segundo campo: nombre de grupo o persona responsable del DTD
- Tercer campo: tipo de documento y número de versión
- Cuarto campo: lenguaje (2 letras)
- Campos separados por //
<!DOCTYPE BOOK PUBLIC "-//Joseph Smith//General Book Version 5.3//EN" "http://www.library.org/book.dtd">
XHTML Document
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Virtual Library</title>
</head>
<body>
<p>Moved to <a href="http://vlib.org/">vlib.org</a>.</p>
</body>
</html>
Definición de Elementos
<!ELEMENT name content_model>
- Ejemplos :
<!ELEMENT direction (left, right, top?)>
<!ELEMENT CHAPTER (INTRODUCTION, (P | QUOTE | NOTE)*, DIV*)>
<!ELEMENT HR EMPTY>
<!ELEMENT p (#PCDATA | I)* >
<!ELEMENT %title; %content; >
<!ELEMENT DOCUMENT ANY>
Content_model
- ANY
- Cualquier tipo de contenido - Elementos o PCDATA
<!ELEMENT DOCUMENT ANY>
- Listas de elementos hijos
- Nombres de los elementos en paréntesis
<!ELEMENT direction (left, right, top?)>
- #PCDATA (Parsed Character Data)
- Texto sin marcas
<!ELEMENT First_Name (#PCDATA)>
Múltiples Hijos
- a+ - Una o más ocurrencias de a
<!ELEMENT BOOK (CHAPTER)+>
- a* - Cero o más ocurrencias de a
<!ELEMENT List (Object)*>
- a? - a o nada
<!ELEMENT Table (plate)?>
- a, b - a seguido de b
<!ELEMENT SUM (op1, op2)>
- a | b - a o b pero no no ambos
<!ELEMENT POINT (COORDINATES | POLAR)>
- (expression) - expresiones que pueden ser tomadas como una sola
<!ELEMENT CHAPTER (INTRODUCTION, (P | QUOTE | NOTE)*, DIV*)>
Sequences
<!ELEMENT Name (Last_Name, First_Name)
<Name>
<Last_Name>Punin</Last_Name>
<First_Name>John</First_Name>
</Name>Choices
<!ELEMENT ITEM (PRODUCT, NUMBER, (PRICE | CHARGEACCT | SAMPLE))>
<ITEM>
<PRODUCT>Tomatoes</PRODUCT>
<NUMBER>8</NUMBER>
<PRICE>$1.25</PRICE>
</ITEM>
<ITEM>
<PRODUCT>Oranges</PRODUCT>
<NUMBER>24</NUMBER>
<SAMPLE>$4.98</SAMPLE>
</ITEM>Mixed Content
- Ejemplo 1:
<!ELEMENT PRODUCT (#PCDATA | PRODUCT_ID)*>
<PRODUCT>Tomatoes</PRODUCT>
<PRODUCT>
<PRODUCT_ID>12411.95411.02121</PRODUCT_ID>
</PRODUCT>- Ejemplo 2:
<!ELEMENT p (#PCDATA | b)*>
<!ELEMENT b (#PCDATA)>
<p>This is <b>bold</b> text</p>Elementos Vacíos & Comentarios en DTDs
Elementos Vacíos:
<!ELEMENT CREDIT_WARNING EMPTY>
<CREDIT_WARNING></CREDIT_WARNING> or
<CREDIT_WARNING/>Comentarios DTD:
<!-- DOCUMENT is the root element -->
<!ELEMENT DOCUMENT (CUSTOMER)*>
Attributes
- Parejas Nombre/Valor
- Agregan información adicional a los tags de inicio
<CUSTOMER LAST_NAME="Smith" FIRST_NAME="Sam"
DATE="February 6, 2001" PURCHASE="Tomatoes"
PRICE="$1.25" NUMBER="8" />Declarando atributos en DTDs
<!ATTLIST element_name
attribute_name type default_value
attribute_name type default_value
.
.
.
attribute_name type default_value>
- element_name - nombre del elemento
- attribute_name - nombre del atributo
- type - tipo del atributo (ver siguiente sección)
- default_value - valor por default
<!ELEMENT greeting (#PCDATA)>
<!ATTLIST greeting
language CDATA "English">
<greeting language="Spanish">
Hola!
</greeting>Tipos de Atributos
- CDATA - Simple Character Data - Texto que no lleva marcas
<!ELEMENT Rectangle EMPTY>
<!ATTLIST Rectangle
length CDATA "0px"
width CDATA "0px">
<Rectangle width="11.px" length="40px"/>
Valores por default para CDATA
#REQUIRED
No hay un default, pero el atributo del documento debe indicar algun valor necesariamente
<!ELEMENT img EMPTY>
<!ATTLIST img
alt CDATA #REQUIRED
src CDATA #REQUIRED>
<img src="xmlj.jpg" alt="XMLJ Image"/>
#IMPLIED
No hay un default, y el atributo del documento no necesariamente tiene que utilizarse<!ELEMENT img EMPTY>
<!ATTLIST img
alt CDATA #REQUIRED
src CDATA #REQUIRED
width CDATA #IMPLIED
height CDATA #IMPLIED>
<img src="xmlj.jpg" alt="XMLJ Image" width="300"/>
#FIXED VALUE
Se fija el valor del atributo al valor "VALUE".<!ELEMENT ADDRESS (#PCDATA)>
<!ATTLIST ADDRESS
country CDATA #FIXED "USA">
<ADDRESS country="USA">123 15th St. Troy NY 12111.</ADDRESS>
- Enumerated - Listas de valores (se debe usar alguno de ellos)
<!ELEMENT TITLE (#PCDATA)>
<!ATTLIST TITLE
ALIGN (LEFT | CENTER | RIGHT) "LEFT">
<TITLE>Programming XML in Java</TITLE>
<TITLE ALIGN="CENTER">Programming XML in Java</TITLE>
- NMTOKEN - Una palabra que no puede contener letras, números, '.', '-', '_', o ':'. No puede tener espacios
<!ELEMENT student_name (#PCDATA)>
<!ATTLIST student_name student_no NMTOKEN #REQUIRED>
<student_name student_no="9216735">Jo Smith</student_name>
- NMTOKENS - Palabras que pueden tokenizarse por espacios
<!ATTLIST performances dates NMTOKENS #REQUIRED>
<performances dates="27-02-1977 04-11-1911. 24-12-2002">
Kat and the Kings
</performances>
- ID
- Identificador único del atributo
- No debe aparecer más de un sola vez en el documento XML
- El primer caracter deber una letra o '_', o ':'
- Lo demas caracteres no pueden ser espacios.
<!ELEMENT student_name (#PCDATA)>
<!ATTLIST student_name student_id ID #REQUIRED>
<student_name student_id="S9216735">Jo Smith</student_name>
- IDREF - Referencia hacia el ID de otro elemento.
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE lab_group [
<!ELEMENT lab_group (student_name)*>
<!ELEMENT student_name (#PCDATA)>
<!ATTLIST student_name student_id ID #REQUIRED
tutor IDREF #IMPLIED>
]>
<lab_group>
<student_name student_id="S11.0411.5">Alex Foo</student_name>
<student_name student_id="S9011133">Sarah Bar</student_name>
<student_name student_id="S9216735"
tutor="S11.0411.5">Jo Smith</student_name>
</lab_group>
Entidades (Entities)
- La manera en XML de identificar un elemento de datos
- Puede ser texto o datos binarios.
- General Entity
- Se usa en el contenido de un documento
- Las referencias empiezan con '&' y terminan con ';'
- Parameter Entity
- Se usa en un DTD
- Las referencias empiezan con '%' y terminan con ';'
- Internal Entity - Definida en un documento XML
- External Entity - Definina en una fuente externa: archivo, URI.
Internal General Entities
<!ENTITY name definition>
Ejemplo 1:
<!ELEMENT DATE (#PCDATA)>Ejemplo 2:
<!ENTITY TODAY "February 7, 2001">
<DATE>&TODAY;</DATE>
<!ENTITY NAME "John Punin">
<!ENTITY CNAME "&NAME; Palacios">External General Entities
<!ENTITY name SYSTEM URI>
<!ENTITY name PUBLIC FPI URI>
Ejemplo:
<!ELEMENT DATE (#PCDATA)>
<!ENTITY TODAY SYSTEM "date.xml">
<DATE>&TODAY;</DATE>Predefined General Entity References
- & - La letra &
- ' - La letra '
- > - La letra >
- < - La letra <
- " - La letra "
<!ELEMENT EMAIL (#PCDATA)>
<!ENTITY at_new "@">
<EMAIL>carlos&at_new;mail.udlap.mx</EMAIL>Parameter Entities
- Internal
<!ENTITY % name definition>
- External
<!ENTITY % name SYSTEM URI>
<!ENTITY % name PUBLIC FPI URI>Ejemplo:
<!ELEMENT CUSTOMER (NAME, DATE, ORDERS)>
<!ELEMENT BUYER (NAME, DATE, ORDERS)>
<!ELEMENT DISCOUNTER (NAME, DATE, ORDERS)>
<!ENTITY % record "(NAME, DATE, ORDERS)">
<!ELEMENT CUSTOMER %record;>
<!ELEMENT BUYER %record;>
<!ELEMENT DISCOUNTER %record;>
11.3 SAX
11.3.1 Simple API for XML
- Es una interfaz común implementada por varios parsers de XML
- Es la interfaz estándar basada en eventos para el análisis de XML
- SAX no es un XML Parser
- SAX2 es simplemente una nueva versión de SAX
- SAX2 agrega el soporte para XML Namespaces
- SAX 2.0/Java final release:
http://www.megginson.com/SAX/Java/index.htmlQué es un un API basado en eventos (Event-Based)?
- Son APIs que reportan eventos directamente a la aplicación a través de llamadas
- Start Element
- Start Document
- End Element
- Las aplicaciones deben implementar manejadores (handlers) para poder lidear con estos eventos
- El api basado en eventos es una manera simple y de bajo nivel para accesar los documentos XML
- Es posible analizar grandes documentos, más allá de la capacidad de memoria del sistema
- También es posible que la aplicación construya la estructura del documento usando los eventos generados
Cómo funciona SAX ?
- Documento XML
<?xml version="1.0"?>
<Name>
<Last_Name>Punin</Last_Name>
<First_Name>John</First_Name>
</Name>
- Eventos
start document
start element: Name
start element: Last_Name
characters: Punin
end element: Last_Name
start element: First_Name
characters: John
end element: First_Name
end element: Name
end documentSAX2/Java Parsers y Drivers
- The Apache XML Project's Xerces Java Parser
http://xml.apache.org/xerces-j/index.html- Sun's JAXP
http://java.sun.com/xml/- SAXON XSLT processor
http://users.iclway.co.uk/mhkay/saxon/- Oracle XML Developer's Kit for Java
http://technet.oracle.com/tech/xml/xdk_java.html- ParserAdapter
http://www.megginson.com/SAX/Java/index.html
Problema: Imprime una lista de los Elementos del siguiente documento XML:
11.3.2 Utilización de SAX
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">
<name>John Punin</name>
</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>
DefaultHandler
- Implementaciones por default para todas las llamadas de métodos
- Métodos requeridos
- void characters(char[] ch, int start, int length)
- void endDocument()
- void endElement(String uri, String localName, String rawName)
- void startDocument()
- void startElement(String uri, String localName, String rawName Attributes attributes)
SAXParser
- La clase SAXParser hereda de la clase XMLParser
java.lang.Object
|
+--org.apache.xerces.framework.XMLParser
|
+--org.apache.xerces.parsers.SAXParser
- Registrar el manejador SAXHandler con el parser SAXParser
- 4 interfaces de SAX
- Entity Resolver - maneja entidades externas
- DTDHandler - maneja eventos del DTD
- ContentHandler - maneja el contenido de un documento
- ErrorHandler - maneja los errores
Usando Xerces XML Parser
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;
public class SaxNames extends DefaultHandler
{
public void startElement(String uri, String localName, String rawName,
Attributes attributes)
{
System.out.println("Element : " + localName);
}
public static void main(String[] args)
{
try{
SaxNames SAXHandler = new SaxNames();
SAXParser parser = new SAXParser();
parser.setContentHandler(SAXHandler);
parser.setErrorHandler(SAXHandler);
parser.parse(args[0]);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
}Compilando y Corriendo el ejemplo
- javac -classpath "
xercesImpl.jar:xmlParserAPIs.jar
" SaxNames.java- java -classpath "
xercesImpl.jar:xmlParserAPIs.jar
" SaxNames students.xmlElement : course
Element : name
Element : teacher
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
11.3.3 Utilización de SAX (2)
Problema: Imprimir la lista de estudiantes, su promedio y el promedio del curso
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">
<name>John Punin</name>
</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>Creando el SAXHandler y Parser
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;
class SaxGrades extends DefaultHandler
{
....
public static void main(String[] args)
{
try{
SaxGrades SAXHandler = new SaxGrades();
SAXParser parser = new SAXParser();
parser.setContentHandler(SAXHandler);
parser.setErrorHandler(SAXHandler);
parser.parse(args[0]);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
}Manejado los eventos del startElement y endElement
static float grades[][] = new float[100][5];
int gi = -1;
int nstudent = 0;
public void startElement(String uri, String localName, String rawName,
Attributes attributes)
{
if(localName.equals("hw1"))
gi = 0;
else if(localName.equals("hw2"))
gi = 1;
else if(localName.equals("project"))
gi = 2;
else if(localName.equals("final"))
gi = 3;
else if(localName.equals("student"))
nstudent++;
}
public void endElement(String uri, String localName, String rawName)
{
gi = -1;
}Escribiendo los caracteres
public void characters(char characters[], int start, int length)
{
String chData = (new String(characters, start, length)).trim();
if(chData.indexOf("\n") < 0 && chData.length() > 0) {
if(gi >= 0){
grades[nstudent-1][gi] = Integer.parseInt(chData);
}
}
}Manejado el endDocument
public void endDocument()
{
float Ave = 0;
int i = 0, j = 0;
System.out.println("Grades");
for(i = 0; i < nstudent ; i++){
float total = 0;
for(j = 0; j < 4; j++){
total += grades[i][j];
}
grades[i][4] = total/4;
Ave += grades[i][4];
System.out.println("Student " + i + "=" + grades[i][4]);
}
Ave /= nstudent;
System.out.println("Class Average = " + Ave);
}Poniendo todo junto
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;
class SaxGrades extends DefaultHandler
{
static float grades[][] = new float[100][5];
int gi = -1;
int nstudent = 0;
public void startElement(String uri, String localName, String rawName,
Attributes attributes)
{
if(localName.equals("hw1"))
gi = 0;
else if(localName.equals("hw2"))
gi = 1;
else if(localName.equals("project"))
gi = 2;
else if(localName.equals("final"))
gi = 3;
else if(localName.equals("student"))
nstudent++;
}
public void endElement(String uri, String localName, String rawName)
{
gi = -1;
}
public void characters(char characters[], int start, int length)
{
String chData = (new String(characters, start,length)).trim();
if(chData.indexOf("\n") < 0 && chData.length() > 0){
if(gi >= 0){
grades[nstudent-1][gi] = Integer.parseInt(chData);
}
}
}
public void endDocument()
{
float Ave = 0;
int i = 0, j = 0;
System.out.println("Grades");
for(i = 0; i < nstudent ; i++){
float total = 0;
for(j = 0; j < 4; j++){
total += grades[i][j];
}
grades[i][4] = total/4;
Ave += grades[i][4];
System.out.println("Student " + i + "=" + grades[i][4]);
}
Ave /= nstudent;
System.out.println("Class Average =" + Ave);
}
}
public static void main(String[] args)
{
try{
SaxGrades SAXHandler = new SaxGrades();
SAXParser parser = new SAXParser();
parser.setContentHandler(SAXHandler);
parser.setErrorHandler(SAXHandler);
parser.parse(args[0]);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}Compilando y corriendo el ejemplo (SaxGrades)
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" SaxGrades.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" SaxGrades students.xml
Grades
Student 0= 66.25
Student 1= 77.5
Student 2= 73.75
Class Average = 72.5
11.3.4 Utilización de SAX (empleando atributos)
Attributes Interface
int getIndex(String rawName)
Gets the index of an attribute given a raw name
String getRawName(int index)
Gets the attribute's raw name by index
String getValue(int index)
Gets an attribute's value by index
String getValue(String rawName)
Gets an attribute's value by raw name
Problema: Calcular el área de cada una de las figuras:<?xml version="1.0"?>
<figures>
<circle x="20" y="10" r="20"/>
<rectangle x="-3" y="4" w="5" h="36"/>
<ellipse x="-5" y="6" w="30" h="50"/>
<rectangle x="7" y="23" w="58" h="45"/>
<circle x="-2" y="5" r="35"/>
<ellipse x="-10" y="-8" w="45" h="30"/>
</figures>import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;
public class SaxFigures extends DefaultHandler
{
public void startElement(String uri, String localName, String rawName,
Attributes attributes)
{
if(localName.equals("circle"))
{
String sr = attributes.getValue("r");
float radius = Float.valueOf(sr).floatValue();
float area = (float)Math.PI*radius*radius;
System.out.println("Circle : Radius = " + radius +
" Area = " + area);
}
else if(localName.equals("ellipse"))
{
String sw = attributes.getValue("w");
String sh = attributes.getValue("h");
float width = Float.valueOf(sw).floatValue();
float height = Float.valueOf(sh).floatValue();
float area = (float)Math.PI*(width/2)*(height/2);
System.out.println("Ellipse : Width = " + width +
" Height = " + height +
" Area = " + area);
}
else if(localName.equals("rectangle"))
{
String sh = attributes.getValue("h");
String sw = attributes.getValue("w");
float width = Float.valueOf(sw).floatValue();
float height = Float.valueOf(sh).floatValue();
float area = width * height;
System.out.println("Rectangle : Width = " + width +
" Height = " + height +
" Area = " + area);
}
}
public static void main(String[] args)
{
try{
SaxFigures SAXHandler = new SaxFigures();
SAXParser parser = new SAXParser();
parser.setContentHandler(SAXHandler);
parser.setErrorHandler(SAXHandler);
parser.parse(args[0]);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
}
Compilando y corriendo el ejemplo (SaxFigures)
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" SaxFigures.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" SaxFigures figures.xml
Circle : Radius = 20.0 Area = 1256.6371
Rectangle : Width = 5.0 Height = 36.0 Area = 111..0
Ellipse : Width = 30.0 Height = 50.0 Area = 11711.0973
Rectangle : Width = 511.0 Height = 45.0 Area = 2610.0
Circle : Radius = 35.0 Area = 311.11.4512
Ellipse : Width = 45.0 Height = 30.0 Area = 1060.211.6
11.4 DOM
11.4.1 W3C Document Object Model (DOM)
Documentos de XML son tratados como árboles de nodos
Cada item es un nodo (node)
Elementos hijos y los textos son consideras como subnodos (subnodes)
W3C DOM Site: http://www.w3.org/DOM/
DOM Java Language Binding:
http://www.w3.org/TR/DOM-Level-2-Core/java-binding.html
Objetos del W3C XML DOM
Element - Un elemento
Attribute - Un atributo
Text - Texto contenido por un elemento o atributo
CDATAsection - Sección CDATA
EntityReference - Referencia a una entidad
Entity - Indicación de una entidad
ProcessingInstruction - Instrucción de procesamiento
Comment - Contenido de un Comentario
Document - Un documento
DocumentType - Referencia el elemento
<!DOCTYPE>
DocumentFragment - Referencia a un fragmento de un documento
Notation - Notación
Objetos relacionado a los nodos
Node - Un nodo del árbol del documento
NodeList - Una lista de nodos
NamedNodeMap - Permite la interacción y acceso por nombre a la colección de atributos
Documento XML como un árbol de nodos
<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT>
<GREETING>Hello from XML</GREETING>
<MESSAGE>Welcome to Programing XML in Java</MESSAGE>
</DOCUMENT>
Niveles de DOM
Level 0 - Versiones iniciales de DOM en los browsers
Level 1 - Concentrado en los modelos de HTML y XML:
Level 2 - Define un conjunto de objetos e interfaces para el acceso y manipulación de documentos
Document Object Model (DOM) Level 2 Core Specification:
http://www.w3.org/TR/DOM-Level-2-Core/Level 3 - Manejará el acceso, abrir y guardar, no solo de documentos sino de DTDs y schemas
Document Object Model (DOM) Level 3 Core Specification
http://www.w3.org/TR/DOM-Level-3-Core/DOM XML Parsers
Oracle XML parser for Java
http://technet.oracle.com/tech/xml/parser_java2/index.htmXerces Java Parser
http://xml.apache.org/xerces-j/index.htmlIBM XML4J Parser
http://alphaworks.ibm.com/tech/xml4jTurboPower XML Partner
http://www.turbopower.com/products/xmlpartner/
11.4.2 Utilización de DOMProblema: Desplegar el conteo de elementos
<students>
del siguiente documento:
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">
<name>John Punin</name>
</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>
Clase DOMParser
Xerces 1.3.1 Package org.w3c.dom http://xml.apache.org/apiDocs/org/w3c/dom/package-summary.html
Complete Xerces API documentation
http://xml.apache.org/apiDocs/index.htmlDOMParser class is derived from the XMLParser class
java.lang.Object
|
+--org.apache.xerces.framework.XMLParser
|
+--org.apache.xerces.parsers.DOMParser
parse()
analiza la entrada (archivo)Document
getDocument()
Método que devuelve el documento como tal
Métodos de la interface Document
Attr createAttribute(String name)
Creates an attribute of the given name
Element createElement(String tagName)
Creates an element of the type given
Text createTextNode(String data)
Creates a Text Node
Element getDocumentElement()
Gets the root element of the document
Element getElementById(String elementId)
Get the element with the given ID
NodeList getElementsByTagName(String tagname)
Returns a NodeList of all the elements with a given tag name
Métodos de la interface NodeList
int getLength()
Gets the number of nodes in this list
Node item(int index)
Gets the item at the specified index value in the collection
Usando Xerces XML Parser
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
public class DOMCountNames
{
public static void main(String[] args)
{
try{
DOMParser parser = new DOMParser();
parser.parse(args[0]);
Document doc = parser.getDocument();
NodeList nodelist = doc.getElementsByTagName("student");
System.out.println(args[0] + " has " + nodelist.getLength()
+ " <student> elements.");
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
}Compilando y corriendo el ejemplo DOMCountNames
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMCountNames.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMCountNames students.xml
students.xml has 3 <student> elements.
11.4.3 Utilización de DOM (documentos enteros)Métodos de la interface Node
NamedNodeMap getAttributes()
Gets a NamedNodeMap containing the attributes of this node
NodeList getChildNodes()
Gets a NodeList that contains all children of this node
String getLocalName()
Gets the local name of the node
String getNodeName()
Gets the name of this node
String getNodeValue()
Gets the value of this node
Node getParentNode()
Gets the parent of this node
short getNodeType()
Gets a code representing the type of the nodeNode Types
static short ATTRIBUTE_NODE
static short CDATA_SECTION_NODE
static short COMMENT_NODE
static short DOCUMENT_FRAGMENT_NODE
static short DOCUMENT_NODE
static short DOCUMENT_TYPE_NODE
static short ELEMENT_NODE
static short ENTITY_NODE
static short ENTITY_REFERENCE_NODE
static short NOTATION_NODE
static short PROCESSING_INSTRUCTION_NODE
static short TEXT_NODE
Recorriendo el documento entero
Problema: Desplegar una lista de los elementos del documento:
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">
<name>John Punin</name>
</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
class DOMDisplayElements
{
public static void displayDocument(String uri)
{
try{
DOMParser parser = new DOMParser();
parser.parse(uri);
Document doc = parser.getDocument();
display_names(doc);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
public static void display_names(Node node)
{
.
.
.
}
public static void main(String[] args)
{
DOMDisplayElements.displayDocument(args[0]);
}
}
Handling Document Nodes:
public static void display_names(Node node)
{
if(node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
display_names(((Document)node).getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
.
.
.
break;
}
}
}
Handling Element Nodes:
case Node.ELEMENT_NODE: {
System.out.println("Element : " + node.getNodeName());
NodeList childNodes = node.getChildNodes();
if(childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length ; loopIndex++)
{
display_names(childNodes.item(loopIndex));
}
}
break;
}Poniendo todo junto
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
class DOMDisplayElements
{
public static void displayDocument(String uri)
{
try{
DOMParser parser = new DOMParser();
parser.parse(uri);
Document doc = parser.getDocument();
display_names(doc);
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
public static void display_names(Node node)
{
if(node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
display_names(((Document)node).getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
System.out.println("Element : " + node.getNodeName());
NodeList childNodes = node.getChildNodes();
if(childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length ; loopIndex++)
{
display_names(childNodes.item(loopIndex));
}
}
break;
}
}
}
public static void main(String[] args)
{
DOMDisplayElements.displayDocument(args[0]);
}
}Compilando y corriendo el ejemplo DOMNameElements
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMDisplayElements.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMDisplayElements students.xml
Element : course
Element : name
Element : teacher
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
Element : student
Element : name
Element : hw1
Element : hw2
Element : project
Element : final
11.4.4 Utilización de DOM (Manejando Nodes)
Problema: Desplegar una lista de estudiantes, su promedio y el promedio del curso
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">
<name>John Punin</name>
</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>Creando DOMParser y Document
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
class DOMGrades
{
public static void computeGrades(String uri)
{
try{
DOMParser parser = new DOMParser();
parser.parse(uri);
Document doc = parser.getDocument();
traverse_tree(doc);
compute_final_grades();
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
.
.
.
public static void main(String[] args)
{
Grades.computeGrades(args[0]);
}
}Manejando Document Node, Element Node y Text Node
static float grades[][] = new float[100][5];
static int nstudent = 0;
static int gi = -1;
private static void traverse_tree(Node node)
{
if(node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
traverse_tree(((Document)node).getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
String elementName = node.getNodeName();
gi = -1;
if(elementName.equals("hw1"))
gi = 0;
else if(elementName.equals("hw2"))
gi = 1;
else if(elementName.equals("project"))
gi = 2;
else if(elementName.equals("final"))
gi = 3;
else if(elementName.equals("student"))
nstudent++;
NodeList childNodes = node.getChildNodes();
if(childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length ; loopIndex++)
{
traverse_tree(childNodes.item(loopIndex));
}
}
break;
}
case Node.TEXT_NODE: {
String chData = node.getNodeValue().trim();
if(chData.indexOf("\n") < 0 && chData.length() > 0) {
if(gi >= 0)
grades[nstudent-1][gi] = Integer.parseInt(chData);
}
}
}
}Calculando las calificaciones después de recorrer el árbol
static float grades[][] = new float[100][5];
static int nstudent = 0;
private static void compute_final_grades()
{
float Ave = 0;
int i = 0, j = 0;
System.out.println("Grades");
for(i = 0; i < nstudent ; i++)
{
float total = 0;
for(j = 0; j < 4; j++) {
total += grades[i][j];
}
grades[i][4] = total/4;
Ave += grades[i][4];
System.out.println("Student " + i + "=" + grades[i][4]);
}
Ave /= nstudent;
System.out.println("Class Average =" + Ave);
}Poniendo todo junto
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
class DOMGrades
{
static float grades[][] = new float[100][5];
static int nstudent = 0;
static int gi = -1;
public static void computeGrades(String uri)
{
try {
DOMParser parser = new DOMParser();
parser.parse(uri);
Document doc = parser.getDocument();
traverse_tree(doc);
compute_final_grades();
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void compute_final_grades()
{
float Ave = 0;
int i = 0, j = 0;
System.out.println("Grades");
for(i = 0; i < nstudent ; i++)
{
float total = 0;
for(j = 0; j < 4; j++) {
total += grades[i][j];
}
grades[i][4] = total/4;
Ave += grades[i][4];
System.out.println("Student " + i + "=" + grades[i][4]);
}
Ave /= nstudent;
System.out.println("Class Average =" + Ave);
}
private static void traverse_tree(Node node)
{
if(node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
traverse_tree(((Document)node).getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
String elementName = node.getNodeName();
gi = -1;
if(elementName.equals("hw1"))
gi = 0;
else if(elementName.equals("hw2"))
gi = 1;
else if(elementName.equals("project"))
gi = 2;
else if(elementName.equals("final"))
gi = 3;
else if(elementName.equals("student"))
nstudent++;
NodeList childNodes = node.getChildNodes();
if(childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length ; loopIndex++)
{
traverse_tree(childNodes.item(loopIndex));
}
}
break;
}
case Node.TEXT_NODE: {
String chData = node.getNodeValue().trim();
if(chData.indexOf("\n") < 0 && chData.length() > 0) {
if(gi >= 0)
grades[nstudent-1][gi] = Integer.parseInt(chData);
}
}
}
}
public static void main(String[] args)
{
DOMGrades.computeGrades(args[0]);
}
}Compilando y corriendo el ejemploDOMGrades
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMGrades.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMGrades students.xml
Grades
Student 0=66.25
Student 1=77.5
Student 2=73.75
Class Average =72.5
11.4.5 Utilización de DOM (empleando atributos)Attr Interface Methods:
String getName()
Gets the name of this attribute
Element getOwnerElement()
Gets the Element node to which this attribute is attached
String getValue()
Gets the value of the attribute as a string
NamedNodeMap Interface Methods:
int getLength()
Returns the number of nodes in this map
Node getNamedItem(String name)
Gets a node indicated by name
Node item(int index)
Gets an item in the map by index
Problema: Calcular el área de las figuras
<?xml version="1.0"?>
<figures>
<circle x="20" y="10" r="20"/>
<rectangle x="-3" y="4" w="5" h="36"/>
<ellipse x="-5" y="6" w="30" h="50"/>
<rectangle x="7" y="23" w="58" h="45"/>
<circle x="-2" y="5" r="35"/>
<ellipse x="-10" y="-8" w="45" h="30"/>
</figures>case Node.ELEMENT_NODE:
{
String elementName = node.getNodeName();
NamedNodeMap attrs = node.getAttributes();
if(elementName.equals("circle")) {
Attr attrib = (Attr)attrs.getNamedItem("r");
String sr = attrib.getValue();
float radius = Float.valueOf(sr).floatValue();
float area = (float)Math.PI*radius*radius;
System.out.println("Circle : Radius = " + radius +
" Area = " + area);
}
}Poniendo todo junto
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
class DOMFigures
{
public static void computeArea(String uri)
{
try{
DOMParser parser = new DOMParser();
parser.parse(uri);
Document doc = parser.getDocument();
traverse_tree(doc);
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
private static void traverse_tree(Node node)
{
if(node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
traverse_tree(((Document)node).getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
String elementName = node.getNodeName();
NamedNodeMap attrs = node.getAttributes();
if(elementName.equals("circle")) {
Attr attrib = (Attr)attrs.getNamedItem("r");
String sr = attrib.getValue();
float radius = Float.valueOf(sr).floatValue();
float area = (float)Math.PI*radius*radius;
System.out.println("Circle : Radius = " + radius + " Area = " + area);
}
else if(elementName.equals("rectangle")) {
Attr attrib = (Attr)attrs.getNamedItem("w");
String sw = attrib.getValue();
attrib = (Attr)attrs.getNamedItem("h");
String sh = attrib.getValue();
float width = Float.valueOf(sw).floatValue();
float height = Float.valueOf(sh).floatValue();
float area = width * height;
System.out.println("Rectangle : Width = " + width +
" Height = " + height + " Area = " + area);
}
else if(elementName.equals("ellipse")) {
Attr attrib = (Attr)attrs.getNamedItem("w");
String sw = attrib.getValue();
attrib = (Attr)attrs.getNamedItem("h");
String sh = attrib.getValue();
float width = Float.valueOf(sw).floatValue();
float height = Float.valueOf(sh).floatValue();
float area = (float)Math.PI*(width/2)*(height/2);
System.out.println("Ellipse : Width = " + width +
" Height = " + height + " Area = " + area);
}
NodeList childNodes = node.getChildNodes();
if(childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length ; loopIndex++)
{
traverse_tree(childNodes.item(loopIndex));
}
}
break;
}
}
}
public static void main(String[] args)
{
DOMFigures.computeArea(args[0]);
}
}Compilando y corriendo el ejemploDOMFigures
javac -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMFigures.java
java -classpath "xercesImpl.jar:xmlParserAPIs.jar" DOMFigures figures.xml
Circle : Radius = 20.0 Area = 1256.6371
Rectangle : Width = 5.0 Height = 36.0 Area = 111..0
Ellipse : Width = 30.0 Height = 50.0 Area = 11711.0973
Rectangle : Width = 511.0 Height = 45.0 Area = 2610.0
Circle : Radius = 35.0 Area = 311.11.4512
Ellipse : Width = 45.0 Height = 30.0 Area = 1060.211.6
11.5 XML Namespaces
11.5.1 XML Namespaces
Resuelven un gran problema: Conflictos entre nombres de tags
XHTML - HTML 4.0 escrito en XML
MathML - Despliega equaciones matemáticas
XHTML y MathML se empalman/intersectan en algunos tags: <var>, <select>
11.5.2 Creando un Namespace
Documento XML sin namespaces
<?xml version="1.0"?> <book> <title>Programming XML in Java</title> </book>Documento XML con un namespace
- Un namespace es definido de la siguiente manera "xmlns:prefix"
- Prefix es la palabra que identificará al namespace
- El atributo xmlns:prefix debe estar asignado a un URI
- Cada tag debe ser escrito agregando el prefijo del namespace
- En realidad el prefijo es sustituido por el URI correspondiente
<?xml version="1.0"?> <!-- both namespace prefixes are available throughout --> <bk:book xmlns:bk='http://www.books.org/books'> <bk:title>Programing XML in Java</bk:title> </bk:book>
Documento XML con namespaces
<?xml version="1.0"?> <!-- both namespace prefixes are available throughout --> <bk:book xmlns:bk='http://www.books.org/books' xmlns:isbn='urn:ISBN:0-395-36341-6'> <bk:title>Programing XML in Java</bk:title> <isbn:number>15611.91379</isbn:number> </bk:book>
Creando Namespaces locales
El atributo xmlns puede ser utilizado en cualquier elemento
<?xml version="1.0"?> <!-- both namespace prefixes are available throughout --> <bk:book xmlns:bk='http://www.books.org/books'> <bk:title>Programing XML in Java</bk:title> <isbn:number xmlns:isbn='urn:ISBN:0-395-36341-6'> 15611.91379 </isbn:number> </bk:book>Default Namespaces
A partir de la definición de un xmlns, ese namespace se toma por default
Todos los elementos encerrados se asume que pertenecen a ese namespace
<?xml version="1.0"?> <!-- both namespace prefixes are available throughout --> <book xmlns='http://www.books.org/books'> <title>Programing XML in Java<title> <isbn:number xmlns:isbn='urn:ISBN:0-395-36341-6'> 15611.91379 </isbn:number> </book>Combining XHTML and MathML using namespaces
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>A Math Example</title> </head> <body> <p>The following is MathML markup:</p> <math xmlns="http://www.w3.org/19911.Math/MathML"> <apply> <log/> <logbase><cn>3</cn></logbase> <ci> x </ci> </apply> </math> </body> </html>Notas a cerca de los Atributos
Ningún tag debe contener 2 atributos con:
Nombres idénticos o
Nombres idénticos que pertenezcan al mismo namespace (prefijo); si pertenecen a namespaces diferentes entonces si pueden tener nombres idénticos.
Ejemplo Válido:
<?xml version="1.0"?> <RESERVATION xmlns="http://www.aeroline.com/reservations" xmlns:html="http://www.w3.org/1999/xhtml"> <NAME html:class="largeSansSerif">Layman, A</NAME> <SEAT class="Y" html:class="largeMonotype">33B</SEAT> <html:a href='/cgi-bin/ResStatus'>Check Status</html:a> <DEPARTURE>1997-05-24T07:55:00+1</DEPARTURE> </RESERVATION>Ejemplo Inválido:
<!-- http://www.w3.org is bound to n1 and n2 --> <x xmlns:n1="http://www.w3.org" xmlns:n2="http://www.w3.org" > <bad a="1" a="2" /> <bad n1:a="1" n2:a="2" /> </x>
11.6 XPath
11.6.1 XML Path
Expresiones para identificar partes particulares de un documento XML
Especifica un nodo o un conjunto de nodos
Una ruta de localización (location path) consiste en uno o más pasos de localización
Rutas absolutas comienzan con /
Rutas relativas NO comienzan con /
- Los pasos pueden ser:
- Eje (axis)
- Nodo a ser interrogado (node test)
- 0 o más predicados (predicates)
- child::student[position() = 2]
- child (axis)
- student (node test)
- position() = 2 (predicate)
11.6.2 XPath axis
ancestor
ancestor-or-self
attribute
child
descendant
descendant-or-self
following
following-sibling
namespace
parent
preceding
preceding-sibling
self
11.6.3 XPath Node tests
comment()
node()
processing-instruction()
text()
11.6.4 XPath Predicates
Node Sets
last()
- Returns the number of nodes in a node setposition()
- Returns the position of the context nodecount(node-set)
- Returns the number of nodeslocal-name(node-set)
- Returns the local name of the first nodenamespace-uri(node-set)
- Returns the URI of the namespace of the first nodename(node-set)
- Returns the full, qualified name of the first node
- Booleans
!=
- Is not equal to<
- Is less than (use < in XML documents)<=
- Is less than or equal to=
- Is equal to>
- Is greater than>=
- Is greater than or equal toand
- And operatoror
- Or operatortrue()
- returns truefalse()
- returns false
Example:<xsl:template match="student[position() > 2]">
...
</xsl:template>- Numbers
+
- Addition-
- Substraction*
- Multiplicationdiv
- Divisionmod
- Modulusceiling()
- Smallest integerfloor()
- Largest integerround()
- Nearest integersum()
- Sum of numbers
- Strings
- starts-with(string string1, string string2) - Boolean
- contains(string string1, string string2) - Boolean
- substring(string string1, number offset, number length) - String
- substring-before(string string1, string string2) - String
- substring-after(string string1, string string2) - String
- string-length(string string1) - Number
- normalize-space(string string1) - String
- translate(string string1, string string2,string string3) - String
- concat(string string1, string string2,...) - String
- Result tree fragments
11.6.5 Ejemplo de XPath
- child::student
- attribute::id
- descendant::name
- ancestor::hw1
- self::teacher
- /descendant::student/child::name
- child::student[attribute::id="js"]
- child::student[child::name]
11.6.6 Sintáxis abreviada de XPath
Expression
self::node()
parent::node()
child::childname
attribute::childname
/descendant-or-self::node()/
Abbreviation
.
..
childname
@childname
//
XPath Abbreviated Syntax Examples
- student
- *
- text()
- @id
- student[2]
- */student
- /course/student[2]/name
- //student
- ../@id
- student[name]
- student[name="John Punin"]
- student[id="js"]
- student[hw1 or hw2]
11.7 Extensible Style Language Transformations (XSLT)
11.7.1 Qué es XSL?
Es 2 cosas:
Transformation Language (XSLT)
Formatting Language (XSL Formatting Objects)
XSLT transforma un documento XML en otro documento XML
XSLFO da formato y estilo a un documento de diversas maneras
XSLT - http://www.w3.org/TR/xslt
11.7.2 Operaciones en árbol dentro de XSL
11.7.3 Usando XSLT Style Sheets
Para poder hacer una tranformación se necesita:
Documento XML ha ser transformado (students.xml)
Style Sheet que especifica la transformación (students.xsl)
XML Document (students.xml)
<?xml version="1.0"?>
<course>
<name id="csci_2962">Programming XML in Java</name>
<teacher id="jp">John Punin</teacher>
<student id="js">
<name>John Smith</name>
<hw1>30</hw1>
<hw2>70</hw2>
<project>11.</project>
<final>11.</final>
</student>
<student id="gl">
<name>George Lucas</name>
<hw1>11.</hw1>
<hw2>90</hw2>
<project>100</project>
<final>40</final>
</student>
<student id="lr">
<name>Elizabeth Roberts</name>
<hw1>60</hw1>
<hw2>95</hw2>
<project>50</project>
<final>90</final>
</student>
</course>XSLT Style Sheet (students.xsl)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="course">
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates select="student"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="student">
<P>
<xsl:value-of select="name"/>
</P>
</xsl:template>
</xsl:stylesheet>Realizando la transformación
En el servidor - Debe existir un programa, ej Java Servlet, que utiliza la hoja de estilo para transformarlo automáticamente enviarlo al cliente
En el cliente - Un programa, ej un navegador, puede hacer la tranformación en base a la especificación de la hoja de estilo
<?xml-stylesheet href="students.xsl" type="text/xsl"?>
<course>... </course>
Nota: Algunos browsers no tienen asociada la extensión/mimetype xsl marcarán un error, la solución es nombrar la hoja de estilo con extensión xml.
Con un programa independiente - Programas o aplicaciones que realizan todas las acciones con algun objetivo en particular
11.7.4 Procesadores de XSLT
Oracle XML parser for Java
http://technet.oracle.com/tech/xml/parser_java2/Sablotron
http://www.gingerall.com/charlie-bin/get/webGA/act/sablotron.actMicrosoft XML Parser
http://msdn.microsoft.com/downloads/webtechnology/xml/msxml.aspXalan Java
http://xml.apache.org/xalan-j/index.html
Utilizando el procesador Xalan
XML document (students.xml)
XSLT style sheet (students.xsl)
Xalan jar file (xalan.jar)
java -classpath "xalan.jar" org.apache.xalan.xslt.Process
-IN students.xml -XSL students.xsl -OUT students.html
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.StringWriter;
import java.io.IOException;import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import mx.udlap.ict.util.*;
public class SimpleTransform
{
public static void main(String[] args)
throws TransformerException, TransformerConfigurationException,
FileNotFoundException, IOException
{
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource("students.xsl"));
String out=new String();
StringWriter sw=new StringWriter();
transformer.transform(new StreamSource("students.xml"), new StreamResult(sw));
out=sw.toString();
}
}
Output File (students.html)
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<P>John Smith</P>
<P>George Lucas</P>
<P>Elizabeth Roberts</P>
</BODY>
</HTML>11.7.5 Creando XSLT Style Sheets
Documentos XML son árboles de nodos
Tipos de Nodos
Document root
Start of document
Attribute - Value of an attribute
Comment - Text of a comment
Element - Character data in the element
Namespace - Namespace's URI
Processing Instruction - Text of processing instruction
Text - Hold the text of the node
XSLT Style Sheets are well formed XML Documents
La hoja de estilo es también un documento XML
xsl:stylesheet - elemento raíz
xsl:template - cómo tranformar el nodo seleccionado
match - atributo para seleccionar el nodo (usando XPath)
"/" - nodo raíz del documento XML de entrada (que será transformado)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
.
.
.
</xsl:template>
</xsl:stylesheet>La hoja de estilo más simple, sin hacer nada.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>
New XML Document
</TITLE>
</HEAD>
<BODY>
Programming XML in Java
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>El elemento xsl:apply-templates
Aplica los cambios (templates) a los hijos del nodo seleccionado
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="course">
<xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="student">
<P>
Student Data
</P>
</xsl:template>
</xsl:stylesheet>El elemento xsl:value-of
Obtener el valor de los nodos y poder escribirlo en archivo de salida
XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="course">
<xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="student">
<P>
<xsl:value-of select="name"/>
</P>
</xsl:template>
</xsl:stylesheet>HTML output file:
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<P>John Smith</P>
<P>George Lucas</P>
<P>Elizabeth Roberts</P>
</BODY>
</HTML>Manejando selecciones múltiples con xsl:for-each
Select attribute solo selecciona el primer nodo (elemento) que cumpla con el criterio
En este caso el student solo tiene un tag "name", pero si tuviera varios, solo obtendríamos el primero
Si se quiere tener múltiples selecciones, recuperar los demás "name" contenidos en un nodo entonces se debe utilizar xsl:for-each
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Name of students</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="course">
<xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="student">
<xsl:for-each select="name">
<P> <xsl:value-of select="."/> </P>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>Especificando patrones para el atributo "match"
Encontrando el nodo raíz:
<xsl:template match="/">
...
</xsl:template>Encontrando elementos:
<xsl:template match="student">
...
</xsl:template>Encontrando elementos hijos:
<xsl:template match="course/student">
...
</xsl:template>
<xsl:template match="course/*/name">
...
</xsl:template>Encontrando hijos descendientes:
<xsl:template match="course//name">
...
</xsl:template>Ejemplo:
XSL Style Sheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Names</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="course/name">
<H2>
<xsl:value-of select="."/>
</H2>
</xsl:template>
<xsl:template match="course/*/name">
<H3>
<xsl:value-of select="."/>
</H3>
</xsl:template>
</xsl:stylesheet>
HTML output file:
<HTML>
<HEAD>
<TITLE>Names</TITLE>
</HEAD>
<BODY>
<H2>Programming XML in Java</H2>
<H3>John Smith</H3>
<H3>George Lucas</H3>
<H3>Elizabeth Roberts</H3>
</BODY>
</HTML>
Encontrando atributos
Colocar el prefijo @ a los nombres de atributos
Ejemplo:
XML Document Input (figures.xml)
<?xml version="1.0"?>
<figures>
<circle x="20" y="10" r="20"/>
<rectangle x="-3" y="4" w="5" h="36"/>
<ellipse x="-5" y="6" w="30" h="50"/>
<rectangle x="7" y="23" w="58" h="45"/>
<circle x="-2" y="5" r="35"/>
<ellipse x="-10" y="-8" w="45" h="30"/>
</figures>XSL Style Sheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD><TITLE>Figures</TITLE></HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="figures">
<TABLE>
<TR><TD>X</TD><TD>Y</TD></TR>
<xsl:apply-templates select="circle"/>
</TABLE>
</xsl:template>
<xsl:template match="circle">
<TR> <TD><xsl:value-of select="@x"/></TD>
<TD><xsl:value-of select="@y"/></TD> </TR>
</xsl:template>
</xsl:stylesheet>HTML output file:
<HTML>
<HEAD>
<TITLE>Figures</TITLE>
</HEAD>
<BODY>
<TABLE>
<TR>
<TD>X</TD><TD>Y</TD>
</TR>
<TR>
<TD>20</TD><TD>10</TD>
</TR>
<TR>
<TD>-2</TD><TD>5</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Matching Comments:
<xsl:template match="comment()">
...
</xsl:template>Matching Text Nodes:
<xsl:template match="text()">
...
</xsl:template>
Using the OR operator:
Example: Generar una lista de los nombres de estudiantes y las calificaciones de sus proyectos
XSL Style Sheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="course">
<HTML>
<HEAD>
<TITLE>Projects Grades</TITLE>
</HEAD>
<BODY>
<TABLE>
<xsl:apply-templates select="student"/>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="student">
<TR><xsl:apply-templates/></TR>
</xsl:template>
<xsl:template match="name | project">
<TD><xsl:value-of select="."/></TD>
</xsl:template>
</xsl:stylesheet>HTML output file:
<HTML>
<HEAD>
<TITLE>Projects Grades</TITLE>
</HEAD>
<BODY>
<TABLE>
<TR>
<TD>John Smith</TD><TD>11.</TD>
</TR>
<TR>
<TD>George Lucas</TD><TD>100</TD>
</TR>
<TR>
<TD>Elizabeth Roberts</TD><TD>50</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Validando con []
Valida cuándo una condición es "true", por ejemplo:
elemento "student" con un elemento hijo "name"
<xsl:template match="student[name]">
Cualquier elemento que tenga un subelemento "name"
<xsl:template match="*[name]">
Elemento "student" que tenga los subelementos "hw1" o "hw2"
<xsl:template match="student[hw1 | hw2]">
Example: Nombre del estudiante con id 'js'
XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="course">
<NAME>
<xsl:apply-templates select="student"/>
</NAME>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="student[@id = 'js']">
<xsl:value-of select="name"/>
</xsl:template>
</xsl:stylesheet>11.7.6 Reglas por default de XSLT
1. <xsl:template match="/ | *">
<xsl:apply-templates/>
</xsl:template>
2. <xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
3. <xsl:template match="@">
<xsl:value-of select="."/>
</xsl:template>
4. <xsl:template match="comment()"/>
5. <xsl:template match="processing-instruction()"/>
Style-sheet sin reglas:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>
Output File (aplicado a students.xml):
<?xml version="1.0" encoding="UTF-8"?>
Programming XML in Java
John Punin
John Smith
30
70
11.
11.
George Lucas
11.
90
100
40
Elizabeth Roberts
60
95
50
9011.7.7 Creando "templates" para atributos
Convertir el texto de algunos elementos en atributos de otros elementos
XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="course">
<STUDENTS>
<xsl:apply-templates select="student"/>
</STUDENTS>
</xsl:template>
<xsl:template match="student">
<STUDENT NAME="{name}"
HW1="{hw1}"
HW2="{hw2}"
PROJECT="{project}"
FINAL="{final}"/>
</xsl:template>
</xsl:stylesheet>XML output file:
<?xml version="1.0" encoding="UTF-8"?>
<STUDENTS>
<STUDENT FINAL="11." PROJECT="11." HW2="70" HW1="30" NAME="John Smith"/>
<STUDENT FINAL="40" PROJECT="100" HW2="90" HW1="11." NAME="George Lucas"/>
<STUDENT FINAL="90" PROJECT="50" HW2="95" HW1="60" NAME="Elizabeth Roberts"/>
</STUDENTS>11.7.11.Creando nuevos Elementos
Para crear nuevos elementos se utiliza<xsl:element>
XML document (animals.xml):
<?xml version="1.0"?>
<animals>
<animal name="dog" class="mammal" legs="4"/>
<animal name="shark" class="fish" legs="0"/>
<animal name="chicken" class="bird" legs="2"/>
</animals>Transformarlo al XML document (pets.xml):
<?xml version="1.0" encoding="UTF-8"?>
<pets>
<mammal>
<name>dog</name>
<legs>4</legs>
</mammal>
<fish>
<name>shark</name>
<legs>0</legs>
</fish>
<bird>
<name>chicken</name>
<legs>2</legs>
</bird>
</pets>XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="animals">
<pets>
<xsl:apply-templates select="animal"/>
</pets>
</xsl:template>
<xsl:template match="animal">
<xsl:element name="{@class}">
<name><xsl:value-of select="@name"/></name>
<legs><xsl:value-of select="@legs"/></legs>
</xsl:element>
</xsl:template>
</xsl:stylesheet>11.7.9 Creando nuevos Atributos
Para crear nuevos atributos se utiliza <xsl:attribute>
XML document (animals.xml):
<?xml version="1.0"?>
<animals>
<animal name="dog" class="mammal" legs="4"/>
<animal name="shark" class="fish" legs="0"/>
<animal name="chicken" class="bird" legs="2"/>
</animals>Transformarlo al XML document (pets.xml):
<?xml version="1.0" encoding="UTF-8"?>
<pets>
<mammal name="dog" legs="4"/>
<fish name="shark" legs="0"/>
<bird name="chicken" legs="2"/>
</pets>XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="animals">
<pets>
<xsl:apply-templates select="animal"/>
</pets>
</xsl:template>
<xsl:template match="animal">
<xsl:element name="{@class}">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="legs">
<xsl:value-of select="@legs"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>11.7.10 Copiando y ordenando nodos
<xsl:copy>para copiar nodos
<xsl:sort> para ordenar conjuntos de nodos
(select attribute especifica qué se debe ordenar)
Ejemplo: Ordenar los elementos "animal" por el numero de "legs" en (animals.xml)
XML Input file:
<?xml version="1.0"?>
<animals>
<animal name="dog" class="mammal" legs="4"/>
<animal name="shark" class="fish" legs="0"/>
<animal name="chicken" class="bird" legs="2"/>
</animals>XML Output file:
<?xml version="1.0"?>
<animals>
<animal name="shark" class="fish" legs="0"/>
<animal name="chicken" class="bird" legs="2"/>
<animal name="dog" class="mammal" legs="4"/>
</animals>XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="animals">
<animals>
<xsl:apply-templates>
<xsl:sort data-type="number" select="@legs"/>
</xsl:apply-templates>
</animals>
</xsl:template>
<xsl:template match="animal">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>11.7.11 Usando "xsl:variable" y "text output" type
Problema: Calcular el promedio de cada estudiante y el promedio del grupo
XML Input file (students.xml):
XSL Style Sheet :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="course">
<xsl:apply-templates select="student"/>
total average="<xsl:value-of select="(sum(//hw1) +
sum(//hw2) +
sum(//final) +
sum(//project))
div (4*count(//student))"/>"
</xsl:template>
<xsl:template match="student">
<xsl:variable name="ave">
<xsl:value-of select="(hw1 + hw2 + project + final) div 4"/>
</xsl:variable>
Student name="<xsl:value-of select="name"/>"
average="<xsl:value-of select="$ave"/>"
</xsl:template>
</xsl:stylesheet>Output file (grades.txt):
Student name="John Smith"
average="66.25"
Student name="George Lucas"
average="77.5"
Student name="Elizabeth Roberts"
average="73.75"
total average="72.5"11.7.12 Usando "xsl:if"
Problema: Desplegar el nombre de los estudiantes cuyos promedios sean mayores que 70
XML Input file (students.xml):
XSL Style Sheet:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="course">
<xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="student">
<xsl:variable name="ave">
<xsl:value-of select="(hw1 + hw2 + project + final) div 4"/>
</xsl:variable>
<xsl:if test="$ave > 70">
Student name="<xsl:value-of select="name"/>"
average="<xsl:value-of select="$ave"/>"
</xsl:if>
</xsl:template>
</xsl:stylesheet>Output file (grades70.txt):
Student name="George Lucas"
average="77.5"
Student name="Elizabeth Roberts"
average="73.75"11.7.13 Controlando el tipo de salida
XML es el tipo por default
<xsl:output method="xml"/>
HTML 4.0
<xsl:output method="html"/>
Text
<xsl:output method="text"/>
Inserta espacios en blanco y sangrías
<xsl:output indent="yes"/>
Produce el elemento DOCTYPE
<xsl:output doctype-system="students.dtd"/>
*produces: <!DOCTYPE course SYSTEM "students.dtd">
11.8 XML Databases
11.8.1 Antecedentes
- El analizar un documento XML no es trivial, aunque se puede hacer con SAX o DOM
- XPath y XSLT (Xalan) permiten hacer búsquedas en un documento de una manera sencilla a través de dicho lenguaje de consulta
- Cuando hablamos de realizae un búsqueda en una colección (conjunto de) documentos las cosas cambian, la complejidad aumenta y se deben buscar alternativas
11.8.2 Definición
Hablar de documentos XML es hablar de 2 categorías
- Centrados en los datos (data-centric): usados para el transporte de datos ya que probablemente estaremos hablando de datos estructurados organizados en XML
- Centrados en el documento (document-centric): tienen una estructura irregular y sobre todo, esa estructura es importante
Para cada caso la manera de realizar una consulta es diferente:
Para los documentos centrados en los datos, podemos pensar en datos estructurados que pueden extraerse del documento e indexarse con alguna base de datos convencionalPor otro lado para los datos centrados en el documento el reto no es tan trivial ya que se pretende hacer consultas pero no solo sobre el contenido, sino también sobre la estructura del documento.
De modo que una base de datos XML es aquella que define un modelo lógico de un documento XML y almacena y recupera documentos de acuerdo a ese modelo.
11.8.3 Tipos de Bases de Datos XMLXML Enabled Databases (Bases de datos habilitadas para XML): son aquellas que desglosan la información de un documento XML en su correspondiente esquema relacional o de objetos
Product Developer License DB Type Access 2002 Microsoft Commercial Relational Cache InterSystems Corp. Commercial Multi-valued DB2 IBM Commercial Relational eXtremeDB McObject Commercial Navigational FileMaker FileMaker Commercial FileMaker FoxPro Microsoft Commercial Relational Informix IBM Commercial Relational Matisse Matisse Software Commercial Object-oriented Objectivity/DB Objectivity Commercial Object-oriented OpenInsight Revelation Software Commercial Multi-valued Oracle 11., 9i Oracle Commercial Relational SQL Server 2000 Microsoft Commercial Relational Sybase ASE 12.5 Sybase Commercial Relational Versant enJin Versant Corp. Commercial Object-oriented
XML Native Databases (Bases de datos nativas de XML): son aquellas que respetan la estructura del documento, se pueden hacer consultas sobre dicha estructura y es posible recuperar el documento tal como fue insertado originalmente.
Product Developer License DB Type 4Suite, 4Suite Server FourThought Open Source Object-oriented Birdstep RDM XML Birdstep Commercial Object-oriented Centor Interaction Server Centor Software Corp. Commercial Proprietary Cerisent XQE Cerisent Commercial Proprietary(?) Coherity XML Database Coherity Commercial Proprietary DBDOM K. Ari Krupnikov Open Source Relational dbXML dbXML Group Commercial Proprietary DOM-Safe Ellipsis Commercial Proprietary eXist Wolfgang Meier Open Source Relational eXtc M/Gateway Developments Ltd. Commercial Multi-valued eXtensible Information Server (XIS) eXcelon Corp. Commercial Object-oriented (ObjectStore). Relational and other data through Data Junction GoXML DB XML Global Commercial Proprietary (Text-based) Infonyte DB Infonyte Commercial Proprietary (Model-based) Ipedo XML Database Ipedo Commercial Proprietary Lore Stanford University Research Semi-structured Lucid XML Data Manager Ludic'i.t. Commercial Proprietary MindSuite XDB Wired Minds Commercial Object-oriented Natix data ex machina Commercial File system(?) Neocore XML Management System NeoCore Commercial Proprietary ozone ozone-db.org Open Source Object-oriented Sekaiju / Yggdrasill Media Fusion Commercial Proprietary SQL/XML-IMDB QuiLogic Commercial Proprietary (native XML and relational) Tamino Software AG Commercial Proprietary. Relational through ODBC. TeraText DBS TeraText Solutions Commercial Proprietary TEXTML Server IXIA, Inc. Commercial Proprietary (Text-based) TigerLogic XDMS Raining Data Commercial Pick TOTAL XML Cincom Commercial Object-relational? Virtuoso OpenLink Software Commercial Proprietary. Relational through ODBC XDBM Matthew Parry, Paul Sokolovsky Open Source Proprietary (Model-based) XDB ZVON.org Open Source Relational (PostgreSQL only?) X-Hive/DB X-Hive Corporation Commercial Object-oriented (Objectivity/DB). Relational through JDBC Xindice Apache Software Foundation Open Source Proprietary (Model-based) Xyleme Zone Server Xyleme SA Commercial Proprietary
11.8.4 Programando con una XML DatabaseAfortunadamente el grupo XMLDB ha propuesto un API que todos los proveedores deben implementar
Al igual que con otras aplicaciones el API simplemente define un conjunto de interfaces que cada proveedor implementa:
org.xmldb.api
Interfaces
DatabaseManagerorg.xmldb.api.base
Interfaces
Collection
Configurable
Database
Resource
ResourceIterator
ResourceSet
Service
Classes
ErrorCodes
Exceptions
XMLDBExceptionorg.xmldb.api.modules
Interfaces
BinaryResource
CollectionManagementService
TransactionService
XMLResource
XPathQueryService
XUpdateQueryService
Es importante recordar:
Recuperación de un documento import org.xmldb.api.base.*; import org.xmldb.api.modules.*; import org.xmldb.api.*; public class RetrieveExample { public static void main(String args[]) throws Exception { String driver = "org.exist.xmldb.DatabaseImpl"; Class cl = Class.forName(driver); Database database = (Database)cl.newInstance(); DatabaseManager.registerDatabase(database); database.setProperty("create-database", "true"); Collection col = DatabaseManager.getCollection("xmldb:exist:///db/thesis"); col.setProperty("pretty", "true"); col.setProperty("encoding", "ISO-11.59-1"); XMLResource res = (XMLResource)col.getResource(args[0]); if(res == null) { System.err.println("could not retrieve document " + args[0] + "!"); return; } System.out.println((String)res.getContent()); } }Imports:
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;El driver puede ser:
- "org.exist.xmldb.DatabaseImpl"
- "org.apache.xindice.client.xmldb.DatabaseImpl"
El url puede ser
- xmldb:exist://localhost:11.11./db/thesis
- xmldb:xindice://localhost:4011./db/thesis
Ejecutando una consulta import org.xmldb.api.base.*; import org.xmldb.api.modules.*; import org.xmldb.api.*; public class QueryExample { public static void main(String args[]) throws Exception { String driver = "exist.xmldb.DatabaseImpl"; Class cl = Class.forName(driver); Database database = (Database)cl.newInstance(); database.setProperty("create-database", "true"); DatabaseManager.registerDatabase(database); Collection col = DatabaseManager.getCollection("xmldb:exist:///db/thesis"); XPathQueryService service = (XPathQueryService) col.getService("XPathQueryService", "1.0"); service.setProperty("pretty", "true"); service.setProperty("encoding", "ISO-11.59-1"); ResourceSet result = service.query(args[0]); ResourceIterator i = result.getIterator(); while(i.hasMoreResources()) { Resource r = i.nextResource(); System.out.println((String)r.getContent()); } } }*Los resultados estarán expresados en XML
Agregando un documento import org.xmldb.api.*; import org.xmldb.api.base.*; import org.xmldb.api.modules.*; import org.exist.util.XMLUtil; public class APIParse { public static void main(String args[]) throws Exception { String collection = args[0], file = args[1]; if(collection.startsWith("/db")) // remove /db if specified collection = collection.substring(3); // initialize driver String driver = "org.exist.xmldb.DatabaseImpl"; Class cl = Class.forName(driver); Database database = (Database)cl.newInstance(); database.setProperty("create-database", "true"); DatabaseManager.registerDatabase(database); // try to get collection Collection col = DatabaseManager.getCollection("xmldb:exist:///db" + collection); if(col == null) { // collection does not exist: get root collection and create it Collection root = DatabaseManager.getCollection("xmldb:exist:///db"); CollectionManagementService mgtService = (CollectionManagementService) root.getService("CollectionManagementService", "1.0"); col = mgtService.createCollection(collection); } // create new XMLResource; an id will be assigned to the new resource XMLResource document = (XMLResource)col.createResource(null, "XMLResource"); File f = new File(file); if(!f.canRead()) System.err.println("can't read file " + file); document.setContent(f); System.out.print("storing document " + document.getId() + "..."); col.storeResource(document); System.out.println("ok."); } }
11.8.5 Utilizando una XML DatabaseBásicamente la utilización radica en los siguientes pasos:
- Escoger una XMLDatabase (exist y xindice son los más recomendables)
- Instalarla, configurarla y si de preferencia crear usuarios y permisos
- Crear un DTD que deberán seguir todos los documentos de la colección
- Formular los posibles queries en XPath que deseamos obtener de la colección
- Crear las aplicaciones que ejecuten las distintas acciones en la XMLDB
- Diseñar las XSL que den formato a los resultados de las búsquedas
- Integrar todas las partes y lixto :)
11.9 Lo que no se vio de XML
Esta sección de XML tiene como punto centrar el aprovechar el lenguaje como medio de almacenamiento, pero XML está siendo utilizado para muchos otros fines
XSL-FO: XSL Formatting Objects, que permiten crear presentaciones para los documentos ej. PDF
XML-RPC: Remote Procedure Call en XML
<methodCall>
<methodName>sample.sumAndDifference</methodName>
<params>
<param><value><int>5</int></value></param></params>
<param><value><int>3</int></value></param>
</methodCall>
SOAP: un protocolo simple basado en XML que permite a aplicaciones intercambiar información a través de HTTP
SOAP request:
POST /InStock HTTP/1.1
Host: www.stock.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.stock.org/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>SOAP response:
HTTP/1.1 200 OK
Content-Type: application/soap; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.stock.org/stock">
<m:GetStockPriceResponse>
<m:Price>34.5</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>