1 /* $Id: zeerex.c,v 1.6 2007-03-31 20:06:18 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'",
18 s, n->parent->name, n->name);
21 // returns an nmem-allocated string if attr is present, or null
22 static char *attrtostr(NMEM m, xmlNode *n, const char *name)
24 char *s = (char *) xmlGetProp(n, (xmlChar *) name);
27 char *r = nmem_strdup(m, s);
35 static int attrtoint(xmlNode *n, const char *name)
37 char *s = (char *)xmlGetProp(n, (xmlChar *) name);
48 static Zr_bool attrtobool(xmlNode *node, const char *name)
50 char *v = (char *) xmlGetProp(node, (xmlChar *) name);
54 if (!strcmp(v, "true"))
56 else if (!strcmp(v, "false"))
59 res = Zr_bool_unknown;
64 return Zr_bool_unknown;
67 static char *valuetostr(NMEM m, xmlNode *n)
69 char *val = (char *) xmlNodeGetContent(n);
72 char *res = nmem_strdup(m, val);
80 static int valuetoint(xmlNode *n)
82 char *s = (char *) xmlNodeGetContent(n);
93 static Zr_langstr *findlangstr(NMEM m, xmlNode *node, const char *name)
97 for (n = node->children; n; n = n->next)
99 if (n->type == XML_ELEMENT_NODE
100 && !strcmp((const char *) n->name, name))
102 Zr_langstr *new = nmem_malloc(m, sizeof(*new));
103 memset(new, 0, sizeof(*new));
104 new->primary = attrtobool(n, "primary");
105 new->lang = attrtostr(m, n, "lang");
106 new->str = valuetostr(m, n);
114 const char *zr_langstr(Zr_langstr *s, const char *lang)
117 for (p = s; p; p = p->next)
118 if ((!lang && p->primary == Zr_bool_true) ||
119 (lang && p->lang && !strcmp(lang, p->lang)))
124 static struct zr_authentication *authentication(NMEM m, xmlNode *node)
127 struct zr_authentication *r = nmem_malloc(m, sizeof(*r));
128 memset(r, 0, sizeof(*r));
129 r->type = attrtostr(m, node, "type");
130 for (n = node->children; n; n = n->next)
132 if (n->type != XML_ELEMENT_NODE)
134 if (!strcmp((const char *) n->name, "open"))
135 r->open = valuetostr(m, n);
136 else if (!strcmp((const char *) n->name, "user"))
137 r->user = valuetostr(m, n);
138 else if (!strcmp((const char *) n->name, "group"))
139 r->group = valuetostr(m, n);
140 else if (!strcmp((const char *) n->name, "password"))
141 r->password = valuetostr(m, n);
144 fail("Unexpected element", n);
152 static struct zr_serverInfo *serverInfo(NMEM m, xmlNode *node)
155 struct zr_serverInfo *r = nmem_malloc(m, sizeof(*r));
156 memset(r, 0, sizeof(*r));
158 r->protocol = attrtostr(m, node, "protocol");
159 r->version = attrtostr(m, node, "version");
160 r->transport = attrtostr(m, node, "transport");
161 r->method = attrtostr(m, node, "method");
162 for (n = node->children; n; n = n->next)
164 if (n->type != XML_ELEMENT_NODE)
166 if (!strcmp((const char *) n->name, "host"))
167 r->host = valuetostr(m, n);
168 else if (!strcmp((const char *) n->name, "port"))
169 r->port = valuetoint(n);
170 else if (!strcmp((const char *) n->name, "database"))
171 r->database = valuetostr(m, n);
172 else if (!strcmp((const char *) n->name, "authentication"))
174 if (!(r->authentication = authentication(m, n)))
179 fail("Unexpected element", n);
186 static struct zr_agent *agent(NMEM m, xmlNode *node)
188 struct zr_agent *r = nmem_malloc(m, sizeof(*r));
189 memset(r, 0, sizeof(*r));
190 r->type = attrtostr(m, node, "type");
191 r->identifier = attrtostr(m, node, "identifier");
192 r->value = valuetostr(m, node);
196 static struct zr_implementation *implementation(NMEM m, xmlNode *node)
199 struct zr_implementation *r = nmem_malloc(m, sizeof(*r));
200 memset(r, 0, sizeof(*r));
201 r->identifier = attrtostr(m, node, "identifier");
202 r->version = attrtostr(m, node, "version");
203 r->title = findlangstr(m, node, "title");
204 for (n = node->children; n; n = n->next)
206 if (n->type != XML_ELEMENT_NODE)
208 if (!strcmp((const char *) n->name, "agent"))
210 struct zr_agent *ag = agent(m, node);
213 ag->next = r->agents;
220 struct zr_databaseInfo *databaseInfo(NMEM m, xmlNode *node)
223 struct zr_databaseInfo *r = nmem_malloc(m, sizeof(*r));
224 memset(r, 0, sizeof(*r));
226 r->title = findlangstr(m, node, "title");
227 r->description = findlangstr(m, node, "description");
228 r->history = findlangstr(m, node, "history");
229 r->extent = findlangstr(m, node, "extent");
230 r->restrictions = findlangstr(m, node, "restrictions");
231 r->langUsage = findlangstr(m, node, "langUsage");
233 for (n = node->children; n; n = n->next)
235 if (n->type != XML_ELEMENT_NODE)
237 if (!strcmp((const char *) n->name, "agents"))
240 for (n2 = n->children; n2; n2 = n2->next)
242 if (n2->type != XML_ELEMENT_NODE)
244 if (strcmp((const char *) n2->name, "agent"))
248 struct zr_agent *ag = agent(m, n2);
251 ag->next = r->agents;
256 else if (!strcmp((const char *) n->name, "implementation"))
258 if (!(r->implementation = implementation(m, n)))
261 else if (!strcmp((const char *) n->name, "links"))
264 for (n2 = n->children; n2; n2 = n2->next)
266 if (n2->type != XML_ELEMENT_NODE)
268 if (!strcmp((const char *) n2->name, "link"))
272 struct zr_link *li = nmem_malloc(m, sizeof(*li));
273 memset(li, 0, sizeof(*li));
274 li->type = attrtostr(m, n2, "type");
275 li->value = valuetostr(m, n2);
281 else if (!strcmp((const char *) n->name, "history") && !r->lastUpdate)
282 r->lastUpdate = attrtostr(m, n, "lastUpdate");
283 else if (!strcmp((const char *) n->name, "extent") && !r->numberOfRecords)
284 r->numberOfRecords = attrtoint(n, "numberOfRecords");
285 else if (!strcmp((const char *) n->name, "langUsage") && !r->codes)
286 r->codes = attrtostr(m, n, "codes");
291 struct zr_metaInfo *metaInfo(NMEM m, xmlNode *node)
294 struct zr_metaInfo *r = nmem_malloc(m, sizeof(*r));
295 memset(r, 0, sizeof(*r));
297 for (n = node->children; n; n = n->next)
299 if (n->type != XML_ELEMENT_NODE)
301 if (!strcmp((const char *) n->name, "dateModified"))
302 r->dateModified = valuetostr(m, n);
303 else if (!strcmp((const char *) n->name, "dateAggregated"))
304 r->dateAggregated = valuetostr(m, n);
305 else if (!strcmp((const char *) n->name, "aggregatedFrom"))
306 r->aggregatedFrom = valuetostr(m, n);
309 fail("Unexpected element", n);
316 struct zr_set *set(NMEM m, xmlNode *node)
318 struct zr_set *r = nmem_malloc(m, sizeof(*r));
319 memset(r, 0, sizeof(*r));
320 r->name = attrtostr(m, node, "name");
321 r->identifier = attrtostr(m, node, "identifier");
322 r->title = findlangstr(m, node, "title");
326 struct zr_attr *attr(NMEM m, xmlNode *node)
328 struct zr_attr *r = nmem_malloc(m, sizeof(*r));
329 memset(r, 0, sizeof(*r));
330 r->type = attrtoint(node, "type");
331 r->set = attrtostr(m, node, "set");
335 static struct zr_map *map(NMEM m, xmlNode *node)
338 struct zr_map *r = nmem_malloc(m, sizeof(*r));
339 memset(r, 0, sizeof(*r));
341 r->lang = attrtostr(m, node, "lang");
342 r->primary = attrtobool(node, "primary");
343 for (n = node->children; n; n = n->next)
345 if (n->type != XML_ELEMENT_NODE)
347 if (!strcmp((const char *) n->name, "name"))
349 r->set = attrtostr(m, n, "set");
350 r->name = valuetostr(m, n);
352 else if (!strcmp((const char *) n->name, "attr"))
354 struct zr_attr *new = attr(m, n);
357 new->next = r->attrs;
362 fail("Unexpected element", n);
369 static Zr_setting *findsetting(NMEM m, xmlNode *node, char *name)
371 static Zr_setting *r = 0;
373 for (n = node->children; n; n = n->next)
375 if (node->type == XML_ELEMENT_NODE && !strcmp((const char *) n->name, name))
378 struct zr_setting *new = nmem_malloc(m, sizeof(*new));
379 memset(new, 0, sizeof(*new));
380 new->type = attrtostr(m, n, "type");
381 for (n2 = n->children; n2; n2 = n2->next)
383 if (n2->type == XML_ELEMENT_NODE && !strcmp((const char *) n2->name, "map"))
385 new->map = map(m, n2);
392 new->value = (char *) xmlNodeGetContent(n);
400 static struct zr_configInfo *configInfo(NMEM m, xmlNode *node)
402 struct zr_configInfo *r = nmem_malloc(m, sizeof(*r));
404 r->defaultv = findsetting(m, node, "default");
405 r->setting = findsetting(m, node, "setting");
406 r->supports = findsetting(m, node, "supports");
410 static struct zr_index *parse_index(NMEM m, xmlNode *node)
413 struct zr_index *r = nmem_malloc(m, sizeof(*r));
414 memset(r, 0, sizeof(*r));
416 r->search = attrtobool(node, "search");
417 r->scan = attrtobool(node, "scan");
418 r->sort = attrtobool(node, "sort");
419 r->id = attrtostr(m, node, "id");
420 r->title = findlangstr(m, node, "title");
422 for (n = node->children; n; n = n->next)
424 if (n->type != XML_ELEMENT_NODE)
426 if (!strcmp((const char *) n->name, "map"))
428 struct zr_map *new = map(m, n);
434 else if (!strcmp((const char *) n->name, "configInfo"))
436 if (!(r->configInfo = configInfo(m, n)))
439 else if (strcmp((const char *) n->name, "title"))
441 fail("Unknown child element", n);
448 static struct zr_sortKeyword *sortKeyword(NMEM m, xmlNode *node)
450 struct zr_sortKeyword *r = nmem_malloc(m, sizeof(*r));
451 memset(r, 0, sizeof(*r));
452 r->value = valuetostr(m, node);
456 static struct zr_indexInfo *indexInfo(NMEM m , xmlNode *node)
459 struct zr_indexInfo *r = nmem_malloc(m, sizeof(*r));
460 memset(r, 0, sizeof(*r));
462 for (n = node->children; n; n = n->next)
464 if (n->type != XML_ELEMENT_NODE)
466 if (!strcmp((const char *) n->name, "set"))
468 struct zr_set *new = set(m, n);
474 else if (!strcmp((const char *) n->name, "index"))
476 struct zr_index *new = parse_index(m, n);
479 new->next = r->indexes;
482 else if (!strcmp((const char *) n->name, "sortKeyword"))
484 struct zr_sortKeyword *new = sortKeyword(m, n);
487 new->next = r->sortKeywords;
488 r->sortKeywords = new;
490 else if (!strcmp((const char *) n->name, "sortKeyword"))
492 if (!(r->configInfo = configInfo(m, n)))
497 fail("Unknown child element", n);
504 static struct zr_elementSet *elementSet(NMEM m, xmlNode *node)
506 struct zr_elementSet *r = nmem_malloc(m, sizeof(*r));
507 memset(r, 0, sizeof(*r));
508 r->name = attrtostr(m, node, "name");
509 r->identifier = attrtostr(m, node, "identifier");
510 r->title = findlangstr(m, node, "title");
514 static struct zr_recordSyntax *recordSyntax(NMEM m, xmlNode *node)
517 struct zr_recordSyntax *r = nmem_malloc(m, sizeof(*r));
518 struct zr_elementSet **elementp = &r->elementSets;
520 memset(r, 0, sizeof(*r));
521 r->name = attrtostr(m, node, "name");
522 r->identifier = attrtostr(m, node, "identifier");
523 for (n = node->children; n; n = n->next)
525 if (n->type != XML_ELEMENT_NODE)
527 if (!strcmp((const char *) n->name, "elementSet"))
529 if (!(*elementp = elementSet(m, n)))
531 elementp = &(*elementp)->next;
535 fail("Unknown child element", n);
542 static struct zr_recordInfo *recordInfo(NMEM m, xmlNode *node)
545 struct zr_recordInfo *r = nmem_malloc(m, sizeof(*r));
546 struct zr_recordSyntax **syntaxp = &r->recordSyntaxes;
548 memset(r, 0, sizeof(*r));
549 for (n = node->children; n; n = n->next)
551 if (n->type != XML_ELEMENT_NODE)
553 if (!strcmp((const char *) n->name, "recordSyntax"))
555 if (!(*syntaxp = recordSyntax(m, n)))
557 syntaxp = &(*syntaxp)->next;
561 fail("Unknown child element", n);
569 static struct zr_schema *schema(NMEM m, xmlNode *node)
571 struct zr_schema *r = nmem_malloc(m, sizeof(*r));
572 memset(r, 0, sizeof(*r));
574 r->name = attrtostr(m, node, "name");
575 r->identifier = attrtostr(m, node, "identifier");
576 r->retrieve = attrtobool(node, "retrieve");
577 r->sort = attrtobool(node, "sort");
578 r->location = attrtostr(m, node, "location");
579 r->title = findlangstr(m, node, "title");
583 static struct zr_schemaInfo *schemaInfo(NMEM m, xmlNode *node)
586 struct zr_schemaInfo *r = nmem_malloc(m, sizeof(*r));
587 struct zr_schema **schemap = &r->schemas;
589 memset(r, 0, sizeof(*r));
590 for (n = node->children; n; n = n->next)
592 if (n->type != XML_ELEMENT_NODE)
594 if (!strcmp((const char *) n->name, "schema"))
596 if (!(*schemap = schema(m, n)))
598 schemap = &(*schemap)->next;
602 fail("Unknown child element", n);
609 static struct zr_explain *explain(NMEM m, xmlNode *node)
612 struct zr_explain *r = nmem_malloc(m, sizeof(*r));
613 memset(r, 0, sizeof(*r));
615 for (n = node->children; n; n = n->next)
617 if (n->type != XML_ELEMENT_NODE)
619 if (!strcmp((const char *) n->name, "serverInfo"))
621 if (!(r->serverInfo = serverInfo(m, n)))
624 else if (!strcmp((const char *) n->name, "databaseInfo"))
626 if (!(r->databaseInfo = databaseInfo(m, n)))
629 else if (!strcmp((const char *) n->name, "metaInfo"))
631 if (!(r->metaInfo = metaInfo(m, n)))
634 else if (!strcmp((const char *) n->name, "indexInfo"))
636 if (!(r->indexInfo = indexInfo(m, n)))
639 else if (!strcmp((const char *) n->name, "recordInfo"))
641 if (!(r->recordInfo = recordInfo(m, n)))
644 else if (!strcmp((const char *) n->name, "schemaInfo"))
646 if (!(r->schemaInfo = schemaInfo(m, n)))
649 else if (!strcmp((const char *) n->name, "configInfo"))
651 if (!(r->configInfo = configInfo(m, n)))
654 else if (!strcmp((const char *) n->name, "status"))
658 fail("Unknown child element of root node", n);
665 struct zr_explain *zr_read_xml(NMEM m, xmlNode *n)
667 return explain(m, n);
670 struct zr_explain *zr_read_file(NMEM m, const char *fn)
672 xmlDoc *doc = xmlParseFile(fn);
673 struct zr_explain *r;
676 yaz_log(YLOG_WARN|YLOG_ERRNO, "Unable to open %s", fn);
679 r = explain(m, xmlDocGetRootElement(doc));
687 * indent-tabs-mode: nil
689 * vim: shiftwidth=4 tabstop=8 expandtab