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