Hola en esta cuarta parte del curso hablaremos sobre los DTD teniendo su origen en SGML es una de las formas de definir la estructura de un documento XML para que cuando un programa lo lea se pueda saber la estructura (actualmente se usan más otras formas de hecho en python veremos que al menos lo que hice no requiere un DTD)
Esto es un ejemplo de DTD:
<!ELEMENT billetes(billete*)>
<!ELEMENT billete(nombre,horario,tren)>
<!ATTLIST billete id #ID #REQUIRED>
<!ELEMENT nombre (#PCDATA)>
<!ELEMENT horario (#PCDATA)>
<!ELEMENT tren (vagon,fila,asiento)
<!ELEMENT vagon (#PCDATA)>
<!ELEMENT fila (#PCDATA)>
<!ELEMENT asiento (#PCDATA)>
Como podeis ver el DTD tiene primero la sentencia <!ELEMENT nombre_del_elemento (#PCDATA o otro elemento)
esto nos permite definir un elemento lo que hay entre parentesis es el tipo de dato del elemento o el nombre de otro elemento en el caso de que se desee otro elemento ahi, usando ATTLIST nombreElemento nombreAtributo
definimos los atributos posteriormente le añadimos el tipo de dato CDATA
o usar un enum para añadir una serie de valores de datos concretos por ejemplo <!ATTLIST semaforo estado (verde|amarillo|rojo) ""
además podemos poner entre comillas un valor por defecto
Tipos de datos para los atributos:
- CDATA: Es el tipo texto podemos introducir cualquier tipo de texot
- ID: No puede empezar por numeros llevar espacios es un identificador y debe ser unico ya que es un ID
- NMTOKEN: Los NMTOKEN no pueden tener espacios y solo pueden llevar coma, dos puntos, guiones,guiones bajos,letras, numeros y practicamente nada más
- NMTOKENS son como una lista de NMTOKEN divididos por espacios
Los tipos de datos de los Elementos son principalmente:
- EMPTY: Es decir que el elemento esta vacio aunque todavia puede contener atributos ya que esto se refiere al contenido de los elementos
- ANY: Se puede introducir cualquier tipo de dato
- PCDATA: Es decir texto
Ademas de todo eso se pueden usar simbolos para definir la cantidad de un elemento que debe haber si no hay signos solo puede haber un ejemplar de ese elemento pero si hay alguno de los siguientes signos
Programa en Python
Ahora aqui no voy a incluir lo del DTD para no hacerlo tan lioso pero voy a hacer un pequeño programa de gestion de libros el cual tendra informacion basica y permitira buscar por titulo o autor.
Para eso vamos a usar este XML de ejemplo, sobre el cual haremos algo de juego ya que añadiremos nuestros propios libros
<libros>
<libro>
<titulo>Las aventuras del intento de Dios</titulo>
<autor>Amld</autor>
<paginasLeidas>45</paginasLeidas>
<paginasTotales>450</paginasTotales>
<estado>Leyendo</estado>
</libro>
<libro>
<titulo>Las aventuras del intento de Demonio</titulo>
<autor>Amld</autor>
<paginasLeidas>0</paginasLeidas>
<paginasTotales>450</paginasTotales>
<estado>Por leer</estado>
</libro>
</libros>
Busqueda de libro
Ahora pasaremos a buscar el libro Las aventuras del intento de Dios usando python en nuestro xml usando el siguiente codigo
import xml.etree.ElementTree as ET
tree = ET.parse("prueba.xml")
root = tree.getroot()
libro1 = root.find("libro[titulo='Las aventuras del intento de Dios']")
if libro1 is not None:
print("Titulo: " + libro1.find('titulo').text)
print("Autor: " + libro1.find('autor').text)
print("Paginas leidas: " + libro1.find('paginasLeidas').text)
print("Paginas Totales: " + libro1.find('paginasTotales').text)
Las tres primeras partes son importar la libreria que vamos a usar y darle un nombre que la haga más facil de llamar, la segunda es parsear el archivo y convertirlo al tipo de objeto que esta libreria usa para trabajar, luego como todo XML tiene un elemento raiz usamos el metodo getroot
para obtenerla y a partir de ahi podemos buscar el objeto que nos devuelve root contiene los nodos del XML en forma de objeto por lo que usando el metodo find
podemos decirle de la manera en la que lo indico que desde el elemento raiz busque un elemento libro que tenga como titulo el del primer libro, este metodo solo devuelve la primera coincidencia si usas metodos como findall puedes obtener todas las coincidencias de una busqueda y recorrerlas y hacer cosas pero ahora vamos a quedarnos en lo simple con esto una vez hemos obtenido el libro que queremos lo ponemos con una variable para accederlo con un nombre, y luego despues de aplicar una comprobacion para ver que existe podemos usar el mismo metodo find para buscar dentro de las etiquetas del XML ya que pues las subetiquetas tambien son etiquetas XML y las representa en este caso como nodos dentro del libro1 y por tanto tambien son objetos de este tipo entonces lo que necesito es encontrar dentro del objeto los nodos de nombre, autor y demás que sean de lo que necesito, los cuales se encuentran en la propiedad text
y así obtengo la informacion, esto es muy basico, y probablemente haya maneras de ir haciendo pero así ya se pueden empezar a hacer aplicaciones simples con esto