YAZ 5.37.0
xmlquery.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
8#if HAVE_CONFIG_H
9#include <config.h>
10#endif
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <assert.h>
16
17#if YAZ_HAVE_XML2
18#include <libxml/parser.h>
19#include <libxml/tree.h>
20
21#include <yaz/logrpn.h>
22#include <yaz/xmlquery.h>
23#include <yaz/nmem_xml.h>
24#include <yaz/xml_get.h>
25#include <yaz/oid_db.h>
26#include <yaz/snprintf.h>
27
28static int check_diagnostic(const xmlNode *ptr, ODR odr,
29 int *error_code, const char **addinfo)
30{
31 if (ptr && ptr->type == XML_ELEMENT_NODE &&
32 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
33 {
34 struct _xmlAttr *attr;
35 const char *code_str = 0;
36 const char *addinfo_str = 0;
37 for (attr = ptr->properties; attr; attr = attr->next)
38 {
39 if (!xmlStrcmp(attr->name, BAD_CAST "code") &&
40 attr->children && attr->children->type == XML_TEXT_NODE)
41 code_str = (const char *) attr->children->content;
42 else if (!xmlStrcmp(attr->name, BAD_CAST "addinfo") &&
43 attr->children && attr->children->type == XML_TEXT_NODE)
44 addinfo_str = (const char *) attr->children->content;
45 else
46 {
47 *error_code = 1;
48 *addinfo = "bad attribute for diagnostic element";
49 return 1;
50 }
51 }
52 if (!code_str)
53 {
54 *error_code = 1;
55 *addinfo = "missing @code for diagnostic element";
56 return 1;
57 }
58 *error_code = atoi(code_str);
59 if (addinfo_str)
60 *addinfo = odr_strdup(odr, addinfo_str);
61 return 1;
62 }
63 else
64 return 0;
65}
66
68 xmlNodePtr parent)
69{
70 char formstr[30];
71 const char *setname = 0;
72 char oid_name_str[OID_STR_MAX];
73
74 if (element->attributeSet)
75 {
76 setname = yaz_oid_to_string_buf(element->attributeSet,
77 0, oid_name_str);
78 }
79
80 if (element->which == Z_AttributeValue_numeric)
81 {
82 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
83
84 if (setname)
85 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
86
87 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *element->attributeType);
88 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
89
90 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *element->value.numeric);
91 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
92 }
93 else if (element->which == Z_AttributeValue_complex)
94 {
95 int i;
96 for (i = 0; i<element->value.complex->num_list; i++)
97 {
98 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
99
100 if (setname)
101 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
102
103 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *element->attributeType);
104 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
105
106 if (element->value.complex->list[i]->which ==
108 {
109 xmlNewProp(node, BAD_CAST "value", BAD_CAST
110 element->value.complex->list[i]->u.string);
111 }
112 else if (element->value.complex->list[i]->which ==
114 {
115 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF,
116 *element->value.complex->list[i]->u.numeric);
117 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
118 }
119 }
120 }
121}
122
123
124static xmlNodePtr yaz_query2xml_term(const Z_Term *term, xmlNodePtr parent)
125{
126 xmlNodePtr t = 0;
127 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "term", 0);
128 char formstr[20];
129 const char *type = 0;
130
131 switch (term->which)
132 {
133 case Z_Term_general:
134 type = "general";
135 t = xmlNewTextLen(BAD_CAST term->u.general->buf, term->u.general->len);
136 break;
137 case Z_Term_numeric:
138 type = "numeric";
139 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *term->u.numeric);
140 t = xmlNewText(BAD_CAST formstr);
141 break;
143 type = "string";
144 t = xmlNewText(BAD_CAST term->u.characterString);
145 break;
146 case Z_Term_oid:
147 type = "oid";
148 break;
149 case Z_Term_dateTime:
150 type = "dateTime";
151 break;
152 case Z_Term_external:
153 type = "external";
154 break;
156 type ="integerAndUnit";
157 break;
158 case Z_Term_null:
159 type = "null";
160 break;
161 default:
162 break;
163 }
164 if (t) /* got a term node ? */
165 xmlAddChild(node, t);
166 if (type)
167 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
168 return node;
169}
170
171static xmlNodePtr yaz_query2xml_apt(const Z_AttributesPlusTerm *zapt,
172 xmlNodePtr parent)
173{
174 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "apt", 0);
175 int num_attributes = zapt->attributes->num_attributes;
176 int i;
177 for (i = 0; i<num_attributes; i++)
179 yaz_query2xml_term(zapt->term, node);
180
181 return node;
182}
183
184
185static void yaz_query2xml_operator(Z_Operator *op, xmlNodePtr node)
186{
187 const char *type = 0;
188 switch(op->which)
189 {
190 case Z_Operator_and:
191 type = "and";
192 break;
193 case Z_Operator_or:
194 type = "or";
195 break;
197 type = "not";
198 break;
199 case Z_Operator_prox:
200 type = "prox";
201 break;
202 default:
203 return;
204 }
205 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
206
207 if (op->which == Z_Operator_prox)
208 {
209 char formstr[30];
210
211 if (op->u.prox->exclusion)
212 {
213 if (*op->u.prox->exclusion)
214 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "true");
215 else
216 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "false");
217 }
218 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *op->u.prox->distance);
219 xmlNewProp(node, BAD_CAST "distance", BAD_CAST formstr);
220
221 if (*op->u.prox->ordered)
222 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "true");
223 else
224 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "false");
225
226 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *op->u.prox->relationType);
227 xmlNewProp(node, BAD_CAST "relationType", BAD_CAST formstr);
228
229 switch(op->u.prox->which)
230 {
232 yaz_snprintf(formstr, sizeof formstr, ODR_INT_PRINTF, *op->u.prox->u.known);
233 xmlNewProp(node, BAD_CAST "knownProximityUnit",
234 BAD_CAST formstr);
235 break;
237 default:
238 xmlNewProp(node, BAD_CAST "privateProximityUnit",
239 BAD_CAST "private");
240 break;
241 }
242 }
243}
244
245static xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
246 xmlNodePtr parent)
247{
248 if (zs->which == Z_RPNStructure_complex)
249 {
250 Z_Complex *zc = zs->u.complex;
251
252 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "operator", 0);
253 if (zc->roperator)
257 return node;
258 }
259 else if (zs->which == Z_RPNStructure_simple)
260 {
261 if (zs->u.simple->which == Z_Operand_APT)
263 parent);
264 else if (zs->u.simple->which == Z_Operand_resultSetId)
265 return xmlNewChild(parent, /* NS */ 0, BAD_CAST "rset",
266 BAD_CAST zs->u.simple->u.resultSetId);
267 }
268 return 0;
269}
270
271static xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
272{
273 if (rpn->attributeSetId)
274 {
275 char oid_name_str[OID_STR_MAX];
276 const char *setname = yaz_oid_to_string_buf(rpn->attributeSetId,
277 0, oid_name_str);
278 if (setname)
279 xmlNewProp(parent, BAD_CAST "set", BAD_CAST setname);
280 }
281 return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
282}
283
284static xmlNodePtr yaz_query2xml_ccl(const Odr_oct *ccl, xmlNodePtr node)
285{
286 return 0;
287}
288
289static xmlNodePtr yaz_query2xml_z3958(const Odr_oct *ccl, xmlNodePtr node)
290{
291 return 0;
292}
293
294static xmlNodePtr yaz_query2xml_cql(const char *cql, xmlNodePtr node)
295{
296 return 0;
297}
298
299void yaz_rpnquery2xml(const Z_RPNQuery *rpn, xmlDocPtr *docp)
300{
301 Z_Query query;
302
303 query.which = Z_Query_type_1;
304 query.u.type_1 = (Z_RPNQuery *) rpn;
305 yaz_query2xml(&query, docp);
306}
307
308void yaz_query2xml(const Z_Query *q, xmlDocPtr *docp)
309{
310 xmlNodePtr top_node, q_node = 0, child_node = 0;
311
312 assert(q);
313 assert(docp);
314
315 top_node = xmlNewNode(0, BAD_CAST "query");
316
317 switch (q->which)
318 {
319 case Z_Query_type_1:
320 case Z_Query_type_101:
321 q_node = xmlNewChild(top_node, 0, BAD_CAST "rpn", 0);
322 child_node = yaz_query2xml_rpn(q->u.type_1, q_node);
323 break;
324 case Z_Query_type_2:
325 q_node = xmlNewChild(top_node, 0, BAD_CAST "ccl", 0);
326 child_node = yaz_query2xml_ccl(q->u.type_2, q_node);
327 break;
328 case Z_Query_type_100:
329 q_node = xmlNewChild(top_node, 0, BAD_CAST "z39.58", 0);
330 child_node = yaz_query2xml_z3958(q->u.type_100, q_node);
331 break;
332 case Z_Query_type_104:
333 if (q->u.type_104->which == Z_External_CQL)
334 {
335 q_node = xmlNewChild(top_node, 0, BAD_CAST "cql", 0);
336 child_node = yaz_query2xml_cql(q->u.type_104->u.cql, q_node);
337 }
338 }
339 if (child_node && q_node)
340 {
341 *docp = xmlNewDoc(BAD_CAST "1.0");
342 xmlDocSetRootElement(*docp, top_node); /* make it top node in doc */
343 }
344 else
345 {
346 *docp = 0;
347 xmlFreeNode(top_node);
348 }
349}
350
351static bool_t *boolVal(ODR odr, const char *str)
352{
353 if (*str == '\0' || strchr("0fF", *str))
354 return odr_booldup(odr, 0);
355 return odr_booldup(odr, 1);
356}
357
358static Odr_int *intVal(ODR odr, const char *str)
359{
360 return odr_intdup(odr, atoi(str));
361}
362
363static void yaz_xml2query_operator(const xmlNode *ptr, Z_Operator **op,
364 ODR odr,
365 int *error_code, const char **addinfo)
366{
367 const char *type = yaz_xml_get_prop((xmlNodePtr) ptr, "type");
368 if (!type)
369 {
370 *error_code = 1;
371 *addinfo = "no operator type";
372 return;
373 }
374 *op = (Z_Operator*) odr_malloc(odr, sizeof(Z_Operator));
375 if (!strcmp(type, "and"))
376 {
377 (*op)->which = Z_Operator_and;
378 (*op)->u.op_and = odr_nullval();
379 }
380 else if (!strcmp(type, "or"))
381 {
382 (*op)->which = Z_Operator_or;
383 (*op)->u.op_or = odr_nullval();
384 }
385 else if (!strcmp(type, "not"))
386 {
387 (*op)->which = Z_Operator_and_not;
388 (*op)->u.and_not = odr_nullval();
389 }
390 else if (!strcmp(type, "prox"))
391 {
392 struct _xmlAttr *attr;
394 odr_malloc(odr, sizeof(*pop));
395 (*op)->which = Z_Operator_prox;
396 (*op)->u.prox = pop;
397 /* default values */
398 pop->exclusion = 0;
399 pop->ordered = odr_booldup(odr, 1);
400 pop->relationType =
404 pop->distance = odr_intdup(odr, 1);
405
406 for (attr = ptr->properties; attr; attr = attr->next)
407 {
408 const char *value = (const char *) attr->children->content;
409 if (!xmlStrcmp(attr->name, BAD_CAST "type"))
410 ;
411 else if (!xmlStrcmp(attr->name, BAD_CAST "exclusion"))
412 pop->exclusion = boolVal(odr, value);
413 else if (!xmlStrcmp(attr->name, BAD_CAST "distance"))
414 pop->distance = intVal(odr, value);
415 else if (!xmlStrcmp(attr->name, BAD_CAST "ordered"))
416 pop->ordered = boolVal(odr, value);
417 else if (!xmlStrcmp(attr->name, BAD_CAST "relationType"))
418 pop->relationType = intVal(odr, value);
419 else if (!xmlStrcmp(attr->name, BAD_CAST "knownProximityUnit"))
420 {
422 pop->u.known = intVal(odr, value);
423 }
424 else if (!xmlStrcmp(attr->name, BAD_CAST "privateProximityUnit"))
425 {
427 pop->u.known = intVal(odr, value);
428 }
429 else
430 {
431 *error_code = 1;
432 *addinfo = "bad proximity attribute";
433 break;
434 }
435 }
436 }
437 else
438 {
439 *error_code = 1;
440 *addinfo = "bad operator type";
441 }
442}
443
444static void yaz_xml2query_attribute_element(const xmlNode *ptr,
445 Z_AttributeElement **elem, ODR odr,
446 int *error_code,
447 const char **addinfo)
448{
449 int i;
450 xmlChar *set = 0;
451 xmlChar *type = 0;
452 xmlChar *value = 0;
453 int num_values = 0;
454 struct _xmlAttr *attr;
455 for (attr = ptr->properties; attr; attr = attr->next)
456 {
457 if (!xmlStrcmp(attr->name, BAD_CAST "set") &&
458 attr->children && attr->children->type == XML_TEXT_NODE)
459 set = attr->children->content;
460 else if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
461 attr->children && attr->children->type == XML_TEXT_NODE)
462 type = attr->children->content;
463 else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
464 attr->children && attr->children->type == XML_TEXT_NODE)
465 {
466 value = attr->children->content;
467 num_values++;
468 }
469 else
470 {
471 *error_code = 1;
472 *addinfo = "bad attribute for attr content";
473 return;
474 }
475 }
476 if (!type)
477 {
478 *error_code = 1;
479 *addinfo = "missing type attribute for att content";
480 return;
481 }
482 if (!value)
483 {
484 *error_code = 1;
485 *addinfo = "missing value attribute for att content";
486 return;
487 }
488
489 *elem = (Z_AttributeElement *) odr_malloc(odr, sizeof(**elem));
490 if (set)
493 (const char *) set,
494 odr);
495 else
496 (*elem)->attributeSet = 0;
497 (*elem)->attributeType = intVal(odr, (const char *) type);
498
499 /* looks like a number ? */
500 for (i = 0; value[i] && value[i] >= '0' && value[i] <= '9'; i++)
501 ;
502 if (num_values > 1 || value[i])
503 { /* multiple values or string, so turn to complex attribute */
504 (*elem)->which = Z_AttributeValue_complex;
505 (*elem)->value.complex =
507 (*elem)->value.complex->num_list = num_values;
508 (*elem)->value.complex->list = (Z_StringOrNumeric **)
509 odr_malloc(odr, sizeof(Z_StringOrNumeric*) * num_values);
510
511 /* second pass over attr values */
512 i = 0;
513 for (attr = ptr->properties; attr; attr = attr->next)
514 {
515 if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
516 attr->children && attr->children->type == XML_TEXT_NODE)
517 {
518 const char *val = (const char *) attr->children->content;
519 assert (i < num_values);
520 (*elem)->value.complex->list[i] = (Z_StringOrNumeric *)
522 (*elem)->value.complex->list[i]->which =
524 (*elem)->value.complex->list[i]->u.string =
525 odr_strdup(odr, val);
526 i++;
527 }
528 }
529 (*elem)->value.complex->num_semanticAction = 0;
530 (*elem)->value.complex->semanticAction = 0;
531 }
532 else
533 { /* good'ld numeric value */
534 (*elem)->which = Z_AttributeValue_numeric;
535 (*elem)->value.numeric = intVal(odr, (const char *) value);
536 }
537}
538
539static char *strVal(const xmlNode *ptr_cdata, ODR odr)
540{
541 return nmem_text_node_cdata(ptr_cdata, odr_getmem(odr));
542}
543
544static void yaz_xml2query_term(const xmlNode *ptr, Z_Term **term, ODR odr,
545 int *error_code, const char **addinfo)
546{
547 xmlChar *type = 0;
548 struct _xmlAttr *attr;
549 char *cdata = strVal(ptr->children, odr);
550
551 for (attr = ptr->properties; attr; attr = attr->next)
552 {
553 if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
554 attr->children && attr->children->type == XML_TEXT_NODE)
555 type = attr->children->content;
556 else
557 {
558 *error_code = 1;
559 *addinfo = "bad attribute for attr content";
560 return;
561 }
562 }
563 *term = (Z_Term *) odr_malloc(odr, sizeof(Z_Term));
564
565 if (!type || !xmlStrcmp(type, BAD_CAST "general"))
566 {
567 (*term)->which = Z_Term_general;
568 (*term)->u.general =
569 odr_create_Odr_oct(odr, cdata, strlen(cdata));
570 }
571 else if (!xmlStrcmp(type, BAD_CAST "numeric"))
572 {
573 (*term)->which = Z_Term_numeric;
574 (*term)->u.numeric = intVal(odr, cdata);
575 }
576 else if (!xmlStrcmp(type, BAD_CAST "string"))
577 {
578 (*term)->which = Z_Term_characterString;
579 (*term)->u.characterString = cdata;
580 }
581 else if (!xmlStrcmp(type, BAD_CAST "oid"))
582 {
583 *error_code = 1;
584 *addinfo = "unhandled term type: oid";
585 }
586 else if (!xmlStrcmp(type, BAD_CAST "dateTime"))
587 {
588 *error_code = 1;
589 *addinfo = "unhandled term type: dateTime";
590 }
591 else if (!xmlStrcmp(type, BAD_CAST "integerAndUnit"))
592 {
593 *error_code = 1;
594 *addinfo = "unhandled term type: integerAndUnit";
595 }
596 else if (!xmlStrcmp(type, BAD_CAST "null"))
597 {
598 (*term)->which = Z_Term_null;
599 (*term)->u.null = odr_nullval();
600 }
601 else
602 {
603 *error_code = 1;
604 *addinfo = "unhandled term type";
605 }
606}
607
608static void yaz_xml2query_apt(const xmlNode *ptr_apt,
610 int *error_code, const char **addinfo)
611{
612 const xmlNode *ptr = ptr_apt->children;
613 int i, num_attr = 0;
614
615 *zapt = (Z_AttributesPlusTerm *)
617
618 /* deal with attributes */
619 (*zapt)->attributes = (Z_AttributeList*)
621
622 /* how many attributes? */
623 for (; ptr; ptr = ptr->next)
624 if (ptr->type == XML_ELEMENT_NODE)
625 {
626 if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
627 num_attr++;
628 else
629 break;
630 }
631
632 /* allocate and parse for real */
633 (*zapt)->attributes->num_attributes = num_attr;
634 (*zapt)->attributes->attributes = (Z_AttributeElement **)
635 odr_malloc(odr, sizeof(Z_AttributeElement*) * num_attr);
636
637 i = 0;
638 ptr = ptr_apt->children;
639 for (; ptr; ptr = ptr->next)
640 if (ptr->type == XML_ELEMENT_NODE)
641 {
642 if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
643 {
645 ptr, &(*zapt)->attributes->attributes[i], odr,
646 error_code, addinfo);
647 i++;
648 }
649 else
650 break;
651 }
652 if (check_diagnostic(ptr, odr, error_code, addinfo))
653 return;
654
655 if (ptr && ptr->type == XML_ELEMENT_NODE)
656 {
657 if (!xmlStrcmp(ptr->name, BAD_CAST "term"))
658 {
659 /* deal with term */
660 yaz_xml2query_term(ptr, &(*zapt)->term, odr, error_code, addinfo);
661 }
662 else
663 {
664 *error_code = 1;
665 *addinfo = "bad element in apt content";
666 }
667 }
668 else
669 {
670 *error_code = 1;
671 *addinfo = "missing term node in apt content";
672 }
673}
674
675static void yaz_xml2query_rset(const xmlNode *ptr, Z_ResultSetId **rset,
676 ODR odr, int *error_code, const char **addinfo)
677{
678 if (ptr->children)
679 {
680 *rset = strVal(ptr->children, odr);
681 }
682 else
683 {
684 *error_code = 1;
685 *addinfo = "missing rset content";
686 }
687}
688
689static void yaz_xml2query_rpnstructure(const xmlNode *ptr, Z_RPNStructure **zs,
690 ODR odr,
691 int *error_code, const char **addinfo)
692{
693 while (ptr && ptr->type != XML_ELEMENT_NODE)
694 ptr = ptr->next;
695
696 if (!ptr || ptr->type != XML_ELEMENT_NODE)
697 {
698 *error_code = 1;
699 *addinfo = "missing rpn operator, rset, apt node";
700 return;
701 }
702 if (check_diagnostic(ptr, odr, error_code, addinfo))
703 return;
704
705 *zs = (Z_RPNStructure *) odr_malloc(odr, sizeof(Z_RPNStructure));
706 if (!xmlStrcmp(ptr->name, BAD_CAST "operator"))
707 {
708 Z_Complex *zc = (Z_Complex *) odr_malloc(odr, sizeof(Z_Complex));
709
710 (*zs)->which = Z_RPNStructure_complex;
711 (*zs)->u.complex = zc;
712
713 yaz_xml2query_operator(ptr, &zc->roperator, odr, error_code, addinfo);
714
715 ptr = ptr->children;
716 while (ptr && ptr->type != XML_ELEMENT_NODE)
717 ptr = ptr->next;
718 yaz_xml2query_rpnstructure(ptr, &zc->s1, odr, error_code, addinfo);
719 if (ptr)
720 ptr = ptr->next;
721 while (ptr && ptr->type != XML_ELEMENT_NODE)
722 ptr = ptr->next;
723 yaz_xml2query_rpnstructure(ptr, &zc->s2, odr, error_code, addinfo);
724 }
725 else
726 {
727 Z_Operand *s = (Z_Operand *) odr_malloc(odr, sizeof(Z_Operand));
729 (*zs)->u.simple = s;
730 if (!xmlStrcmp(ptr->name, BAD_CAST "apt"))
731 {
732 s->which = Z_Operand_APT;
734 odr, error_code, addinfo);
735 }
736 else if (!xmlStrcmp(ptr->name, BAD_CAST "rset"))
737 {
740 odr, error_code, addinfo);
741 }
742 else
743 {
744 *error_code = 1;
745 *addinfo = "bad element: expected binary, apt or rset";
746 }
747 }
748}
749
750static void yaz_xml2query_rpn(const xmlNode *ptr, Z_RPNQuery **query, ODR odr,
751 int *error_code, const char **addinfo)
752{
753 const char *set = yaz_xml_get_prop((xmlNodePtr) ptr, "set");
754
755 *query = (Z_RPNQuery*) odr_malloc(odr, sizeof(Z_RPNQuery));
756 if (set)
757 {
758 (*query)->attributeSetId =
760 CLASS_ATTSET, set, odr);
761 }
762 else
763 (*query)->attributeSetId = 0;
764 yaz_xml2query_rpnstructure(ptr->children, &(*query)->RPNStructure,
765 odr, error_code, addinfo);
766}
767
768static void yaz_xml2query_(const xmlNode *ptr, Z_Query **query, ODR odr,
769 int *error_code, const char **addinfo)
770{
771 if (check_diagnostic(ptr, odr, error_code, addinfo))
772 return;
773 if (ptr && ptr->type == XML_ELEMENT_NODE &&
774 !xmlStrcmp(ptr->name, BAD_CAST "query"))
775 {
776 const char *type;
777 ptr = ptr->children;
778 while (ptr && ptr->type != XML_ELEMENT_NODE)
779 ptr = ptr->next;
780 if (!ptr || ptr->type != XML_ELEMENT_NODE)
781 {
782 *error_code = 1;
783 *addinfo = "missing query content";
784 return;
785 }
786 type = (const char *) ptr->name;
787
788 *query = (Z_Query*) odr_malloc(odr, sizeof(Z_Query));
789 if (!type || !strcmp(type, "rpn"))
790 {
791 (*query)->which = Z_Query_type_1;
792 yaz_xml2query_rpn(ptr, &(*query)->u.type_1, odr,
793 error_code, addinfo);
794 }
795 else if (!strcmp(type, "ccl"))
796 {
797 *error_code = 1;
798 *addinfo = "ccl not supported yet";
799 }
800 else if (!strcmp(type, "z39.58"))
801 {
802 *error_code = 1;
803 *addinfo = "z39.58 not supported yet";
804 }
805 else if (!strcmp(type, "cql"))
806 {
807 *error_code = 1;
808 *addinfo = "cql not supported yet";
809 }
810 else
811 {
812 *error_code = 1;
813 *addinfo = "unsupported query type";
814 }
815 }
816 else
817 {
818 *error_code = 1;
819 *addinfo = "missing query element";
820 }
821}
822
823void yaz_xml2query(const xmlNode *xmlnodep, Z_Query **query, ODR odr,
824 int *error_code, const char **addinfo)
825{
826 yaz_xml2query_(xmlnodep, query, odr, error_code, addinfo);
827}
828
829/* YAZ_HAVE_XML2 */
830#endif
831
832/*
833 * Local variables:
834 * c-basic-offset: 4
835 * c-file-style: "Stroustrup"
836 * indent-tabs-mode: nil
837 * End:
838 * vim: shiftwidth=4 tabstop=8 expandtab
839 */
840
enum l_file_type type
Definition log.c:47
Header for Z39.50 Query Printing.
char * nmem_text_node_cdata(const xmlNode *ptr_cdata, NMEM nmem)
copies TEXT Libxml2 node data to NMEM
Definition nmem_xml.c:19
Header for Nibble Memory functions + Libxml2 specific stuff.
Odr_null * odr_nullval(void)
Definition odr.c:30
#define odr_getmem(o)
Definition odr.h:216
#define ODR_INT_PRINTF
Definition odr.h:49
#define bool_t
Definition odr.h:52
struct odr * ODR
Definition odr.h:121
nmem_int_t Odr_int
Definition odr.h:47
struct odr_oct Odr_oct
Odr_oct * odr_create_Odr_oct(ODR o, const char *buf, int sz)
Definition odr_mem.c:66
Odr_int * odr_intdup(ODR o, Odr_int v)
Definition odr_mem.c:51
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
Odr_bool * odr_booldup(ODR o, Odr_bool v)
Definition odr_mem.c:56
char * odr_strdup(ODR o, const char *str)
Definition odr_mem.c:36
yaz_oid_db_t yaz_oid_std(void)
returns standard OID database
Definition oid_db.c:33
const char * yaz_oid_to_string_buf(const Odr_oid *oid, oid_class *oclass, char *buf)
maps any OID to string (named or dot-notation)
Definition oid_db.c:99
Odr_oid * yaz_string_to_oid_odr(yaz_oid_db_t oid_list, oid_class oclass, const char *name, ODR o)
creates ODR malloc'ed OID from string
Definition oid_db.c:72
Header for OID database.
@ CLASS_ATTSET
Definition oid_db.h:50
#define OID_STR_MAX
Definition oid_util.h:40
#define Z_External_CQL
Definition prt-ext.h:93
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition snprintf.c:31
Header for config file reading utilities.
Odr_int * attributeType
Definition z-core.h:581
Z_ComplexAttribute * complex
Definition z-core.h:585
Z_AttributeSetId * attributeSet
Definition z-core.h:580
Odr_int * numeric
Definition z-core.h:584
union Z_AttributeElement::@260252174261265367116362007076255375270002041323 value
int num_attributes
Definition z-core.h:532
Z_AttributeElement ** attributes
Definition z-core.h:533
Z_AttributeList * attributes
Definition z-core.h:522
Z_StringOrNumeric ** list
Definition z-core.h:574
Z_RPNStructure * s2
Definition z-core.h:495
Z_Operator * roperator
Definition z-core.h:496
Z_RPNStructure * s1
Definition z-core.h:494
union Z_External::@173112132151266201036013025012152147264102163302 u
Z_InternationalString * cql
Definition prt-ext.h:138
int which
Definition prt-ext.h:63
Z_ResultSetId * resultSetId
Definition z-core.h:513
int which
Definition z-core.h:510
Z_AttributesPlusTerm * attributesPlusTerm
Definition z-core.h:512
union Z_Operand::@072322006164213251104156071070134267373322123052 u
int which
Definition z-core.h:559
Z_ProximityOperator * prox
Definition z-core.h:564
union Z_Operator::@171225215357037113014354143242105145344254361002 u
Odr_bool * ordered
Definition z-core.h:594
Odr_int * distance
Definition z-core.h:593
Z_ProxUnit * known
Definition z-core.h:604
Odr_int * relationType
Definition z-core.h:601
Odr_bool * exclusion
Definition z-core.h:592
union Z_ProximityOperator::@031336250334025346341060256205106006053041305237 u
union Z_Query::@270220245041066023256025363242165325012357336235 u
Z_External * type_104
Definition z-core.h:477
Z_RPNQuery * type_1
Definition z-core.h:472
Odr_oct * type_2
Definition z-core.h:473
int which
Definition z-core.h:469
Odr_oct * type_100
Definition z-core.h:474
Z_AttributeSetId * attributeSetId
Definition z-core.h:489
Z_RPNStructure * RPNStructure
Definition z-core.h:490
Z_Complex * complex
Definition z-core.h:503
union Z_RPNStructure::@272042053041255367154306203353273370010236313243 u
Z_Operand * simple
Definition z-core.h:502
union Z_StringOrNumeric::@255321135104110073015132067151226017215302214211 u
Odr_int * numeric
Definition z-core.h:1322
Z_InternationalString * string
Definition z-core.h:1321
union Z_Term::@023217361022206241314262227377164117366363003164 u
Odr_oct * general
Definition z-core.h:539
Z_InternationalString * characterString
Definition z-core.h:541
int which
Definition z-core.h:537
Odr_int * numeric
Definition z-core.h:540
int len
Definition odr.h:102
char * buf
Definition odr.h:101
Definition odr.h:125
const char * yaz_xml_get_prop(const xmlNode *n, const char *fmt,...)
Definition xml_get.c:19
XML node getter/creation utilities.
static bool_t * boolVal(ODR odr, const char *str)
Definition xmlquery.c:351
static void yaz_xml2query_attribute_element(const xmlNode *ptr, Z_AttributeElement **elem, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:444
static int check_diagnostic(const xmlNode *ptr, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:28
void yaz_query2xml(const Z_Query *q, xmlDocPtr *docp)
Definition xmlquery.c:308
static void yaz_xml2query_rset(const xmlNode *ptr, Z_ResultSetId **rset, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:675
static Odr_int * intVal(ODR odr, const char *str)
Definition xmlquery.c:358
static xmlNodePtr yaz_query2xml_ccl(const Odr_oct *ccl, xmlNodePtr node)
Definition xmlquery.c:284
static void yaz_xml2query_rpnstructure(const xmlNode *ptr, Z_RPNStructure **zs, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:689
static void yaz_xml2query_(const xmlNode *ptr, Z_Query **query, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:768
void yaz_rpnquery2xml(const Z_RPNQuery *rpn, xmlDocPtr *docp)
Definition xmlquery.c:299
static char * strVal(const xmlNode *ptr_cdata, ODR odr)
Definition xmlquery.c:539
static void yaz_xml2query_rpn(const xmlNode *ptr, Z_RPNQuery **query, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:750
static void yaz_query2xml_attribute_element(const Z_AttributeElement *element, xmlNodePtr parent)
Definition xmlquery.c:67
static xmlNodePtr yaz_query2xml_term(const Z_Term *term, xmlNodePtr parent)
Definition xmlquery.c:124
static void yaz_query2xml_operator(Z_Operator *op, xmlNodePtr node)
Definition xmlquery.c:185
static xmlNodePtr yaz_query2xml_cql(const char *cql, xmlNodePtr node)
Definition xmlquery.c:294
static xmlNodePtr yaz_query2xml_z3958(const Odr_oct *ccl, xmlNodePtr node)
Definition xmlquery.c:289
static void yaz_xml2query_term(const xmlNode *ptr, Z_Term **term, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:544
static xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs, xmlNodePtr parent)
Definition xmlquery.c:245
static xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
Definition xmlquery.c:271
static xmlNodePtr yaz_query2xml_apt(const Z_AttributesPlusTerm *zapt, xmlNodePtr parent)
Definition xmlquery.c:171
void yaz_xml2query(const xmlNode *xmlnodep, Z_Query **query, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:823
static void yaz_xml2query_apt(const xmlNode *ptr_apt, Z_AttributesPlusTerm **zapt, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:608
static void yaz_xml2query_operator(const xmlNode *ptr, Z_Operator **op, ODR odr, int *error_code, const char **addinfo)
Definition xmlquery.c:363
Query / XML conversions.
#define Z_AttributeValue_numeric
Definition z-core.h:586
#define Z_Operator_and_not
Definition z-core.h:567
#define Z_Operator_or
Definition z-core.h:566
#define Z_Term_characterString
Definition z-core.h:549
#define Z_ProximityOperator_Prox_lessThanOrEqual
Definition z-core.h:596
#define Z_ProximityOperator_private
Definition z-core.h:607
#define Z_StringOrNumeric_numeric
Definition z-core.h:1324
#define Z_Operand_APT
Definition z-core.h:515
#define Z_ProximityOperator_known
Definition z-core.h:606
#define Z_AttributeValue_complex
Definition z-core.h:587
#define Z_Term_dateTime
Definition z-core.h:551
#define Z_Term_general
Definition z-core.h:547
#define Z_StringOrNumeric_string
Definition z-core.h:1323
#define Z_Query_type_1
Definition z-core.h:479
#define Z_Operator_prox
Definition z-core.h:568
#define Z_Query_type_101
Definition z-core.h:482
#define Z_Operand_resultSetId
Definition z-core.h:516
#define Z_RPNStructure_complex
Definition z-core.h:505
#define Z_Operator_and
Definition z-core.h:565
#define Z_Term_numeric
Definition z-core.h:548
Z_InternationalString Z_ResultSetId
Definition z-core.h:304
#define Z_RPNStructure_simple
Definition z-core.h:504
#define Z_Term_integerAndUnit
Definition z-core.h:553
#define Z_Term_null
Definition z-core.h:554
#define Z_Term_oid
Definition z-core.h:550
#define Z_ProxUnit_word
Definition z-core.h:612
#define Z_Term_external
Definition z-core.h:552
#define Z_Query_type_104
Definition z-core.h:484
#define Z_Query_type_100
Definition z-core.h:481
#define Z_Query_type_2
Definition z-core.h:480