1) avergonzaros
2) ir a leerlo. ¡Inmediatamente!
Ahora, si estáis leyendo esto, puede ser que ya habéis pasado los dos puntos anteriores, entonces podemos continuar. Vamos a utilizar también esta vez la libXML2 para escribir una función que consigue extraer todas las parejas key-value que componen un documento XML.
Siempre más fácil... |
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <libxml/parser.h> // prototipos locales void deserialize(const char* document); void recurDoc(xmlDocPtr doc, xmlNodePtr cur); // main del programa de test int main(int argc, char **argv) { // test argumentos if (argc <= 1) { printf("Usage: %s docname\n", argv[0]); return(0); } /* libxml2: inicializa la librería y testea potenciales ABI mismatches entre la versión compilada y la actual shared library usada */ LIBXML_TEST_VERSION; // deserializa XML deserialize(argv[1]); // sale con Ok return EXIT_SUCCESS; } // función deserialize() void deserialize( const char* document) { // elimina los blank nodes xmlKeepBlanksDefault(0); // extrae el documento del file xmlDocPtr doc; if ((doc = xmlParseFile(document)) == NULL ) { fprintf(stderr,"Document not parsed successfully. \n"); return; } // test si el documento non está vacio xmlNodePtr cur; if ((cur = xmlDocGetRootElement(doc)) == NULL) { fprintf(stderr,"empty document\n"); xmlFreeDoc(doc); return; } // recurre y libera el documento recurDoc(doc, cur); xmlFreeDoc(doc); } // función recursiva de lectura del documento void recurDoc( xmlDocPtr doc, xmlNodePtr cur) { // loop de lectura xmlChar *value; cur = cur->xmlChildrenNode; while (cur != NULL) { // extrae y libera un elemento if ((value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) != NULL) { printf("key: %-10s - value: %s\n", cur->name, value); xmlFree(value); } // llamada recursiva recurDoc(doc, cur); // pasa al próximo elemento cur = cur->next; } // sale return; }Y, como siempre:
1) codigo que se auto-explica, ampliamente comentado y... los comentarios hablan por sí mismos.
2) la función main() no hace más que arrancar la función deserialize(): concéntrese en esa.
La función, en realidad, está dividida en dos partes: deserialize() prepara la lectura del documento y recurDoc() (que es una función recursiva que se llama a si misma) recurre el documento n-veces hasta que haya campos para leer.
Este ejemplo es apto para leer cualquier archivo XML que se le pasa como argumento, y se puede especializar fácilmente, por ejemplo si les pasais un file de estructura conocida (por ejemplo, se puede intentar con el catálogo XML de películas producidas por nuestro anterior Serializer) podeis rellenar los campos con lo campos key-value de la estructura de datos correspondiente (en nuestro caso la struct Catalog). En pocas palabras, con un poco de imaginación, la pareja Serializer/Deserializer que os he propuesto, permite una gran cantidad de actividades interesantes en programas que utilizan datos XML. Buen trabajo...
Os recuerdo una vez más que, para probar el programa en Linux (lo cual hice, por supuesto...) se debe instalar antes la libXML2 (desde el repository de la distribución), y luego compilar el programa con:
gcc desxml.c -I/usr/include/libxml2 -o desxml -lxml2¡Hasta el próximo post!
No hay comentarios:
Publicar un comentario