From: Jérôme Pinot <ngc891@gmail.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 22 Apr 2012 05:27:25 +0000 (05:27 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 22 Apr 2012 05:27:25 +0000 (05:27 +0000)
Subject: [E-devel] [patch] eina_simple_xml example

Here is an example for eina_simple_xml
This patch includes a small sample XML file, source code (for parsing and
printing it out) and the doxygen doc.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@70385 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/examples/Makefile.am
src/examples/chat.xml [new file with mode: 0644]
src/examples/eina_simple_xml_parser_01.c [new file with mode: 0644]
src/include/eina_simple_xml_parser.h

index c8d80f9..26af9fe 100644 (file)
@@ -41,6 +41,7 @@ SRCS = \
        eina_model_01.c \
        eina_model_02.c \
        eina_model_03.c \
+       eina_simple_xml_parser_01.c \
        eina_value_01.c \
        eina_value_02.c \
        eina_value_03.c \
@@ -85,6 +86,7 @@ examples_PROGRAMS += \
        eina_model_02 \
        eina_model_03 \
        eina_model_04 \
+       eina_simple_xml_parser_01 \
        eina_value_01 \
        eina_value_02 \
        eina_value_03 \
diff --git a/src/examples/chat.xml b/src/examples/chat.xml
new file mode 100644 (file)
index 0000000..140269c
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE board SYSTEM "tp-0.1.dtd">
+<board site="http://linuxfr.org/">
+  <post id="3211">
+    <login>houplaboom</login>
+    <message>Is this an XML test?</message>
+  </post>
+  <post id="3212">
+    <login>fredx</login>
+    <message>I'm seeing bald people.</message>
+  </post>
+  <post id="3213">
+    <login>NedFlanders</login>
+    <message>Don't call him!</message>
+  </post>
+  <post id="3214">
+    <login>Single</login>
+    <message>I'm not bald!</message>
+  </post>
+  <post id="3215">
+    <login>ngc891</login>
+    <message>It was an XML test.</message>
+  </post>
+</board>
diff --git a/src/examples/eina_simple_xml_parser_01.c b/src/examples/eina_simple_xml_parser_01.c
new file mode 100644 (file)
index 0000000..e85f2f0
--- /dev/null
@@ -0,0 +1,127 @@
+//Compile with:
+//gcc -Wall -o eina_simple_xml_01 eina_simple_xml_01.c `pkg-config --cflags --libs eina`
+
+#include <Eina.h>
+#include <stdio.h>
+#include <string.h>
+
+static Eina_Bool _xml_attr_cb(void *data, const char *key, const char *value);
+static Eina_Bool _xml_tag_cb(void *data, Eina_Simple_XML_Type type,
+               const char *content, unsigned offset, unsigned length);
+static Eina_Bool _print(const void *container, void *data, void *fdata);
+
+Eina_Bool tag_login   = EINA_FALSE;
+Eina_Bool tag_message = EINA_FALSE;
+
+int
+main(void)
+{
+   FILE *file;
+   long size;
+   char *buffer;
+   Eina_Array *array;
+
+   eina_init();
+
+   if ((file = fopen("chat.xml", "rb")))
+     {
+        fseek(file, 0, SEEK_END);
+        size = ftell(file);
+        fseek(file, 0, SEEK_SET);
+
+        if ((buffer = malloc(size)))
+          {
+             fread(buffer, 1, size, file);
+
+             array = eina_array_new(10);
+             eina_simple_xml_parse(buffer, size, EINA_TRUE,
+                                   _xml_tag_cb, array);
+
+             eina_array_foreach(array, _print, NULL);
+        
+             eina_array_free(array);
+             free(buffer);
+          }
+        else
+          {
+             EINA_LOG_ERR("Can't allocate memory!");
+          }
+        fclose(file);
+     }
+   else
+     {
+        EINA_LOG_ERR("Can't open chat.xml!");
+     }
+   eina_shutdown();
+
+   return 0;
+}
+
+static Eina_Bool
+_xml_tag_cb(void *data, Eina_Simple_XML_Type type, const char *content,
+            unsigned offset, unsigned length)
+{
+   char buffer[length+1];
+   Eina_Array *array = data;
+   char str[512];
+
+   if (type == EINA_SIMPLE_XML_OPEN)
+     {
+        if(!strncmp("post", content, strlen("post")))
+          {
+             const char *tags = eina_simple_xml_tag_attributes_find(content,
+                                                                    length);
+             eina_simple_xml_attributes_parse(tags, length - (tags - content),
+                                              _xml_attr_cb, str);
+          }
+        else if (!strncmp("login>", content, strlen("login>")))
+          {
+             tag_login = EINA_TRUE;
+          }
+        else if (!strncmp("message>", content, strlen("message>")))
+          {
+             tag_message = EINA_TRUE;
+          }
+     }
+   else if (type == EINA_SIMPLE_XML_DATA)
+     {
+        if (tag_login == EINA_TRUE)
+          {
+             snprintf(buffer, sizeof(buffer), content);
+             strncat(str, "<", 1);
+             strncat(str, buffer, sizeof(buffer));
+             strncat(str, "> ", 2);
+             tag_login = EINA_FALSE;
+          }
+        else if (tag_message == EINA_TRUE)
+          {
+             snprintf(buffer, sizeof(buffer), content);
+             strncat(str, buffer, sizeof(buffer));
+             tag_message = EINA_FALSE;
+             eina_array_push(array, strdup(str));
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_xml_attr_cb(void *data, const char *key, const char *value)
+{
+   char *str = data;
+
+   if(!strcmp("id", key))
+   {
+      snprintf(str, sizeof(value) + 3, "(%s) ", value);
+   }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_print(const void *container, void *data, void *fdata)
+{
+   printf("%s\n", (char *)data);
+
+   return EINA_TRUE;
+}
index d32f646..4f7d2f5 100644 (file)
 #include "eina_inlist.h"
 
 /**
+ * @page eina_simple_xml_parser_example_01_page
+ * @dontinclude eina_simple_xml_parser_01.c
+ *
+ * We are going to parse an XML sample file and print the data to stdout.
+ *
+ * Like all examples we start by including Eina:
+ * @skipline #include
+ *
+ * We declare 2 booleans to keep track of tags:
+ * @skipline tag_login
+ * @skipline tag_message
+ *
+ * Here we declare some variables and initialize eina:
+ * @until eina_init
+ *
+ * We fill buffer with the XML data from chat.xml:
+ * @until fread
+ *
+ * We will use an Eina_Array to store the data:
+ * @skipline array
+ *
+ * Here we call eina_simple_xml_parse(). We pass the buffer with data, its size,
+ * we ask to strip leading and trailing whitespace, we give the callback
+ * function and the array to store the formatted data:
+ * @until _xml_tag_cb
+ *
+ * This will loop over the array and print the data using _print callback:
+ * @skipline foreach
+ *
+ * This is the main XML parser callback, it will check for known tags and get
+ * the corresponding values:
+ * @skip static
+ * @until str
+ *
+ * We first check for opening tag:
+ * @skipline type
+ *
+ * If we know the tag should have attributes, then we find them using
+ * eina_simple_xml_tag_attributes_find() and give them to another parsing
+ * function using eina_simple_xml_attributes_parse():
+ * @until _xml_attr_cb
+ *
+ * We check for other known tags:
+ * @until tag_message
+ *
+ * We then check data for corresponding tag:
+ * @until EINA_FALSE
+ *
+ * We are doing the formatting in same time and put all the <post> children
+ * in str.
+ * @until EINA_FALSE
+ *
+ * Finally, we store our string in the array:
+ * @skipline push
+ *
+ * This is the callback to parse the attributes, we check for key name and keep
+ * the value:
+ * @skip static
+ * @until snprintf
+ *
+ * This is the function that simply print items of the array:
+ * @until EINA_TRUE
+ *
+ * You can see the full source code
+ * @ref eina_simple_xml_parser_example_01 "here".
+ */
+
+/**
+ * @page eina_simple_xml_parser_example_01
+ * @include eina_simple_xml_parser_01.c
+ * @example eina_simple_xml_parser_01.c
+ */
+
+/**
  * @defgroup Eina_Simple_XML_Group Simple_XML
  *
  * Simplistic relaxed SAX-like XML parser.
  * will not tokenize this. If you want you can use
  * eina_simple_xml_tag_attributes_find() and then
  * eina_simple_xml_attributes_parse().
+ *
+ * For more information, see
+ * @ref eina_simple_xml_parser_example_01_page "this example".
  */
 
 /**