1 /* $Id: zeerex.c,v 1.5 2007-03-29 11:02:04 marc 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 = (char *) xmlGetProp(n, (xmlChar *) name);
26 char *r = nmem_strdup(m, s);
34 static int attrtoint(xmlNode *n, const char *name)
36 char *s = (char *)xmlGetProp(n, (xmlChar *) name);
47 static Zr_bool attrtobool(xmlNode *node, const char *name)
49 char *v = (char *) xmlGetProp(node, (xmlChar *) 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 = (char *) xmlNodeGetContent(n);
71 char *res = nmem_strdup(m, val);
79 static int valuetoint(xmlNode *n)
81 char *s = (char *) 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
99 && !strcmp((const char *) n->name, name))
101 Zr_langstr *new = nmem_malloc(m, sizeof(*new));
102 memset(new, 0, sizeof(*new));
103 new->primary = attrtobool(n, "primary");
104 new->lang = attrtostr(m, n, "lang");
105 new->str = valuetostr(m, n);
113 const char *zr_langstr(Zr_langstr *s, const char *lang)
116 for (p = s; p; p = p->next)
117 if ((!lang && p->primary == Zr_bool_true) ||
118 (lang && p->lang && !strcmp(lang, p->lang)))
123 static struct zr_authentication *authentication(NMEM m, xmlNode *node)
126 struct zr_authentication *r = nmem_malloc(m, sizeof(*r));
127 memset(r, 0, sizeof(*r));
128 r->type = attrtostr(m, node, "type");
129 for (n = node->children; n; n = n->next)
131 if (n->type != XML_ELEMENT_NODE)
133 if (!strcmp((const char *) n->name, "open"))
134 r->open = valuetostr(m, n);
135 else if (!strcmp((const char *) n->name, "user"))
136 r->user = valuetostr(m, n);
137 else if (!strcmp((const char *) n->name, "group"))
138 r->group = valuetostr(m, n);
139 else if (!strcmp((const char *) n->name, "password"))
140 r->password = valuetostr(m, n);
143 fail("Unexpected element", n);
151 static struct zr_serverInfo *serverInfo(NMEM m, xmlNode *node)
154 struct zr_serverInfo *r = nmem_malloc(m, sizeof(*r));
155 memset(r, 0, sizeof(*r));
157 r->protocol = attrtostr(m, node, "protocol");
158 r->version = attrtostr(m, node, "version");
159 r->transport = attrtostr(m, node, "transport");
160 r->method = attrtostr(m, node, "method");
161 for (n = node->children; n; n = n->next)
163 if (n->type != XML_ELEMENT_NODE)
165 if (!strcmp((const char *) n->name, "host"))
166 r->host = valuetostr(m, n);
167 else if (!strcmp((const char *) n->name, "port"))
168 r->port = valuetoint(n);
169 else if (!strcmp((const char *) n->name, "database"))
170 r->database = valuetostr(m, n);
171 else if (!strcmp((const char *) n->name, "authentication"))
173 if (!(r->authentication = authentication(m, n)))
178 fail("Unexpected element", n);
185 static struct zr_agent *agent(NMEM m, xmlNode *node)
187 struct zr_agent *r = nmem_malloc(m, sizeof(*r));
188 memset(r, 0, sizeof(*r));
189 r->type = attrtostr(m, node, "type");
190 r->identifier = attrtostr(m, node, "identifier");
191 r->value = valuetostr(m, node);
195 static struct zr_implementation *implementation(NMEM m, xmlNode *node)
198 struct zr_implementation *r = nmem_malloc(m, sizeof(*r));
199 memset(r, 0, sizeof(*r));
200 r->identifier = attrtostr(m, node, "identifier");
201 r->version = attrtostr(m, node, "version");
202 r->title = findlangstr(m, node, "title");
203 for (n = node->children; n; n = n->next)
205 if (n->type != XML_ELEMENT_NODE)
207 if (!strcmp((const char *) n->name, "agent"))
209 struct zr_agent *ag = agent(m, node);
212 ag->next = r->agents;
219 struct zr_databaseInfo *databaseInfo(NMEM m, xmlNode *node)
222 struct zr_databaseInfo *r = nmem_malloc(m, sizeof(*r));
223 memset(r, 0, sizeof(*r));
225 r->title = findlangstr(m, node, "title");
226 r->description = findlangstr(m, node, "description");
227 r->history = findlangstr(m, node, "history");
228 r->extent = findlangstr(m, node, "extent");
229 r->restrictions = findlangstr(m, node, "restrictions");
230 r->langUsage = findlangstr(m, node, "langUsage");
232 for (n = node->children; n; n = n->next)
234 if (n->type != XML_ELEMENT_NODE)
236 if (!strcmp((const char *) n->name, "agents"))
239 for (n2 = n->children; n2; n2 = n2->next)
241 if (n2->type != XML_ELEMENT_NODE)
243 if (strcmp((const char *) n2->name, "agent"))
247 struct zr_agent *ag = agent(m, n2);
250 ag->next = r->agents;
255 else if (!strcmp((const char *) n->name, "implementation"))
257 if (!(r->implementation = implementation(m, n)))
260 else if (!strcmp((const char *) n->name, "links"))
263 for (n2 = n->children; n2; n2 = n2->next)
265 if (n2->type != XML_ELEMENT_NODE)
267 if (!strcmp((const char *) n2->name, "link"))
271 struct zr_link *li = nmem_malloc(m, sizeof(*li));
272 memset(li, 0, sizeof(*li));
273 li->type = attrtostr(m, n2, "type");
274 li->value = valuetostr(m, n2);
280 else if (!strcmp((const char *) n->name, "history") && !r->lastUpdate)
281 r->lastUpdate = attrtostr(m, n, "lastUpdate");
282 else if (!strcmp((const char *) n->name, "extent") && !r->numberOfRecords)
283 r->numberOfRecords = attrtoint(n, "numberOfRecords");
284 else if (!strcmp((const char *) n->name, "langUsage") && !r->codes)
285 r->codes = attrtostr(m, n, "codes");
290 struct zr_metaInfo *metaInfo(NMEM m, xmlNode *node)
293 struct zr_metaInfo *r = nmem_malloc(m, sizeof(*r));
294 memset(r, 0, sizeof(*r));
296 for (n = node->children; n; n = n->next)
298 if (n->type != XML_ELEMENT_NODE)
300 if (!strcmp((const char *) n->name, "dateModified"))
301 r->dateModified = valuetostr(m, n);
302 else if (!strcmp((const char *) n->name, "dateAggregated"))
303 r->dateAggregated = valuetostr(m, n);
304 else if (!strcmp((const char *) n->name, "aggregatedFrom"))
305 r->aggregatedFrom = valuetostr(m, n);
308 fail("Unexpected element", n);
315 struct zr_set *set(NMEM m, xmlNode *node)
317 struct zr_set *r = nmem_malloc(m, sizeof(*r));
318 memset(r, 0, sizeof(*r));
319 r->name = attrtostr(m, node, "name");
320 r->identifier = attrtostr(m, node, "identifier");
321 r->title = findlangstr(m, node, "title");
325 struct zr_attr *attr(NMEM m, xmlNode *node)
327 struct zr_attr *r = nmem_malloc(m, sizeof(*r));
328 memset(r, 0, sizeof(*r));
329 r->type = attrtoint(node, "type");
330 r->set = attrtostr(m, node, "set");
334 static struct zr_map *map(NMEM m, xmlNode *node)
337 struct zr_map *r = nmem_malloc(m, sizeof(*r));
338 memset(r, 0, sizeof(*r));
340 r->lang = attrtostr(m, node, "lang");
341 r->primary = attrtobool(node, "primary");
342 for (n = node->children; n; n = n->next)
344 if (n->type != XML_ELEMENT_NODE)
346 if (!strcmp((const char *) n->name, "name"))
348 r->set = attrtostr(m, n, "set");
349 r->name = valuetostr(m, n);
351 else if (!strcmp((const char *) n->name, "attr"))
353 struct zr_attr *new = attr(m, n);
356 new->next = r->attrs;
361 fail("Unexpected element", n);
368 static Zr_setting *findsetting(NMEM m, xmlNode *node, char *name)
370 static Zr_setting *r = 0;
372 for (n = node->children; n; n = n->next)
374 if (node->type == XML_ELEMENT_NODE && !strcmp((const char *) n->name, name))
377 struct zr_setting *new = nmem_malloc(m, sizeof(*new));
378 memset(new, 0, sizeof(*new));
379 new->type = attrtostr(m, n, "type");
380 for (n2 = n->children; n2; n2 = n2->next)
382 if (n2->type == XML_ELEMENT_NODE && !strcmp((const char *) n2->name, "map"))
384 new->map = map(m, n2);
391 new->value = (char *) xmlNodeGetContent(n);
399 static struct zr_configInfo *configInfo(NMEM m, xmlNode *node)
401 struct zr_configInfo *r = nmem_malloc(m, sizeof(*r));
403 r->defaultv = findsetting(m, node, "default");
404 r->setting = findsetting(m, node, "setting");
405 r->supports = findsetting(m, node, "supports");
409 static struct zr_index *parse_index(NMEM m, xmlNode *node)
412 struct zr_index *r = nmem_malloc(m, sizeof(*r));
413 memset(r, 0, sizeof(*r));
415 r->search = attrtobool(node, "search");
416 r->scan = attrtobool(node, "scan");
417 r->sort = attrtobool(node, "sort");
418 r->id = attrtostr(m, node, "id");
419 r->title = findlangstr(m, node, "title");
421 for (n = node->children; n; n = n->next)
423 if (n->type != XML_ELEMENT_NODE)
425 if (!strcmp((const char *) n->name, "map"))
427 struct zr_map *new = map(m, n);
433 else if (!strcmp((const char *) n->name, "configInfo"))
435 if (!(r->configInfo = configInfo(m, n)))
438 else if (strcmp((const char *) n->name, "title"))
440 fail("Unknown child element", n);
447 static struct zr_sortKeyword *sortKeyword(NMEM m, xmlNode *node)
449 struct zr_sortKeyword *r = nmem_malloc(m, sizeof(*r));
450 memset(r, 0, sizeof(*r));
451 r->value = valuetostr(m, node);
455 static struct zr_indexInfo *indexInfo(NMEM m , xmlNode *node)
458 struct zr_indexInfo *r = nmem_malloc(m, sizeof(*r));
459 memset(r, 0, sizeof(*r));
461 for (n = node->children; n; n = n->next)
463 if (n->type != XML_ELEMENT_NODE)
465 if (!strcmp((const char *) n->name, "set"))
467 struct zr_set *new = set(m, n);
473 else if (!strcmp((const char *) n->name, "index"))
475 struct zr_index *new = parse_index(m, n);
478 new->next = r->indexes;
481 else if (!strcmp((const char *) n->name, "sortKeyword"))
483 struct zr_sortKeyword *new = sortKeyword(m, n);
486 new->next = r->sortKeywords;
487 r->sortKeywords = new;
489 else if (!strcmp((const char *) n->name, "sortKeyword"))
491 if (!(r->configInfo = configInfo(m, n)))
496 fail("Unknown child element", n);
503 static struct zr_elementSet *elementSet(NMEM m, xmlNode *node)
505 struct zr_elementSet *r = nmem_malloc(m, sizeof(*r));
506 memset(r, 0, sizeof(*r));
507 r->name = attrtostr(m, node, "name");
508 r->identifier = attrtostr(m, node, "identifier");
509 r->title = findlangstr(m, node, "title");
513 static struct zr_recordSyntax *recordSyntax(NMEM m, xmlNode *node)
516 struct zr_recordSyntax *r = nmem_malloc(m, sizeof(*r));
517 struct zr_elementSet **elementp = &r->elementSets;
519 memset(r, 0, sizeof(*r));
520 r->name = attrtostr(m, node, "name");
521 r->identifier = attrtostr(m, node, "identifier");
522 for (n = node->children; n; n = n->next)
524 if (n->type != XML_ELEMENT_NODE)
526 if (!strcmp((const char *) n->name, "elementSet"))
528 if (!(*elementp = elementSet(m, n)))
530 elementp = &(*elementp)->next;
534 fail("Unknown child element", n);
541 static struct zr_recordInfo *recordInfo(NMEM m, xmlNode *node)
544 struct zr_recordInfo *r = nmem_malloc(m, sizeof(*r));
545 struct zr_recordSyntax **syntaxp = &r->recordSyntaxes;
547 memset(r, 0, sizeof(*r));
548 for (n = node->children; n; n = n->next)
550 if (n->type != XML_ELEMENT_NODE)
552 if (!strcmp((const char *) n->name, "recordSyntax"))
554 if (!(*syntaxp = recordSyntax(m, n)))
556 syntaxp = &(*syntaxp)->next;
560 fail("Unknown child element", n);
568 static struct zr_schema *schema(NMEM m, xmlNode *node)
570 struct zr_schema *r = nmem_malloc(m, sizeof(*r));
571 memset(r, 0, sizeof(*r));
573 r->name = attrtostr(m, node, "name");
574 r->identifier = attrtostr(m, node, "identifier");
575 r->retrieve = attrtobool(node, "retrieve");
576 r->sort = attrtobool(node, "sort");
577 r->location = attrtostr(m, node, "location");
578 r->title = findlangstr(m, node, "title");
582 static struct zr_schemaInfo *schemaInfo(NMEM m, xmlNode *node)
585 struct zr_schemaInfo *r = nmem_malloc(m, sizeof(*r));
586 struct zr_schema **schemap = &r->schemas;
588 memset(r, 0, sizeof(*r));
589 for (n = node->children; n; n = n->next)
591 if (n->type != XML_ELEMENT_NODE)
593 if (!strcmp((const char *) n->name, "schema"))
595 if (!(*schemap = schema(m, n)))
597 schemap = &(*schemap)->next;
601 fail("Unknown child element", n);
608 static struct zr_explain *explain(NMEM m, xmlNode *node)
611 struct zr_explain *r = nmem_malloc(m, sizeof(*r));
612 memset(r, 0, sizeof(*r));
614 for (n = node->children; n; n = n->next)
616 if (n->type != XML_ELEMENT_NODE)
618 if (!strcmp((const char *) n->name, "serverInfo"))
620 if (!(r->serverInfo = serverInfo(m, n)))
623 else if (!strcmp((const char *) n->name, "databaseInfo"))
625 if (!(r->databaseInfo = databaseInfo(m, n)))
628 else if (!strcmp((const char *) n->name, "metaInfo"))
630 if (!(r->metaInfo = metaInfo(m, n)))
633 else if (!strcmp((const char *) n->name, "indexInfo"))
635 if (!(r->indexInfo = indexInfo(m, n)))
638 else if (!strcmp((const char *) n->name, "recordInfo"))
640 if (!(r->recordInfo = recordInfo(m, n)))
643 else if (!strcmp((const char *) n->name, "schemaInfo"))
645 if (!(r->schemaInfo = schemaInfo(m, n)))
648 else if (!strcmp((const char *) n->name, "configInfo"))
650 if (!(r->configInfo = configInfo(m, n)))
653 else if (!strcmp((const char *) n->name, "status"))
657 fail("Unknown child element of root node", n);
664 struct zr_explain *zr_read_xml(NMEM m, xmlNode *n)
666 return explain(m, n);
669 struct zr_explain *zr_read_file(NMEM m, const char *fn)
671 xmlDoc *doc = xmlParseFile(fn);
672 struct zr_explain *r;
675 yaz_log(YLOG_WARN|YLOG_ERRNO, "Unable to open %s", fn);
678 r = explain(m, xmlDocGetRootElement(doc));
686 * indent-tabs-mode: nil
688 * vim: shiftwidth=4 tabstop=8 expandtab