From: Pavel Charvat Date: Mon, 28 Apr 2008 11:04:28 +0000 (+0200) Subject: XML: Validate required attributes. Added an option to allocate X-Git-Tag: holmes-import~449^2~2 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=b30841cdf97c8e456a35987f984ce5b0f463ceab;p=libucw.git XML: Validate required attributes. Added an option to allocate missing attributes with default values. --- diff --git a/sherlock/xml/dtd.c b/sherlock/xml/dtd.c index 0abca72a..8c50a532 100644 --- a/sherlock/xml/dtd.c +++ b/sherlock/xml/dtd.c @@ -136,6 +136,14 @@ xml_dtd_find_pentity(struct xml_context *ctx, char *name) /* Elements */ +struct xml_dtd_elems_table; + +static void +xml_dtd_elems_init_data(struct xml_dtd_elems_table *tab UNUSED, struct xml_dtd_elem *e) +{ + slist_init(&e->attrs); +} + #define HASH_PREFIX(x) xml_dtd_elems_##x #define HASH_NODE struct xml_dtd_elem #define HASH_KEY_STRING name @@ -144,6 +152,7 @@ xml_dtd_find_pentity(struct xml_context *ctx, char *name) #define HASH_WANT_FIND #define HASH_WANT_LOOKUP #define HASH_GIVE_ALLOC +#define HASH_GIVE_INIT_DATA #define HASH_TABLE_ALLOC XML_HASH_GIVE_ALLOC #include "lib/hashtable.h" @@ -214,6 +223,7 @@ xml_dtd_attrs_init_key(struct xml_dtd_attrs_table *tab UNUSED, struct xml_dtd_at { attr->elem = elem; attr->name = name; + slist_add_tail(&elem->attrs, &attr->n); } #define HASH_PREFIX(x) xml_dtd_attrs_##x diff --git a/sherlock/xml/dtd.h b/sherlock/xml/dtd.h index c031d348..e2caf987 100644 --- a/sherlock/xml/dtd.h +++ b/sherlock/xml/dtd.h @@ -89,6 +89,7 @@ struct xml_dtd_elem { uns type; char *name; struct xml_dtd_elem_node *node; + slist attrs; void *user; /* User-defined */ }; @@ -140,6 +141,7 @@ enum xml_dtd_attr_type { }; struct xml_dtd_attr { + snode n; char *name; /* Attribute name */ struct xml_dtd_elem *elem; /* Owner element */ uns type; /* See enum xml_dtd_attr_type */ diff --git a/sherlock/xml/parse.c b/sherlock/xml/parse.c index d690ead5..6af02514 100644 --- a/sherlock/xml/parse.c +++ b/sherlock/xml/parse.c @@ -749,6 +749,19 @@ xml_push_element(struct xml_context *ctx) xml_unget_char(ctx); xml_parse_attr(ctx); } + if (e->dtd) + SLIST_FOR_EACH(struct xml_dtd_attr *, a, e->dtd->attrs) + if (a->default_mode == XML_ATTR_REQUIRED) + { + if (!xml_attrs_find(ctx->tab_attrs, e, a->name)) + xml_error(ctx, "Missing required attribute %s in element <%s>", a->name, e->name); + } + else if (a->default_mode != XML_ATTR_IMPLIED && ctx->flags & XML_ALLOC_DEFAULT_ATTRS) + { + struct xml_attr *attr = xml_attrs_lookup(ctx->tab_attrs, e, a->name); + if (!attr->val) + attr->val = a->default_value; + } if ((ctx->flags & XML_REPORT_TAGS) && ctx->h_stag) ctx->h_stag(ctx); } diff --git a/sherlock/xml/xml.h b/sherlock/xml/xml.h index 0dd405de..350fce9a 100644 --- a/sherlock/xml/xml.h +++ b/sherlock/xml/xml.h @@ -81,6 +81,7 @@ enum xml_flags { XML_VALIDATING = 0x00000100, /* Validate everything (not fully implemented!) */ XML_PARSE_DTD = 0x00000200, /* Enable parsing of DTD */ XML_NO_CHARS = 0x00000400, /* The current element must not contain character data (filled automaticaly if using DTD) */ + XML_ALLOC_DEFAULT_ATTRS = 0x00000800, /* Allocate default attribute values so they can be found by XML_ATTR_FOR_EACH */ /* Internals, do not change! */ XML_EMPTY_ELEM_TAG = 0x00010000, /* The current element match EmptyElemTag */