summaryrefslogtreecommitdiff
path: root/xml-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'xml-parser.c')
-rw-r--r--xml-parser.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/xml-parser.c b/xml-parser.c
new file mode 100644
index 0000000..88373dd
--- /dev/null
+++ b/xml-parser.c
@@ -0,0 +1,211 @@
+/* Cataract - Static web photo gallery generator
+ * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <glib.h>
+
+#include "xml-parser.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) {
+ fprintf (stderr, "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) {
+ fprintf (stderr, "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_value: retrieve value from XPath node
+ */
+char *
+xml_file_get_node_value (TXMLFile *file, const char *x_path)
+{
+ xmlXPathObjectPtr xpathObj;
+ xmlNodePtr cur;
+ char *val;
+
+ if ((! file) || (! x_path))
+ return NULL;
+
+ /* Evaluate xpath expression */
+ xpathObj = xmlXPathEvalExpression ((const xmlChar *) x_path, file->xpathCtx);
+ if (xpathObj == NULL) {
+ fprintf (stderr, "Error: unable to evaluate xpath expression \"%s\"\n", x_path);
+ return NULL;
+ }
+
+ val = NULL;
+ if ((xpathObj->nodesetval) && (xpathObj->nodesetval->nodeNr > 0)) {
+ cur = xpathObj->nodesetval->nodeTab[0];
+
+ #ifdef __DEBUG_ALL__
+ printf("Result (%d nodes):\n", xpathObj->nodesetval->nodeNr);
+ printf(" XPATH matched: element node \"%s\", value = '%s'\n", cur->name, cur->content);
+ #endif
+
+ if (cur->content)
+ val = strdup ((char *) cur->content);
+ }
+
+ 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) {
+ fprintf (stderr, "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) {
+ fprintf (stderr, "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;
+}