/* 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 gchar *filename) { TXMLFile *file; file = g_malloc0 (sizeof (TXMLFile)); /* Load XML document */ file->doc = xmlParseFile (filename); if (! file->doc) { log_error ("Error: unable to parse file \"%s\"\n", filename); xml_parser_free (file); return NULL; } /* Create xpath evaluation context */ file->xpathCtx = xmlXPathNewContext (file->doc); if (! file->xpathCtx) { log_error ("Error: unable to create new XPath context\n"); xml_parser_free (file); return FALSE; } return file; } /* * xml_parser_free: close the XML document parser and frees all memory */ void xml_parser_free (TXMLFile *file) { if (file) { if (file->xpathCtx) xmlXPathFreeContext (file->xpathCtx); if (file->doc) xmlFreeDoc (file->doc); g_free (file); } } /* * xml_file_get_node_name: retrieve name of the XPath node */ gchar * xml_file_get_node_name (TXMLFile *file, const gchar *x_path) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; gchar *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 = g_strdup ((const gchar *) 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 */ gchar * xml_file_get_node_value (TXMLFile *file, const gchar *x_path) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; gchar *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) for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) { cur = xpathObj->nodesetval->nodeTab[i]; if (cur->content) { if (val == NULL) { val = g_strdup ((gchar *) cur->content); } else { valx = g_strconcat (val, (gchar *) cur->content, NULL); g_free (val); val = valx; } } } xmlXPathFreeObject (xpathObj); return val; } gchar * xml_file_get_node_value_with_default (TXMLFile *file, const gchar *x_path, const gchar *_default) { gchar *s; s = xml_file_get_node_value (file, x_path); return s ? s : g_strdup (_default); } /* * xml_file_get_node_attribute: retrieve attribute value from XPath node */ gchar * xml_file_get_node_attribute (TXMLFile *file, const gchar *x_path, const gchar *attr) { xmlXPathObjectPtr xpathObj; xmlNodePtr cur; xmlChar *attrvx; gchar *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 = g_strdup ((gchar*) attrvx); xmlFree (attrvx); } } xmlXPathFreeObject (xpathObj); return attrv; } long int xml_file_get_node_attribute_long (TXMLFile *file, const gchar *x_path, const gchar *attr, const int _default) { gchar *s; long int i; s = xml_file_get_node_attribute (file, x_path, attr); if (s == NULL) return _default; i = atol (s); g_free (s); return i; } gboolean xml_file_get_node_attribute_boolean (TXMLFile *file, const gchar *x_path, const gchar *attr, const gboolean _default) { gchar *s; gboolean b; s = xml_file_get_node_attribute (file, x_path, attr); b = s ? (strcasecmp (s, "yes") == 0 || strcasecmp (s, "true") == 0) : _default; g_free (s); return b; } /* * xml_file_get_node_present: existency test of the XPath node */ gboolean xml_file_get_node_present (TXMLFile *file, const gchar *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 gchar *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; }