Parseando XML con Qt QXML es un módulo de la librería de Trolltech Qt (sí sí, la misma que el otro doc
:-) que sirve para analizar sintácticamente documentos en XML. El módulo XML está disponible
en la versión Enterprise y GPL de Qt. Debo decir que esto está totalmente orientado a Qt3, para Qt4
han cambiado la librería. Ya hay la documentación en internet, pero he pensado que es mejor tener
algo que podemos usar que algo que podremos usar. ¿Para qué XML? Bueno, esto está muy explicado en internet. Básicamente porque es simple y potente. Simple porque no requiere un estudio muy importante, por lo menos por lo que refiere a XML en sí, las tecnologías que lo rodean sí que dan para más aprendizaje :). Potente porque da muchas posibilidades. Para dar una idea de lo que representa, daré unos cuantos ejemplos:
Para comprobar la sintaxis de estos tenemos los ficheros DTD que, mediante un parser, nos comprueba si un archivo XML se ciñe a lo que marca el DTD, generalmente la especificación estándar. ¿Como funciona esto? Bueno, hasta aquí es todo bonito. Tenemos unos textos puestos expresamente para que nosotros los
leamos, parece fácil... Para explicaros como funciona, haremos un programa que nos gestione haremos una lista de la compra. Es demasiado freak ir al super con una lista XML, no lo probéis, es sólo un ejemplo, la gente normal no lo entenderían y se asustarían. El programa tendrá esta forma: <!DOCTYPE ListaDeLaCompraML> <lista> <producto cantidad="5" tipo="agua" /> <producto cantidad="1" tipo="leche" /> <producto cantidad="3" tipo="tomates" /> </lista> La lista tiene tags a un nivel sólo, podéis poner los que queráis, es para hacerlo lo más comprensible para vosotros. Los ejemplos los he hecho para consola. Habría podido usar interfaz gráfica, pero pensé que como menos líneas tuviera el programa más claro sería y no es necesária una interfaz gráfica. Usando DOM con Qt Qt nos ofrece muchas clases para DOM y es posible que nos perdamos entre tantas. De las hijas, tenemos principalmente:
Hay más, pero esas son las más utilizadas. Para entender un poco la nomenclatura, el esquema sería este: <documento> <elemento atributo="valor"> texto <!-- comentario --> </elemento> </documento> Escribiendo un documento XML con DOM Para crear el documento pasaremos por 3 pasos: 1. Crear un documento y un hijo para este. QDomDocument doc("ListaDeLaCompraML"); QDomElement root = doc.createElement("lista"); doc.appendChild(root); La primera linea crea un documento, ListaDeLaCompraML es el DOCTYPE. La segunda crea un elemento para el documento y la tercera lo añade al árbol de doc como hijo de éste. 2. Crear hijos para root, para dar contenido al fichero hijo = doc.createElement("producto"); hijo.setAttribute("tipo","leche"); hijo.setAttribute("cantidad","1"); root.appendChild(hijo); La primera línea crea un elemento para doc, como en la primera parte del programa. Las 2 siguientes atributos para el elemento hijo que acabamos de crear y después lo ponemos como hijo de root. Podéis observar que esta acción es la misma que la primera vez pero en vez de crear un nodo hijo del documento, lo es del nodo raiz. 3. Sacarlo todo por stdout. Podía escribirlo en un archivo también, o donde hubiese querido, el método .toString() nos devuelve un QString, así que tenemos toda libertad. :-) cout << doc.toString() << endl; Leiendo un documento XML con DOM Esto lo haremos en x pasos: 1. Cargar el archivo en el Documento QFile nuestralista(argv[1]); if (!nuestralista.open(IO_ReadOnly)) ... if (!doc.setContent(&nuestralista)) ... nuestralista.close(); En la primera línea pasamos argv[1] para que lo abra (es el primer parámetro), después lo abrimos, lo asignamos como contenido a doc y lo cerramos. En los puntos suspensivos tendríamos el código en caso que hubiése algun error. 2. Preparamos el Documento para leerlo. docElem = doc.documentElement(); if(docElem.tagName() != "lista"){ ... elem = docElem.firstChild(); Asignamos el documento a un elemento raiz, comprobamos que el tag del elemento raiz sea lista y ponemos el primer hijo de la raiz en elem, que es un elemento. 3. Mediante un bucle pasamos por todos los hijos de la raiz. Como es un documento a 2 niveles, no tendremos que descender más ni usar recursiones. while(!elem.isNull()) { e = elem.toElement(); cant = e.attribute("cantidad"); tipo = e.attribute("tipo"); cout << "\t- " << cant << " de " << tipo << endl; elem = elem.nextSibling(); } Mientras elem no sea un nulo, pasaremos de elem que es un QDomNode a e que es QDomElement y de este sacaremos los atributos cantidad y tipo y los pasaremos por stdout. Leiendo un documento XML con SAX Para parsear SAX, Qt nos ofrece QXmlReader y QXmlDefaultHandler. Además, tenemos una abstracción
de QXmlReader llamada QXmlSimpleReader que hace lo mismo que QXmlReader pero con menos opciones y de forma mas
simple :). Este ejemplo se compone de 2 partes principalmente. La clase y el main. La clase sería asi: class ClaseLista : public QXmlDefaultHandler { public: bool startDocument(){ cout << "Tienes k comprar: " << endl; return true; } bool startElement( const QString&, const QString&, const QString &name, const QXmlAttributes &attrs ) { if(name == "producto" ){ QString cant, tipo; for( int i=0; i<attrs.count(); i++ ) { if( attrs.localName( i ) == "cantidad" ) cant = attrs.value( i ); else if( attrs.localName( i ) == "tipo" ) tipo = attrs.value( i ); } cout << "\t- " << cant << " de " << tipo << endl; } return true; } }; En startDocument() ponemos lo que queremos que haga cuando empieza el documento y startElement() cuando
empieza un Elemento. El parámetro name nos dice el tagName. El bucle de dentro de la condición
navega por los atributos, creo que no tiene ninguna dificultad. int main(int argc, char *argv[]){ if(argc!=2) ... ClaseLista control; QFile nuestralista(argv[1]); QXmlInputSource documento(nuestralista); QXmlSimpleReader lector; lector.setContentHandler(&control); lector.parse(documento); return EXIT_SUCCESS; } Esto lo que hace es comprobar que haya los parámetros correctos, asignar el primer parámetro a nuestralista (como antes, en DOM). Declaramos y definimos un documento de entrada, un lector, pasamos la clase que hemos hecho para que nos avise y lo ponemos a parsear (analizar el documento). Archivo adjunto: qxml.tar.bz2 (se explica luego) Ya acabo Pues esto ha sido todo, creo que no es muy complicado. Si tenéis alguna duda ya sabéis, podéis contactar conmigo o postear en el foro. He adjuntado un ejemplo para cada uno de los apartados que he tratado más una aplicación gráfica que lo hace más o menos todo, por si tenéis curiosidad o algo :-P. Si habéis tenido algun problema con alguna explicación, los ejemplos también están explicados, quizá os ayude en algo esto. Un saludo a todos y hasta la próxima :-). Boooring (
boooring@gmail.com ) -
http://proli.net/
|