1 /* $Id: zeerex.c,v 1.4 2007-03-15 16:50:56 quinn Exp $ */
3 // Reads Zeerex records into a set of structures
7 #include <yaz/yaz-util.h>
9 #include <libxml/parser.h>
10 #include <libxml/tree.h>
14 // Replace this with something that will take a callback
15 static void fail(const char *s, xmlNode *n)
17 yaz_log(YLOG_WARN, "Zeerex Err '%s'; elem '%s/%s'", s, n->parent->name, n->name);
20 // returns an nmem-allocated string if attr is present, or null
21 static char *attrtostr(NMEM m, xmlNode *n, const char *name)
23 char *s = xmlGetProp(n, name);
26 char *r = nmem_strdup(m, s);
34 static int attrtoint(xmlNode *n, const char *name)
36 char *s = xmlGetProp(n, name);
47 static Zr_bool attrtobool(xmlNode *node, const char *name)
49 char *v = xmlGetProp(node, name);
53 if (!strcmp(v, "true"))
55 else if (!strcmp(v, "false"))
58 res = Zr_bool_unknown;
63 return Zr_bool_unknown;
66 static char *valuetostr(NMEM m, xmlNode *n)
68 char *val = xmlNodeGetContent(n);
71 char *res = nmem_strdup(m, val);
79 static int valuetoint(xmlNode *n)
81 char *s = xmlNodeGetContent(n);
92 static Zr_langstr *findlangstr(NMEM m, xmlNode *node, const char *name)
96 for (n = node->children; n; n = n->next)
98 if (n->type == XML_ELEMENT_NODE && !strcmp(n->name, name))
100 Zr_langstr *new = nmem_malloc(m, sizeof(*new));
101 memset(new, 0, sizeof(*new));
102 new->primary = attrtobool(n, "primary");
103 new->lang = attrtostr(m, n, "lang");
104 new->str = valuetostr(m, n);
112 const char *zr_langstr(Zr_langstr *s, const char *lang)
115 for (p = s; p; p = p->next)
116 if ((!lang && p->primary == Zr_bool_true) ||
117 (lang && p->lang && !strcmp(lang, p->lang)))
122 static struct zr_authentication *authentication(NMEM m, xmlNode *node)
125 struct zr_authentication *r = nmem_malloc(m, sizeof(*r));
126 memset(r, 0, sizeof(*r));
127 r->type = attrtostr(m, node, "type");
128 for (n = node->children; n; n = n->next)
130 if (n->type != XML_ELEMENT_NODE)
132 if (!strcmp(n->name, "open"))
133 r->open = valuetostr(m, n);
134 else if (!strcmp(n->name, "user"))
135 r->user = valuetostr(m, n);
136 else if (!strcmp(n->name, "group"))
137 r->group = valuetostr(m, n);
138 else if (!strcmp(n->name, "password"))
139 r->password = valuetostr(m, n);
142 fail("Unexpected element", n);
150 static struct zr_serverInfo *serverInfo(NMEM m, xmlNode *node)
153 struct zr_serverInfo *r = nmem_malloc(m, sizeof(*r));
154 memset(r, 0, sizeof(*r));
156 r->protocol = attrtostr(m, node, "protocol");
157 r->version = attrtostr(m, node, "version");
158 r->transport = attrtostr(m, node, "transport");
159 r->method = attrtostr(m, node, "method");
160 for (n = node->children; n; n = n->next)
162 if (n->type != XML_ELEMENT_NODE)
164 if (!strcmp(n->name, "host"))
165 r->host = valuetostr(m, n);
166 else if (!strcmp(n->name, "port"))
167 r->port = valuetoint(n);
168 else if (!strcmp(n->name, "database"))
169 r->database = valuetostr(m, n);
170 else if (!strcmp(n->name, "authentication"))
172 if (!(r->authentication = authentication(m, n)))
177 fail("Unexpected element", n);
184 static struct zr_agent *agent(NMEM m, xmlNode *node)
186 struct zr_agent *r = nmem_malloc(m, sizeof(*r));
187 memset(r, 0, sizeof(*r));
188 r->type = attrtostr(m, node, "type");
189 r->identifier = attrtostr(m, node, "identifier");
190 r->value = valuetostr(m, node);
194 static struct zr_implementation *implementation(NMEM m, xmlNode *node)
197 struct zr_implementation *r = nmem_malloc(m, sizeof(*r));
198 memset(r, 0, sizeof(*r));
199 r->identifier = attrtostr(m, node, "identifier");
200 r->version = attrtostr(m, node, "version");
201 r->title = findlangstr(m, node, "title");
202 for (n = node->children; n; n = n->next)
204 if (n->type != XML_ELEMENT_NODE)
206 if (!strcmp(n->name, "agent"))
208 struct zr_agent *ag = agent(m, node);
211 ag->next = r->agents;
218 struct zr_databaseInfo *databaseInfo(NMEM m, xmlNode *node)
221 struct zr_databaseInfo *r = nmem_malloc(m, sizeof(*r));
222 memset(r, 0, sizeof(*r));
224 r->title = findlangstr(m, node, "title");
225 r->description = findlangstr(m, node, "description");
226 r->history = findlangstr(m, node, "history");
227 r->extent = findlangstr(m, node, "extent");
228 r->restrictions = findlangstr(m, node, "restrictions");
229 r->langUsage = findlangstr(m, node, "langUsage");
231 for (n = node->children; n; n = n->next)
233 if (n->type != XML_ELEMENT_NODE)
235 if (!strcmp(n->name, "agents"))
238 for (n2 = n->children; n2; n2 = n2->next)
240 if (n2->type != XML_ELEMENT_NODE)
242 if (strcmp(n2->name, "agent"))
246 struct zr_agent *ag = agent(m, n2);
249 ag->next = r->agents;
254 else if (!strcmp(n->name, "implementation"))
256 if (!(r->implementation = implementation(m, n)))
259 else if (!strcmp(n->name, "links"))
262 for (n2 = n->children; n2; n2 = n2->next)
264 if (n2->type != XML_ELEMENT_NODE)
266 if (!strcmp(n2->name, "link"))
270 struct zr_link *li = nmem_malloc(m, sizeof(*li));
271 memset(li, 0, sizeof(*li));
272 li->type = attrtostr(m, n2, "type");
273 li->value = valuetostr(m, n2);
279 else if (!strcmp(n->name, "history") && !r->lastUpdate)
280 r->lastUpdate = attrtostr(m, n, "lastUpdate");
281 else if (!strcmp(n->name, "extent") && !r->numberOfRecords)
282 r->numberOfRecords = attrtoint(n, "numberOfRecords");
283 else if (!strcmp(n->name, "langUsage") && !r->codes)
284 r->codes = attrtostr(m, n, "codes");
289 struct zr_metaInfo *metaInfo(NMEM m, xmlNode *node)
292 struct zr_metaInfo *r = nmem_malloc(m, sizeof(*r));
293 memset(r, 0, sizeof(*r));
295 for (n = node->children; n; n = n->next)
297 if (n->type != XML_ELEMENT_NODE)
299 if (!strcmp(n->name, "dateModified"))
300 r->dateModified = valuetostr(m, n);
301 else if (!strcmp(n->name, "dateAggregated"))
302 r->dateAggregated = valuetostr(m, n);
303 else if (!strcmp(n->name, "aggregatedFrom"))
304 r->aggregatedFrom = valuetostr(m, n);
307 fail("Unexpected element", n);
314 struct zr_set *set(NMEM m, xmlNode *node)
316 struct zr_set *r = nmem_malloc(m, sizeof(*r));
317 memset(r, 0, sizeof(*r));
318 r->name = attrtostr(m, node, "name");
319 r->identifier = attrtostr(m, node, "identifier");
320 r->title = findlangstr(m, node, "title");
324 struct zr_attr *attr(NMEM m, xmlNode *node)
326 struct zr_attr *r = nmem_malloc(m, sizeof(*r));
327 memset(r, 0, sizeof(*r));
328 r->type = attrtoint(node, "type");
329 r->set = attrtostr(m, node, "set");
333 static struct zr_map *map(NMEM m, xmlNode *node)
336 struct zr_map *r = nmem_malloc(m, sizeof(*r));
337 memset(r, 0, sizeof(*r));
339 r->lang = attrtostr(m, node, "lang");
340 r->primary = attrtobool(node, "primary");
341 for (n = node->children; n; n = n->next)
343 if (n->type != XML_ELEMENT_NODE)
345 if (!strcmp(n->name, "name"))
347 r->set = attrtostr(m, n, "set");
348 r->name = valuetostr(m, n);
350 else if (!strcmp(n->name, "attr"))
352 struct zr_attr *new = attr(m, n);
355 new->next = r->attrs;
360 fail("Unexpected element", n);
367 static Zr_setting *findsetting(NMEM m, xmlNode *node, char *name)
369 static Zr_setting *r = 0;
371 for (n = node->children; n; n = n->next)
373 if (node->type == XML_ELEMENT_NODE && !strcmp(n->name, name))
376 struct zr_setting *new = nmem_malloc(m, sizeof(*new));
377 memset(new, 0, sizeof(*new));
378 new->type = attrtostr(m, n, "type");
379 for (n2 = n->children; n2; n2 = n2->next)
381 if (n2->type == XML_ELEMENT_NODE && !strcmp(n2->name, "map"))
383 new->map = map(m, n2);
390 new->value = xmlNodeGetContent(n);
398 static struct zr_configInfo *configInfo(NMEM m, xmlNode *node)
400 struct zr_configInfo *r = nmem_malloc(m, sizeof(*r));
402 r->defaultv = findsetting(m, node, "default");
403 r->setting = findsetting(m, node, "setting");
404 r->supports = findsetting(m, node, "supports");
408 static struct zr_index *parse_index(NMEM m, xmlNode *node)
411 struct zr_index *r = nmem_malloc(m, sizeof(*r));
412 memset(r, 0, sizeof(*r));
414 r->search = attrtobool(node, "search");
415 r->scan = attrtobool(node, "scan");
416 r->sort = attrtobool(node, "sort");
417 r->id = attrtostr(m, node, "id");
418 r->title = findlangstr(m, node, "title");
420 for (n = node->children; n; n = n->next)
422 if (n->type != XML_ELEMENT_NODE)
424 if (!strcmp(n->name, "map"))
426 struct zr_map *new = map(m, n);
432 else if (!strcmp(n->name, "configInfo"))
434 if (!(r->configInfo = configInfo(m, n)))
437 else if (strcmp(n->name, "title"))
439 fail("Unknown child element", n);
446 static struct zr_sortKeyword *sortKeyword(NMEM m, xmlNode *node)
448 struct zr_sortKeyword *r = nmem_malloc(m, sizeof(*r));
449 memset(r, 0, sizeof(*r));
450 r->value = valuetostr(m, node);
454 static struct zr_indexInfo *indexInfo(NMEM m , xmlNode *node)
457 struct zr_indexInfo *r = nmem_malloc(m, sizeof(*r));
458 memset(r, 0, sizeof(*r));
460 for (n = node->children; n; n = n->next)
462 if (n->type != XML_ELEMENT_NODE)
464 if (!strcmp(n->name, "set"))
466 struct zr_set *new = set(m, n);
472 else if (!strcmp(n->name, "index"))
474 struct zr_index *new = parse_index(m, n);
477 new->next = r->indexes;
480 else if (!strcmp(n->name, "sortKeyword"))
482 struct zr_sortKeyword *new = sortKeyword(m, n);
485 new->next = r->sortKeywords;
486 r->sortKeywords = new;
488 else if (!strcmp(n->name, "sortKeyword"))
490 if (!(r->configInfo = configInfo(m, n)))
495 fail("Unknown child element", n);
502 static struct zr_elementSet *elementSet(NMEM m, xmlNode *node)
504 struct zr_elementSet *r = nmem_malloc(m, sizeof(*r));
505 memset(r, 0, sizeof(*r));
506 r->name = attrtostr(m, node, "name");
507 r->identifier = attrtostr(m, node, "identifier");
508 r->title = findlangstr(m, node, "title");
512 static struct zr_recordSyntax *recordSyntax(NMEM m, xmlNode *node)
515 struct zr_recordSyntax *r = nmem_malloc(m, sizeof(*r));
516 struct zr_elementSet **elementp = &r->elementSets;
518 memset(r, 0, sizeof(*r));
519 r->name = attrtostr(m, node, "name");
520 r->identifier = attrtostr(m, node, "identifier");
521 for (n = node->children; n; n = n->next)
523 if (n->type != XML_ELEMENT_NODE)
525 if (!strcmp(n->name, "elementSet"))
527 if (!(*elementp = elementSet(m, n)))
529 elementp = &(*elementp)->next;
533 fail("Unknown child element", n);
540 static struct zr_recordInfo *recordInfo(NMEM m, xmlNode *node)
543 struct zr_recordInfo *r = nmem_malloc(m, sizeof(*r));
544 struct zr_recordSyntax **syntaxp = &r->recordSyntaxes;
546 memset(r, 0, sizeof(*r));
547 for (n = node->children; n; n = n->next)
549 if (n->type != XML_ELEMENT_NODE)
551 if (!strcmp(n->name, "recordSyntax"))
553 if (!(*syntaxp = recordSyntax(m, n)))
555 syntaxp = &(*syntaxp)->next;
559 fail("Unknown child element", n);
567 static struct zr_schema *schema(NMEM m, xmlNode *node)
569 struct zr_schema *r = nmem_malloc(m, sizeof(*r));
570 memset(r, 0, sizeof(*r));
572 r->name = attrtostr(m, node, "name");
573 r->identifier = attrtostr(m, node, "identifier");
574 r->retrieve = attrtobool(node, "retrieve");
575 r->sort = attrtobool(node, "sort");
576 r->location = attrtostr(m, node, "location");
577 r->title = findlangstr(m, node, "title");
581 static struct zr_schemaInfo *schemaInfo(NMEM m, xmlNode *node)
584 struct zr_schemaInfo *r = nmem_malloc(m, sizeof(*r));
585 struct zr_schema **schemap = &r->schemas;
587 memset(r, 0, sizeof(*r));
588 for (n = node->children; n; n = n->next)
590 if (n->type != XML_ELEMENT_NODE)
592 if (!strcmp(n->name, "schema"))
594 if (!(*schemap = schema(m, n)))
596 schemap = &(*schemap)->next;
600 fail("Unknown child element", n);
607 static struct zr_explain *explain(NMEM m, xmlNode *node)
610 struct zr_explain *r = nmem_malloc(m, sizeof(*r));
611 memset(r, 0, sizeof(*r));
613 for (n = node->children; n; n = n->next)
615 if (n->type != XML_ELEMENT_NODE)
617 if (!strcmp(n->name, "serverInfo"))
619 if (!(r->serverInfo = serverInfo(m, n)))
622 else if (!strcmp(n->name, "databaseInfo"))
624 if (!(r->databaseInfo = databaseInfo(m, n)))
627 else if (!strcmp(n->name, "metaInfo"))
629 if (!(r->metaInfo = metaInfo(m, n)))
632 else if (!strcmp(n->name, "indexInfo"))
634 if (!(r->indexInfo = indexInfo(m, n)))
637 else if (!strcmp(n->name, "recordInfo"))
639 if (!(r->recordInfo = recordInfo(m, n)))
642 else if (!strcmp(n->name, "schemaInfo"))
644 if (!(r->schemaInfo = schemaInfo(m, n)))
647 else if (!strcmp(n->name, "configInfo"))
649 if (!(r->configInfo = configInfo(m, n)))
652 else if (!strcmp(n->name, "status"))
656 fail("Unknown child element of root node", n);
663 struct zr_explain *zr_read_xml(NMEM m, xmlNode *n)
665 return explain(m, n);
668 struct zr_explain *zr_read_file(NMEM m, const char *fn)
670 xmlDoc *doc = xmlParseFile(fn);
671 struct zr_explain *r;
674 yaz_log(YLOG_WARN|YLOG_ERRNO, "Unable to open %s", fn);
677 r = explain(m, xmlDocGetRootElement(doc));
685 * indent-tabs-mode: nil
687 * vim: shiftwidth=4 tabstop=8 expandtab