/* Cataract - Static web photo gallery generator * Copyright (C) 2008 Tomas Bzatek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "xml-parser.h" #include "gallery-utils.h" /* * xml_parser_load: initialize and load the XML document */ TXMLFile * xml_parser_load (const char *filename) { TXMLFile *file; file = malloc (sizeof (TXMLFile)); memset (file, 0, sizeof (TXMLFile)); /* Load XML document */ file->doc = xmlParseFile (filename); if (file->doc == NULL) { log_error ("Error: unable to parse file \"%s\"\n", filename); free (file); return NULL; } /* Create xpath evaluation context */ file->xpathCtx = xmlXPathNewContext (file->doc); if (file->xpathCtx == NULL) { log_error ("Error: unable to create new XPath context\n"); xmlFreeDoc (file->doc); free (file); return FALSE; } return file; } /* * xml_parser_close: close the XML document parser */ void xml_parser_close (TXMLFile *file) { if (file) { xmlXPathFreeContext (file->xpathCtx); xmlFreeDoc (file->doc); free (file); file = NULL; } } /* * xml_file_get_node_name: retrieve name of the XPath node */ char * xml_file_get_node_name (TXMLFile *file, const char *x_path) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; char *attrv; if ((! file) || (! x_path)) return NULL; /* Evaluate xpath expression */ xpathObj = xmlXPathEvalExpression ((const xmlChar *) x_path, file->xpathCtx); if (xpathObj == NULL) { log_error ("Error: unable to evaluate xpath expression \"%s\"\n", x_path); return NULL; } attrv = NULL; if ((xpathObj->nodesetval) && (xpathObj->nodesetval->nodeNr > 0)) { cur = xpathObj->nodesetval->nodeTab[0]; if (cur->name) attrv = strdup ((const char *) cur->name); } xmlXPathFreeObject (xpathObj); return attrv; } /* * xml_file_get_node_value: retrieve string value from XPath node * - multiple matched nodes will be concatenated into one string * - otherwise please use [0], [1] etc. quantificators */ char * xml_file_get_node_value (TXMLFile *file, const char *x_path) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; char *val, *valx; int i; if ((! file) || (! x_path)) return NULL; /* Evaluate xpath expression */ xpathObj = xmlXPathEvalExpression ((const xmlChar *) x_path, file->xpathCtx); if (xpathObj == NULL) { log_error ("Error: unable to evaluate xpath expression \"%s\"\n", x_path); return NULL; } val = NULL; if ((xpathObj->nodesetval) && (xpathObj->nodesetval->nodeNr > 0)) { #ifdef __DEBUG_ALL__ printf("Result (%d nodes):\n", xpathObj->nodesetval->nodeNr); #endif for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) { cur = xpathObj->nodesetval->nodeTab[i]; #ifdef __DEBUG_ALL__ printf(" XPATH matched: element node \"%s[%d]\", value = '%s'\n", cur->name, i, cur->content); #endif if (cur->content) { if (val == NULL) { val = g_strdup ((char *) cur->content); } else { valx = g_strconcat (val, (char *) cur->content, NULL); g_free (val); val = valx; } } } } xmlXPathFreeObject (xpathObj); return val; } /* * xml_file_get_node_attribute: retrieve attribute value from XPath node */ char * xml_file_get_node_attribute (TXMLFile *file, const char *x_path, const char *attr) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; xmlChar *attrvx; char *attrv; if ((! file) || (! x_path)) return NULL; /* Evaluate xpath expression */ xpathObj = xmlXPathEvalExpression ((const xmlChar *) x_path, file->xpathCtx); if (xpathObj == NULL) { log_error ("Error: unable to evaluate xpath expression \"%s\"\n", x_path); return NULL; } attrv = NULL; if ((xpathObj->nodesetval) && (xpathObj->nodesetval->nodeNr > 0)) { cur = xpathObj->nodesetval->nodeTab[0]; attrvx = xmlGetProp (cur, (const xmlChar *) attr); if (attrvx) { attrv = strdup ((char*) attrvx); xmlFree (attrvx); } #ifdef __DEBUG_ALL__ printf("Result (%d nodes):\n", xpathObj->nodesetval->nodeNr); printf(" XPATH matched: element node \"%s\", value = '%s', property value = '%s'\n", cur->name, cur->content, attrv); #endif } xmlXPathFreeObject (xpathObj); return attrv; } long xml_file_get_node_attribute_long (TXMLFile *file, const char *x_path, const char *attr, const int _default) { char *s; long int i; s = xml_file_get_node_attribute (file, x_path, attr); if (s == NULL) return _default; i = atol (s); free (s); return i; } /* * xml_file_get_node_present: existency test of the XPath node */ gboolean xml_file_get_node_present (TXMLFile *file, const char *x_path) { return xml_file_node_get_children_count (file, x_path) > 0; } /* * xml_file_node_get_children_count: retrieve number of children items of the specified XPath node */ int xml_file_node_get_children_count (TXMLFile *file, const char *x_path) { xmlXPathObjectPtr xpathObj; int count; if ((! file) || (! x_path)) return 0; /* Evaluate xpath expression */ xpathObj = xmlXPathEvalExpression ((const xmlChar *) x_path, file->xpathCtx); if (xpathObj == NULL) { log_error ("Error: unable to evaluate xpath expression \"%s\"\n", x_path); return 0; } count = 0; if (xpathObj->nodesetval) count = xpathObj->nodesetval->nodeNr; xmlXPathFreeObject (xpathObj); return count; }