From 01bd6113aa1a6d58a8d7d003b9ffdc49720951f3 Mon Sep 17 00:00:00 2001 From: ryo Date: Mon, 9 Mar 2026 18:48:24 +0000 Subject: Initial commit --- Makefile | 2 + main.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test.xml | 24 +++++++++++ 3 files changed, 166 insertions(+) create mode 100644 Makefile create mode 100644 main.c create mode 100644 test.xml diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..24314bf --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +demo: main.c + tcc -o $@ -I/usr/include/libxml2 -lxml2 $< diff --git a/main.c b/main.c new file mode 100644 index 0000000..bd5651c --- /dev/null +++ b/main.c @@ -0,0 +1,140 @@ +/* + * XML to SQL converter + * Author: ryo@repack.top + * Website: https://repack.top/~ryo + * Version: alpha + */ + +#include +#include +#include +#include +#include + +#define astrtr(s) s[strlen(s)-1] = '\0' +#define astrcmp(s1, s2) xmlStrcmp(s1, (xmlChar *)s2) == 0 +#define asprintf(dst, ...) sprintf(dst+strlen(dst), __VA_ARGS__) + +void query_create(xmlNode *root, char query[]); +void query_insert(xmlNode *root, char query[]); + +int main(int argc, char *argv[]) +{ + xmlDocPtr doc; + xmlNodePtr root; + char *query = malloc(2048 * sizeof(char)); + + if (argc < 2) { + fprintf(stderr, "no file specified\n"); + return 1; + } + + doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS); + if (doc == NULL) { + fprintf(stderr, "can not parse the document\n"); + return 1; + } + + root = xmlDocGetRootElement(doc); + + query_create(root, query); + query_insert(root, query); + puts(query); + + xmlFreeDoc(doc); + free(query); + return 0; +} + +void query_create(xmlNode *root, char *query) +{ + xmlNode *cur, *parent; + int uuid = 0, end, nested = 0; + + cur = root; + while (cur) { + asprintf(query, "CREATE TABLE %s(", cur->name); + cur = cur->children; + if (cur->children->type == XML_ELEMENT_NODE) { + parent = cur->parent; + nested = 1; + cur = cur->children; + } + + while (cur->children->type == XML_TEXT_NODE) { + if (astrcmp(cur->name, "uuid")) + uuid = 1; + + asprintf(query, "%s,", cur->name); + + cur = cur->next; + if (cur == NULL) break; + } + if (nested) { + cur = parent->next; + nested = 0; + } + + if (!uuid) { + asprintf(query, "%s_uuid,", root->name); + } + + astrtr(query); + strcat(query, ");\n"); + } +} + +void query_insert(xmlNode *root, char *query) +{ + xmlNode *cur, *parent; + int uuid = 0, end, nested = 0; + + cur = root; + while (cur) { + asprintf(query, "INSERT INTO %s VALUES(", cur->name); + cur = cur->children; + if (cur->children->type == XML_ELEMENT_NODE) { + parent = cur->parent; + nested = 1; + cur = cur->children; + } + + while (cur->children->type == XML_TEXT_NODE) { + if (astrcmp(cur->name, "uuid")) + uuid = 1; + + asprintf(query, "'%s',", xmlNodeGetContent(cur)); + + if (cur->next == NULL) { + if (nested) { + if (cur->parent == parent->last) { + break; + } + else { + astrtr(query); + strcat(query, "),\n("); + cur = cur->parent->next->children; + } + } else { + cur = cur->next; + break; + } + } else + cur = cur->next; + } + + if (nested) { + cur = parent->next; + nested = 0; + } + + if (!uuid) { + asprintf(query, "'%s',", xmlNodeGetContent(root->children)); + } + + astrtr(query); + strcat(query, ");\n"); + } + astrtr(query); +} + diff --git a/test.xml b/test.xml new file mode 100644 index 0000000..4a06a53 --- /dev/null +++ b/test.xml @@ -0,0 +1,24 @@ + + + 550e8400-e29b-41d4-a716-446655440000 + Main Library + + + 1 + The Great Gatsby + F. Scott Fitzgerald + 1925 + + + 2 + To Kill a Mockingbird + Harper Lee + 1960 + + +
+ 123 Library Lane + Booktown + 90210 +
+
-- cgit v1.2.3