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