From 306801fc6da02fcbed53db6ff98cd0277b763d9a Mon Sep 17 00:00:00 2001 From: Pavel Charvat Date: Thu, 24 Apr 2008 10:41:03 +0200 Subject: [PATCH] XML: A primitive DTD validation of elements... it is slow and does not check valid numbers/order of subtags. --- sherlock/xml/parse.c | 26 +++++++++++++++++++++++--- sherlock/xml/xml.h | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sherlock/xml/parse.c b/sherlock/xml/parse.c index 2003d091..6f5b192f 100644 --- a/sherlock/xml/parse.c +++ b/sherlock/xml/parse.c @@ -680,6 +680,18 @@ xml_attrs_table_cleanup(struct xml_context *ctx) /*** Elements ***/ +static uns +xml_validate_element(struct xml_dtd_elem_node *root, struct xml_dtd_elem *elem) +{ + if (root->elem) + return elem == root->elem; + else + SLIST_FOR_EACH(struct xml_dtd_elem_node *, son, root->sons) + if (xml_validate_element(son, elem)) + return 1; + return 0; +} + static void xml_push_element(struct xml_context *ctx) { @@ -705,12 +717,20 @@ xml_push_element(struct xml_context *ctx) xml_error(ctx, "Undefined element <%s>", e->name); else { - if (e->dtd->type == XML_DTD_ELEM_MIXED) + struct xml_dtd_elem *dtd = e->dtd, *parent_dtd = e->parent ? e->parent->dtd : NULL; + if (dtd->type == XML_DTD_ELEM_MIXED) ctx->flags &= ~XML_NO_CHARS; else ctx->flags |= XML_NO_CHARS; - - // FIXME: validate regular expressions + if (parent_dtd) + if (parent_dtd->type == XML_DTD_ELEM_EMPTY) + xml_error(ctx, "Empty element must not contain children"); + else if (parent_dtd->type != XML_DTD_ELEM_ANY) + { + // FIXME: validate regular expressions + if (!xml_validate_element(parent_dtd->node, dtd)) + xml_error(ctx, "Unexpected element <%s>", e->name); + } } while (1) { diff --git a/sherlock/xml/xml.h b/sherlock/xml/xml.h index 99651389..c920aa3b 100644 --- a/sherlock/xml/xml.h +++ b/sherlock/xml/xml.h @@ -244,7 +244,7 @@ uns xml_row(struct xml_context *ctx); /* Finds a given attribute value in a XML_NODE_ELEM node */ struct xml_attr *xml_attr_find(struct xml_context *ctx, struct xml_node *node, char *name); -/* Similar to xml_attr_find, but it deals also the default values */ +/* Similar to xml_attr_find, but it deals also with default values */ char *xml_attr_value(struct xml_context *ctx, struct xml_node *node, char *name); /* The default value of h_find_entity(), knows <, >, &, ' and " */ -- 2.39.2