1 /* $Id: zeerex.c,v 1.7 2007-04-10 08:48:56 adam Exp $
2 Copyright (c) 2006-2007, Index Data.
4 This file is part of Pazpar2.
6 Pazpar2 is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with Pazpar2; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 // Reads Zeerex records into a set of structures
26 #include <yaz/yaz-util.h>
28 #include <libxml/parser.h>
29 #include <libxml/tree.h>
33 // Replace this with something that will take a callback
34 static void fail(const char *s, xmlNode *n)
36 yaz_log(YLOG_WARN, "Zeerex Err '%s'; elem '%s/%s'",
37 s, n->parent->name, n->name);
40 // returns an nmem-allocated string if attr is present, or null
41 static char *attrtostr(NMEM m, xmlNode *n, const char *name)
43 char *s = (char *) xmlGetProp(n, (xmlChar *) name);
46 char *r = nmem_strdup(m, s);
54 static int attrtoint(xmlNode *n, const char *name)
56 char *s = (char *)xmlGetProp(n, (xmlChar *) name);
67 static Zr_bool attrtobool(xmlNode *node, const char *name)
69 char *v = (char *) xmlGetProp(node, (xmlChar *) name);
73 if (!strcmp(v, "true"))
75 else if (!strcmp(v, "false"))
78 res = Zr_bool_unknown;
83 return Zr_bool_unknown;
86 static char *valuetostr(NMEM m, xmlNode *n)
88 char *val = (char *) xmlNodeGetContent(n);
91 char *res = nmem_strdup(m, val);
99 static int valuetoint(xmlNode *n)
101 char *s = (char *) xmlNodeGetContent(n);
112 static Zr_langstr *findlangstr(NMEM m, xmlNode *node, const char *name)
116 for (n = node->children; n; n = n->next)
118 if (n->type == XML_ELEMENT_NODE
119 && !strcmp((const char *) n->name, name))
121 Zr_langstr *new = nmem_malloc(m, sizeof(*new));
122 memset(new, 0, sizeof(*new));
123 new->primary = attrtobool(n, "primary");
124 new->lang = attrtostr(m, n, "lang");
125 new->str = valuetostr(m, n);
133 const char *zr_langstr(Zr_langstr *s, const char *lang)
136 for (p = s; p; p = p->next)
137 if ((!lang && p->primary == Zr_bool_true) ||
138 (lang && p->lang && !strcmp(lang, p->lang)))
143 static struct zr_authentication *authentication(NMEM m, xmlNode *node)
146 struct zr_authentication *r = nmem_malloc(m, sizeof(*r));
147 memset(r, 0, sizeof(*r));
148 r->type = attrtostr(m, node, "type");
149 for (n = node->children; n; n = n->next)
151 if (n->type != XML_ELEMENT_NODE)
153 if (!strcmp((const char *) n->name, "open"))
154 r->open = valuetostr(m, n);
155 else if (!strcmp((const char *) n->name, "user"))
156 r->user = valuetostr(m, n);
157 else if (!strcmp((const char *) n->name, "group"))
158 r->group = valuetostr(m, n);
159 else if (!strcmp((const char *) n->name, "password"))
160 r->password = valuetostr(m, n);
163 fail("Unexpected element", n);
171 static struct zr_serverInfo *serverInfo(NMEM m, xmlNode *node)
174 struct zr_serverInfo *r = nmem_malloc(m, sizeof(*r));
175 memset(r, 0, sizeof(*r));
177 r->protocol = attrtostr(m, node, "protocol");
178 r->version = attrtostr(m, node, "version");
179 r->transport = attrtostr(m, node, "transport");
180 r->method = attrtostr(m, node, "method");
181 for (n = node->children; n; n = n->next)
183 if (n->type != XML_ELEMENT_NODE)
185 if (!strcmp((const char *) n->name, "host"))
186 r->host = valuetostr(m, n);
187 else if (!strcmp((const char *) n->name, "port"))
188 r->port = valuetoint(n);
189 else if (!strcmp((const char *) n->name, "database"))
190 r->database = valuetostr(m, n);
191 else if (!strcmp((const char *) n->name, "authentication"))
193 if (!(r->authentication = authentication(m, n)))
198 fail("Unexpected element", n);
205 static struct zr_agent *agent(NMEM m, xmlNode *node)
207 struct zr_agent *r = nmem_malloc(m, sizeof(*r));
208 memset(r, 0, sizeof(*r));
209 r->type = attrtostr(m, node, "type");
210 r->identifier = attrtostr(m, node, "identifier");
211 r->value = valuetostr(m, node);
215 static struct zr_implementation *implementation(NMEM m, xmlNode *node)
218 struct zr_implementation *r = nmem_malloc(m, sizeof(*r));
219 memset(r, 0, sizeof(*r));
220 r->identifier = attrtostr(m, node, "identifier");
221 r->version = attrtostr(m, node, "version");
222 r->title = findlangstr(m, node, "title");
223 for (n = node->children; n; n = n->next)
225 if (n->type != XML_ELEMENT_NODE)
227 if (!strcmp((const char *) n->name, "agent"))
229 struct zr_agent *ag = agent(m, node);
232 ag->next = r->agents;
239 struct zr_databaseInfo *databaseInfo(NMEM m, xmlNode *node)
242 struct zr_databaseInfo *r = nmem_malloc(m, sizeof(*r));
243 memset(r, 0, sizeof(*r));
245 r->title = findlangstr(m, node, "title");
246 r->description = findlangstr(m, node, "description");
247 r->history = findlangstr(m, node, "history");
248 r->extent = findlangstr(m, node, "extent");
249 r->restrictions = findlangstr(m, node, "restrictions");
250 r->langUsage = findlangstr(m, node, "langUsage");
252 for (n = node->children; n; n = n->next)
254 if (n->type != XML_ELEMENT_NODE)
256 if (!strcmp((const char *) n->name, "agents"))
259 for (n2 = n->children; n2; n2 = n2->next)
261 if (n2->type != XML_ELEMENT_NODE)
263 if (strcmp((const char *) n2->name, "agent"))
267 struct zr_agent *ag = agent(m, n2);
270 ag->next = r->agents;
275 else if (!strcmp((const char *) n->name, "implementation"))
277 if (!(r->implementation = implementation(m, n)))
280 else if (!strcmp((const char *) n->name, "links"))
283 for (n2 = n->children; n2; n2 = n2->next)
285 if (n2->type != XML_ELEMENT_NODE)
287 if (!strcmp((const char *) n2->name, "link"))
291 struct zr_link *li = nmem_malloc(m, sizeof(*li));
292 memset(li, 0, sizeof(*li));
293 li->type = attrtostr(m, n2, "type");
294 li->value = valuetostr(m, n2);
300 else if (!strcmp((const char *) n->name, "history") && !r->lastUpdate)
301 r->lastUpdate = attrtostr(m, n, "lastUpdate");
302 else if (!strcmp((const char *) n->name, "extent") && !r->numberOfRecords)
303 r->numberOfRecords = attrtoint(n, "numberOfRecords");
304 else if (!strcmp((const char *) n->name, "langUsage") && !r->codes)
305 r->codes = attrtostr(m, n, "codes");
310 struct zr_metaInfo *metaInfo(NMEM m, xmlNode *node)
313 struct zr_metaInfo *r = nmem_malloc(m, sizeof(*r));
314 memset(r, 0, sizeof(*r));
316 for (n = node->children; n; n = n->next)
318 if (n->type != XML_ELEMENT_NODE)
320 if (!strcmp((const char *) n->name, "dateModified"))
321 r->dateModified = valuetostr(m, n);
322 else if (!strcmp((const char *) n->name, "dateAggregated"))
323 r->dateAggregated = valuetostr(m, n);
324 else if (!strcmp((const char *) n->name, "aggregatedFrom"))
325 r->aggregatedFrom = valuetostr(m, n);
328 fail("Unexpected element", n);
335 struct zr_set *set(NMEM m, xmlNode *node)
337 struct zr_set *r = nmem_malloc(m, sizeof(*r));
338 memset(r, 0, sizeof(*r));
339 r->name = attrtostr(m, node, "name");
340 r->identifier = attrtostr(m, node, "identifier");
341 r->title = findlangstr(m, node, "title");
345 struct zr_attr *attr(NMEM m, xmlNode *node)
347 struct zr_attr *r = nmem_malloc(m, sizeof(*r));
348 memset(r, 0, sizeof(*r));
349 r->type = attrtoint(node, "type");
350 r->set = attrtostr(m, node, "set");
354 static struct zr_map *map(NMEM m, xmlNode *node)
357 struct zr_map *r = nmem_malloc(m, sizeof(*r));
358 memset(r, 0, sizeof(*r));
360 r->lang = attrtostr(m, node, "lang");
361 r->primary = attrtobool(node, "primary");
362 for (n = node->children; n; n = n->next)
364 if (n->type != XML_ELEMENT_NODE)
366 if (!strcmp((const char *) n->name, "name"))
368 r->set = attrtostr(m, n, "set");
369 r->name = valuetostr(m, n);
371 else if (!strcmp((const char *) n->name, "attr"))
373 struct zr_attr *new = attr(m, n);
376 new->next = r->attrs;
381 fail("Unexpected element", n);
388 static Zr_setting *findsetting(NMEM m, xmlNode *node, char *name)
390 static Zr_setting *r = 0;
392 for (n = node->children; n; n = n->next)
394 if (node->type == XML_ELEMENT_NODE && !strcmp((const char *) n->name, name))
397 struct zr_setting *new = nmem_malloc(m, sizeof(*new));
398 memset(new, 0, sizeof(*new));
399 new->type = attrtostr(m, n, "type");
400 for (n2 = n->children; n2; n2 = n2->next)
402 if (n2->type == XML_ELEMENT_NODE && !strcmp((const char *) n2->name, "map"))
404 new->map = map(m, n2);
411 new->value = (char *) xmlNodeGetContent(n);
419 static struct zr_configInfo *configInfo(NMEM m, xmlNode *node)
421 struct zr_configInfo *r = nmem_malloc(m, sizeof(*r));
423 r->defaultv = findsetting(m, node, "default");
424 r->setting = findsetting(m, node, "setting");
425 r->supports = findsetting(m, node, "supports");
429 static struct zr_index *parse_index(NMEM m, xmlNode *node)
432 struct zr_index *r = nmem_malloc(m, sizeof(*r));
433 memset(r, 0, sizeof(*r));
435 r->search = attrtobool(node, "search");
436 r->scan = attrtobool(node, "scan");
437 r->sort = attrtobool(node, "sort");
438 r->id = attrtostr(m, node, "id");
439 r->title = findlangstr(m, node, "title");
441 for (n = node->children; n; n = n->next)
443 if (n->type != XML_ELEMENT_NODE)
445 if (!strcmp((const char *) n->name, "map"))
447 struct zr_map *new = map(m, n);
453 else if (!strcmp((const char *) n->name, "configInfo"))
455 if (!(r->configInfo = configInfo(m, n)))
458 else if (strcmp((const char *) n->name, "title"))
460 fail("Unknown child element", n);
467 static struct zr_sortKeyword *sortKeyword(NMEM m, xmlNode *node)
469 struct zr_sortKeyword *r = nmem_malloc(m, sizeof(*r));
470 memset(r, 0, sizeof(*r));
471 r->value = valuetostr(m, node);
475 static struct zr_indexInfo *indexInfo(NMEM m , xmlNode *node)
478 struct zr_indexInfo *r = nmem_malloc(m, sizeof(*r));
479 memset(r, 0, sizeof(*r));
481 for (n = node->children; n; n = n->next)
483 if (n->type != XML_ELEMENT_NODE)
485 if (!strcmp((const char *) n->name, "set"))
487 struct zr_set *new = set(m, n);
493 else if (!strcmp((const char *) n->name, "index"))
495 struct zr_index *new = parse_index(m, n);
498 new->next = r->indexes;
501 else if (!strcmp((const char *) n->name, "sortKeyword"))
503 struct zr_sortKeyword *new = sortKeyword(m, n);
506 new->next = r->sortKeywords;
507 r->sortKeywords = new;
509 else if (!strcmp((const char *) n->name, "sortKeyword"))
511 if (!(r->configInfo = configInfo(m, n)))
516 fail("Unknown child element", n);
523 static struct zr_elementSet *elementSet(NMEM m, xmlNode *node)
525 struct zr_elementSet *r = nmem_malloc(m, sizeof(*r));
526 memset(r, 0, sizeof(*r));
527 r->name = attrtostr(m, node, "name");
528 r->identifier = attrtostr(m, node, "identifier");
529 r->title = findlangstr(m, node, "title");
533 static struct zr_recordSyntax *recordSyntax(NMEM m, xmlNode *node)
536 struct zr_recordSyntax *r = nmem_malloc(m, sizeof(*r));
537 struct zr_elementSet **elementp = &r->elementSets;
539 memset(r, 0, sizeof(*r));
540 r->name = attrtostr(m, node, "name");
541 r->identifier = attrtostr(m, node, "identifier");
542 for (n = node->children; n; n = n->next)
544 if (n->type != XML_ELEMENT_NODE)
546 if (!strcmp((const char *) n->name, "elementSet"))
548 if (!(*elementp = elementSet(m, n)))
550 elementp = &(*elementp)->next;
554 fail("Unknown child element", n);
561 static struct zr_recordInfo *recordInfo(NMEM m, xmlNode *node)
564 struct zr_recordInfo *r = nmem_malloc(m, sizeof(*r));
565 struct zr_recordSyntax **syntaxp = &r->recordSyntaxes;
567 memset(r, 0, sizeof(*r));
568 for (n = node->children; n; n = n->next)
570 if (n->type != XML_ELEMENT_NODE)
572 if (!strcmp((const char *) n->name, "recordSyntax"))
574 if (!(*syntaxp = recordSyntax(m, n)))
576 syntaxp = &(*syntaxp)->next;
580 fail("Unknown child element", n);
588 static struct zr_schema *schema(NMEM m, xmlNode *node)
590 struct zr_schema *r = nmem_malloc(m, sizeof(*r));
591 memset(r, 0, sizeof(*r));
593 r->name = attrtostr(m, node, "name");
594 r->identifier = attrtostr(m, node, "identifier");
595 r->retrieve = attrtobool(node, "retrieve");
596 r->sort = attrtobool(node, "sort");
597 r->location = attrtostr(m, node, "location");
598 r->title = findlangstr(m, node, "title");
602 static struct zr_schemaInfo *schemaInfo(NMEM m, xmlNode *node)
605 struct zr_schemaInfo *r = nmem_malloc(m, sizeof(*r));
606 struct zr_schema **schemap = &r->schemas;
608 memset(r, 0, sizeof(*r));
609 for (n = node->children; n; n = n->next)
611 if (n->type != XML_ELEMENT_NODE)
613 if (!strcmp((const char *) n->name, "schema"))
615 if (!(*schemap = schema(m, n)))
617 schemap = &(*schemap)->next;
621 fail("Unknown child element", n);
628 static struct zr_explain *explain(NMEM m, xmlNode *node)
631 struct zr_explain *r = nmem_malloc(m, sizeof(*r));
632 memset(r, 0, sizeof(*r));
634 for (n = node->children; n; n = n->next)
636 if (n->type != XML_ELEMENT_NODE)
638 if (!strcmp((const char *) n->name, "serverInfo"))
640 if (!(r->serverInfo = serverInfo(m, n)))
643 else if (!strcmp((const char *) n->name, "databaseInfo"))
645 if (!(r->databaseInfo = databaseInfo(m, n)))
648 else if (!strcmp((const char *) n->name, "metaInfo"))
650 if (!(r->metaInfo = metaInfo(m, n)))
653 else if (!strcmp((const char *) n->name, "indexInfo"))
655 if (!(r->indexInfo = indexInfo(m, n)))
658 else if (!strcmp((const char *) n->name, "recordInfo"))
660 if (!(r->recordInfo = recordInfo(m, n)))
663 else if (!strcmp((const char *) n->name, "schemaInfo"))
665 if (!(r->schemaInfo = schemaInfo(m, n)))
668 else if (!strcmp((const char *) n->name, "configInfo"))
670 if (!(r->configInfo = configInfo(m, n)))
673 else if (!strcmp((const char *) n->name, "status"))
677 fail("Unknown child element of root node", n);
684 struct zr_explain *zr_read_xml(NMEM m, xmlNode *n)
686 return explain(m, n);
689 struct zr_explain *zr_read_file(NMEM m, const char *fn)
691 xmlDoc *doc = xmlParseFile(fn);
692 struct zr_explain *r;
695 yaz_log(YLOG_WARN|YLOG_ERRNO, "Unable to open %s", fn);
698 r = explain(m, xmlDocGetRootElement(doc));
706 * indent-tabs-mode: nil
708 * vim: shiftwidth=4 tabstop=8 expandtab