mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 18:25:10 +00:00
204 lines
3.7 KiB
C
204 lines
3.7 KiB
C
#include <XML.h>
|
|
|
|
#include <Cytoplasm/Memory.h>
|
|
#include <Cytoplasm/Str.h>
|
|
#include <Cytoplasm/Log.h>
|
|
|
|
#include <string.h>
|
|
|
|
XMLElement *
|
|
XMLCreateTag(char *name)
|
|
{
|
|
XMLElement *elem;
|
|
if (!name)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
elem = Malloc(sizeof(*elem));
|
|
|
|
elem->type = XML_ELEMENT_TAG;
|
|
elem->name = StrDuplicate(name);
|
|
elem->attrs = HashMapCreate();
|
|
elem->children = ArrayCreate();
|
|
|
|
elem->data = NULL;
|
|
|
|
return elem;
|
|
}
|
|
XMLElement *
|
|
XMLCreateText(char *data)
|
|
{
|
|
XMLElement *elem;
|
|
if (!data)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
elem = Malloc(sizeof(*elem));
|
|
|
|
elem->type = XML_ELEMENT_DATA;
|
|
elem->name = NULL;
|
|
elem->attrs = NULL;
|
|
elem->children = NULL;
|
|
|
|
elem->data = StrDuplicate(data);
|
|
|
|
return elem;
|
|
|
|
}
|
|
|
|
|
|
void
|
|
XMLAddAttr(XMLElement *element, char *key, char *val)
|
|
{
|
|
if (!element || !key || !val)
|
|
{
|
|
return;
|
|
}
|
|
if (element->type != XML_ELEMENT_TAG || !element->attrs)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Free(HashMapSet(element->attrs, key, StrDuplicate(val)));
|
|
}
|
|
void
|
|
XMLAddChild(XMLElement *element, XMLElement *child)
|
|
{
|
|
if (!element || !child)
|
|
{
|
|
return;
|
|
}
|
|
if (element->type != XML_ELEMENT_TAG)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ArrayAdd(element->children, child);
|
|
}
|
|
|
|
void
|
|
XMLFreeElement(XMLElement *element)
|
|
{
|
|
if (!element)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (element->name)
|
|
{
|
|
Free(element->name);
|
|
}
|
|
if (element->data)
|
|
{
|
|
Free(element->data);
|
|
}
|
|
if (element->attrs)
|
|
{
|
|
char *key, *val;
|
|
while (HashMapIterate(element->attrs, &key, (void **) &val))
|
|
{
|
|
Free(val);
|
|
}
|
|
HashMapFree(element->attrs);
|
|
}
|
|
if (element->children)
|
|
{
|
|
size_t i;
|
|
for (i = 0; i < ArraySize(element->children); i++)
|
|
{
|
|
XMLFreeElement(ArrayGet(element->children, i));
|
|
}
|
|
ArrayFree(element->children);
|
|
}
|
|
|
|
Free(element);
|
|
}
|
|
XMLElement *
|
|
XMLookForUnique(XMLElement *parent, char *tag)
|
|
{
|
|
size_t i;
|
|
|
|
if (!parent || !tag)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; i < ArraySize(parent->children); i++)
|
|
{
|
|
XMLElement *child = ArrayGet(parent->children, i);
|
|
if (StrEquals(child->name, tag))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
XMLElement *
|
|
XMLookForTKV(XMLElement *parent, char *tag, char *k, char *v)
|
|
{
|
|
size_t i;
|
|
|
|
if (!parent || !k || !v)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; i < ArraySize(parent->children); i++)
|
|
{
|
|
XMLElement *child = ArrayGet(parent->children, i);
|
|
HashMap *attrs = child->attrs;
|
|
char *value = HashMapGet(attrs, k);
|
|
if (StrEquals(child->name, tag) || !tag)
|
|
{
|
|
if (StrEquals(value, v))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
XMLElement *
|
|
XMLCopy(XMLElement *original)
|
|
{
|
|
XMLElement *ret = NULL;
|
|
if (!original)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
ret = Malloc(sizeof(*ret));
|
|
ret->type = original->type;
|
|
|
|
ret->name = StrDuplicate(original->name);
|
|
ret->data = StrDuplicate(original->data);
|
|
|
|
{
|
|
size_t i;
|
|
ret->children = ArrayCreate();
|
|
|
|
for (i = 0; i < ArraySize(original->children); i++)
|
|
{
|
|
XMLElement *child = ArrayGet(original->children, i);
|
|
ArrayAdd(
|
|
ret->children,
|
|
XMLCopy(child)
|
|
);
|
|
}
|
|
}
|
|
if (original->attrs)
|
|
{
|
|
char *name, *value;
|
|
ret->attrs = HashMapCreate();
|
|
while (HashMapIterate(original->attrs, &name, (void **) &value))
|
|
{
|
|
HashMapSet(ret->attrs, name, StrDuplicate(value));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|