1 /* This file is part of Pazpar2.
2 Copyright (C) 2006-2009 Index Data
4 Pazpar2 is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 // Reads Zeerex records into a set of structures
24 #include <yaz/yaz-util.h>
26 #include <libxml/parser.h>
27 #include <libxml/tree.h>
31 // Replace this with something that will take a callback
32 static void fail(const char *s, xmlNode *n)
34 yaz_log(YLOG_WARN, "Zeerex Err '%s'; elem '%s/%s'",
35 s, n->parent->name, n->name);
38 // returns an nmem-allocated string if attr is present, or null
39 static char *attrtostr(NMEM m, xmlNode *n, const char *name)
41 char *s = (char *) xmlGetProp(n, (xmlChar *) name);
44 char *r = nmem_strdup(m, s);
52 static int attrtoint(xmlNode *n, const char *name)
54 char *s = (char *)xmlGetProp(n, (xmlChar *) name);
65 static Zr_bool attrtobool(xmlNode *node, const char *name)
67 char *v = (char *) xmlGetProp(node, (xmlChar *) name);
71 if (!strcmp(v, "true"))
73 else if (!strcmp(v, "false"))
76 res = Zr_bool_unknown;
81 return Zr_bool_unknown;
84 static char *valuetostr(NMEM m, xmlNode *n)
86 char *val = (char *) xmlNodeGetContent(n);
89 char *res = nmem_strdup(m, val);
97 static int valuetoint(xmlNode *n)
99 char *s = (char *) xmlNodeGetContent(n);
110 static Zr_langstr *findlangstr(NMEM m, xmlNode *node, const char *name)
114 for (n = node->children; n; n = n->next)
116 if (n->type == XML_ELEMENT_NODE
117 && !strcmp((const char *) n->name, name))
119 Zr_langstr *new = nmem_malloc(m, sizeof(*new));
120 memset(new, 0, sizeof(*new));
121 new->primary = attrtobool(n, "primary");
122 new->lang = attrtostr(m, n, "lang");
123 new->str = valuetostr(m, n);
131 const char *zr_langstr(Zr_langstr *s, const char *lang)
134 for (p = s; p; p = p->next)
135 if ((!lang && p->primary == Zr_bool_true) ||
136 (lang && p->lang && !strcmp(lang, p->lang)))
141 static struct zr_authentication *authentication(NMEM m, xmlNode *node)
144 struct zr_authentication *r = nmem_malloc(m, sizeof(*r));
145 memset(r, 0, sizeof(*r));
146 r->type = attrtostr(m, node, "type");
147 for (n = node->children; n; n = n->next)
149 if (n->type != XML_ELEMENT_NODE)
151 if (!strcmp((const char *) n->name, "open"))
152 r->open = valuetostr(m, n);
153 else if (!strcmp((const char *) n->name, "user"))
154 r->user = valuetostr(m, n);
155 else if (!strcmp((const char *) n->name, "group"))
156 r->group = valuetostr(m, n);
157 else if (!strcmp((const char *) n->name, "password"))
158 r->password = valuetostr(m, n);
161 fail("Unexpected element", n);
169 static struct zr_serverInfo *serverInfo(NMEM m, xmlNode *node)
172 struct zr_serverInfo *r = nmem_malloc(m, sizeof(*r));
173 memset(r, 0, sizeof(*r));
175 r->protocol = attrtostr(m, node, "protocol");
176 r->version = attrtostr(m, node, "version");
177 r->transport = attrtostr(m, node, "transport");
178 r->method = attrtostr(m, node, "method");
179 for (n = node->children; n; n = n->next)
181 if (n->type != XML_ELEMENT_NODE)
183 if (!strcmp((const char *) n->name, "host"))
184 r->host = valuetostr(m, n);
185 else if (!strcmp((const char *) n->name, "port"))
186 r->port = valuetoint(n);
187 else if (!strcmp((const char *) n->name, "database"))
188 r->database = valuetostr(m, n);
189 else if (!strcmp((const char *) n->name, "authentication"))
191 if (!(r->authentication = authentication(m, n)))
196 fail("Unexpected element", n);
203 static struct zr_agent *agent(NMEM m, xmlNode *node)
205 struct zr_agent *r = nmem_malloc(m, sizeof(*r));
206 memset(r, 0, sizeof(*r));
207 r->type = attrtostr(m, node, "type");
208 r->identifier = attrtostr(m, node, "identifier");
209 r->value = valuetostr(m, node);
213 static struct zr_implementation *implementation(NMEM m, xmlNode *node)
216 struct zr_implementation *r = nmem_malloc(m, sizeof(*r));
217 memset(r, 0, sizeof(*r));
218 r->identifier = attrtostr(m, node, "identifier");
219 r->version = attrtostr(m, node, "version");
220 r->title = findlangstr(m, node, "title");
221 for (n = node->children; n; n = n->next)
223 if (n->type != XML_ELEMENT_NODE)
225 if (!strcmp((const char *) n->name, "agent"))
227 struct zr_agent *ag = agent(m, node);
230 ag->next = r->agents;
237 struct zr_databaseInfo *databaseInfo(NMEM m, xmlNode *node)
240 struct zr_databaseInfo *r = nmem_malloc(m, sizeof(*r));
241 memset(r, 0, sizeof(*r));
243 r->title = findlangstr(m, node, "title");
244 r->description = findlangstr(m, node, "description");
245 r->history = findlangstr(m, node, "history");
246 r->extent = findlangstr(m, node, "extent");
247 r->restrictions = findlangstr(m, node, "restrictions");
248 r->langUsage = findlangstr(m, node, "langUsage");
250 for (n = node->children; n; n = n->next)
252 if (n->type != XML_ELEMENT_NODE)
254 if (!strcmp((const char *) n->name, "agents"))
257 for (n2 = n->children; n2; n2 = n2->next)
259 if (n2->type != XML_ELEMENT_NODE)
261 if (strcmp((const char *) n2->name, "agent"))
265 struct zr_agent *ag = agent(m, n2);
268 ag->next = r->agents;
273 else if (!strcmp((const char *) n->name, "implementation"))
275 if (!(r->implementation = implementation(m, n)))
278 else if (!strcmp((const char *) n->name, "links"))
281 for (n2 = n->children; n2; n2 = n2->next)
283 if (n2->type != XML_ELEMENT_NODE)
285 if (!strcmp((const char *) n2->name, "link"))
289 struct zr_link *li = nmem_malloc(m, sizeof(*li));
290 memset(li, 0, sizeof(*li));
291 li->type = attrtostr(m, n2, "type");
292 li->value = valuetostr(m, n2);
298 else if (!strcmp((const char *) n->name, "history") && !r->lastUpdate)
299 r->lastUpdate = attrtostr(m, n, "lastUpdate");
300 else if (!strcmp((const char *) n->name, "extent") && !r->numberOfRecords)
301 r->numberOfRecords = attrtoint(n, "numberOfRecords");
302 else if (!strcmp((const char *) n->name, "langUsage") && !r->codes)
303 r->codes = attrtostr(m, n, "codes");
308 struct zr_metaInfo *metaInfo(NMEM m, xmlNode *node)
311 struct zr_metaInfo *r = nmem_malloc(m, sizeof(*r));
312 memset(r, 0, sizeof(*r));
314 for (n = node->children; n; n = n->next)
316 if (n->type != XML_ELEMENT_NODE)
318 if (!strcmp((const char *) n->name, "dateModified"))
319 r->dateModified = valuetostr(m, n);
320 else if (!strcmp((const char *) n->name, "dateAggregated"))
321 r->dateAggregated = valuetostr(m, n);
322 else if (!strcmp((const char *) n->name, "aggregatedFrom"))
323 r->aggregatedFrom = valuetostr(m, n);
326 fail("Unexpected element", n);
333 struct zr_set *set(NMEM m, xmlNode *node)
335 struct zr_set *r = nmem_malloc(m, sizeof(*r));
336 memset(r, 0, sizeof(*r));
337 r->name = attrtostr(m, node, "name");
338 r->identifier = attrtostr(m, node, "identifier");
339 r->title = findlangstr(m, node, "title");
343 struct zr_attr *attr(NMEM m, xmlNode *node)
345 struct zr_attr *r = nmem_malloc(m, sizeof(*r));
346 memset(r, 0, sizeof(*r));
347 r->type = attrtoint(node, "type");
348 r->set = attrtostr(m, node, "set");
352 static struct zr_map *map(NMEM m, xmlNode *node)
355 struct zr_map *r = nmem_malloc(m, sizeof(*r));
356 memset(r, 0, sizeof(*r));
358 r->lang = attrtostr(m, node, "lang");
359 r->primary = attrtobool(node, "primary");
360 for (n = node->children; n; n = n->next)
362 if (n->type != XML_ELEMENT_NODE)
364 if (!strcmp((const char *) n->name, "name"))
366 r->set = attrtostr(m, n, "set");
367 r->name = valuetostr(m, n);
369 else if (!strcmp((const char *) n->name, "attr"))
371 struct zr_attr *new = attr(m, n);
374 new->next = r->attrs;
379 fail("Unexpected element", n);
386 static Zr_setting *findsetting(NMEM m, xmlNode *node, char *name)
388 static Zr_setting *r = 0;
390 for (n = node->children; n; n = n->next)
392 if (node->type == XML_ELEMENT_NODE && !strcmp((const char *) n->name, name))
395 struct zr_setting *new = nmem_malloc(m, sizeof(*new));
396 memset(new, 0, sizeof(*new));
397 new->type = attrtostr(m, n, "type");
398 for (n2 = n->children; n2; n2 = n2->next)
400 if (n2->type == XML_ELEMENT_NODE && !strcmp((const char *) n2->name, "map"))
402 new->map = map(m, n2);
409 new->value = (char *) xmlNodeGetContent(n);
417 static struct zr_configInfo *configInfo(NMEM m, xmlNode *node)
419 struct zr_configInfo *r = nmem_malloc(m, sizeof(*r));
421 r->defaultv = findsetting(m, node, "default");
422 r->setting = findsetting(m, node, "setting");
423 r->supports = findsetting(m, node, "supports");
427 static struct zr_index *parse_index(NMEM m, xmlNode *node)
430 struct zr_index *r = nmem_malloc(m, sizeof(*r));
431 memset(r, 0, sizeof(*r));
433 r->search = attrtobool(node, "search");
434 r->scan = attrtobool(node, "scan");
435 r->sort = attrtobool(node, "sort");
436 r->id = attrtostr(m, node, "id");
437 r->title = findlangstr(m, node, "title");
439 for (n = node->children; n; n = n->next)
441 if (n->type != XML_ELEMENT_NODE)
443 if (!strcmp((const char *) n->name, "map"))
445 struct zr_map *new = map(m, n);
451 else if (!strcmp((const char *) n->name, "configInfo"))
453 if (!(r->configInfo = configInfo(m, n)))
456 else if (strcmp((const char *) n->name, "title"))
458 fail("Unknown child element", n);
465 static struct zr_sortKeyword *sortKeyword(NMEM m, xmlNode *node)
467 struct zr_sortKeyword *r = nmem_malloc(m, sizeof(*r));
468 memset(r, 0, sizeof(*r));
469 r->value = valuetostr(m, node);
473 static struct zr_indexInfo *indexInfo(NMEM m , xmlNode *node)
476 struct zr_indexInfo *r = nmem_malloc(m, sizeof(*r));
477 memset(r, 0, sizeof(*r));
479 for (n = node->children; n; n = n->next)
481 if (n->type != XML_ELEMENT_NODE)
483 if (!strcmp((const char *) n->name, "set"))
485 struct zr_set *new = set(m, n);
491 else if (!strcmp((const char *) n->name, "index"))
493 struct zr_index *new = parse_index(m, n);
496 new->next = r->indexes;
499 else if (!strcmp((const char *) n->name, "sortKeyword"))
501 struct zr_sortKeyword *new = sortKeyword(m, n);
504 new->next = r->sortKeywords;
505 r->sortKeywords = new;
507 else if (!strcmp((const char *) n->name, "sortKeyword"))
509 if (!(r->configInfo = configInfo(m, n)))
514 fail("Unknown child element", n);
521 static struct zr_elementSet *elementSet(NMEM m, xmlNode *node)
523 struct zr_elementSet *r = nmem_malloc(m, sizeof(*r));
524 memset(r, 0, sizeof(*r));
525 r->name = attrtostr(m, node, "name");
526 r->identifier = attrtostr(m, node, "identifier");
527 r->title = findlangstr(m, node, "title");
531 static struct zr_recordSyntax *recordSyntax(NMEM m, xmlNode *node)
534 struct zr_recordSyntax *r = nmem_malloc(m, sizeof(*r));
535 struct zr_elementSet **elementp = &r->elementSets;
537 memset(r, 0, sizeof(*r));
538 r->name = attrtostr(m, node, "name");
539 r->identifier = attrtostr(m, node, "identifier");
540 for (n = node->children; n; n = n->next)
542 if (n->type != XML_ELEMENT_NODE)
544 if (!strcmp((const char *) n->name, "elementSet"))
546 if (!(*elementp = elementSet(m, n)))
548 elementp = &(*elementp)->next;
552 fail("Unknown child element", n);
559 static struct zr_recordInfo *recordInfo(NMEM m, xmlNode *node)
562 struct zr_recordInfo *r = nmem_malloc(m, sizeof(*r));
563 struct zr_recordSyntax **syntaxp = &r->recordSyntaxes;
565 memset(r, 0, sizeof(*r));
566 for (n = node->children; n; n = n->next)
568 if (n->type != XML_ELEMENT_NODE)
570 if (!strcmp((const char *) n->name, "recordSyntax"))
572 if (!(*syntaxp = recordSyntax(m, n)))
574 syntaxp = &(*syntaxp)->next;
578 fail("Unknown child element", n);
586 static struct zr_schema *schema(NMEM m, xmlNode *node)
588 struct zr_schema *r = nmem_malloc(m, sizeof(*r));
589 memset(r, 0, sizeof(*r));
591 r->name = attrtostr(m, node, "name");
592 r->identifier = attrtostr(m, node, "identifier");
593 r->retrieve = attrtobool(node, "retrieve");
594 r->sort = attrtobool(node, "sort");
595 r->location = attrtostr(m, node, "location");
596 r->title = findlangstr(m, node, "title");
600 static struct zr_schemaInfo *schemaInfo(NMEM m, xmlNode *node)
603 struct zr_schemaInfo *r = nmem_malloc(m, sizeof(*r));
604 struct zr_schema **schemap = &r->schemas;
606 memset(r, 0, sizeof(*r));
607 for (n = node->children; n; n = n->next)
609 if (n->type != XML_ELEMENT_NODE)
611 if (!strcmp((const char *) n->name, "schema"))
613 if (!(*schemap = schema(m, n)))
615 schemap = &(*schemap)->next;
619 fail("Unknown child element", n);
626 static struct zr_explain *explain(NMEM m, xmlNode *node)
629 struct zr_explain *r = nmem_malloc(m, sizeof(*r));
630 memset(r, 0, sizeof(*r));
632 for (n = node->children; n; n = n->next)
634 if (n->type != XML_ELEMENT_NODE)
636 if (!strcmp((const char *) n->name, "serverInfo"))
638 if (!(r->serverInfo = serverInfo(m, n)))
641 else if (!strcmp((const char *) n->name, "databaseInfo"))
643 if (!(r->databaseInfo = databaseInfo(m, n)))
646 else if (!strcmp((const char *) n->name, "metaInfo"))
648 if (!(r->metaInfo = metaInfo(m, n)))
651 else if (!strcmp((const char *) n->name, "indexInfo"))
653 if (!(r->indexInfo = indexInfo(m, n)))
656 else if (!strcmp((const char *) n->name, "recordInfo"))
658 if (!(r->recordInfo = recordInfo(m, n)))
661 else if (!strcmp((const char *) n->name, "schemaInfo"))
663 if (!(r->schemaInfo = schemaInfo(m, n)))
666 else if (!strcmp((const char *) n->name, "configInfo"))
668 if (!(r->configInfo = configInfo(m, n)))
671 else if (!strcmp((const char *) n->name, "status"))
675 fail("Unknown child element of root node", n);
682 struct zr_explain *zr_read_xml(NMEM m, xmlNode *n)
684 return explain(m, n);
687 struct zr_explain *zr_read_file(NMEM m, const char *fn)
689 xmlDoc *doc = xmlParseFile(fn);
690 struct zr_explain *r;
693 yaz_log(YLOG_WARN|YLOG_ERRNO, "Unable to open %s", fn);
696 r = explain(m, xmlDocGetRootElement(doc));
704 * indent-tabs-mode: nil
706 * vim: shiftwidth=4 tabstop=8 expandtab