YAZ  5.34.0
srw.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  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <stdlib.h>
14 
15 #include <yaz/srw.h>
16 #include <yaz/wrbuf.h>
17 #include <yaz/nmem_xml.h>
18 #if YAZ_HAVE_XML2
19 #include <libxml/parser.h>
20 #include <libxml/tree.h>
21 #include <assert.h>
22 #include <yaz/facet.h>
23 #include <yaz/proto.h>
24 #include "sru-p.h"
25 
26 char *yaz_negotiate_sru_version(char *input_ver)
27 {
28  if (!input_ver)
29  return "2.0";
30  if (!strcmp(input_ver, "1.1"))
31  return "1.1";
32  if (!strncmp(input_ver, "1.", 2))
33  return "1.2";
34  if (!strncmp(input_ver, "2.", 2))
35  return "2.0";
36  return 0;
37 }
38 
39 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
40  Z_SRW_extra_record **extra,
41  void *client_data, int version2)
42 {
43  if (o->direction == ODR_DECODE)
44  {
46 
47  char *spack = 0;
48  xmlNodePtr ptr;
49 #ifdef Z_SRW_packed
50  rec->packing = 0;
51 #endif
52  rec->recordSchema = 0;
53  rec->recordData_buf = 0;
54  rec->recordData_len = 0;
55  rec->recordPosition = 0;
56  *extra = 0;
57 
58  ex.extraRecordData_buf = 0;
59  ex.extraRecordData_len = 0;
60  ex.recordIdentifier = 0;
61 
62  for (ptr = pptr->children; ptr; ptr = ptr->next)
63  {
64 
65  if (yaz_match_xsd_string(ptr, "recordSchema", o,
66  &rec->recordSchema))
67  ;
68  else if (yaz_match_xsd_string(ptr, "recordPacking", o, &spack))
69  ; /* can't rely on it: in SRU 2.0 it's different semantics */
70  else if (yaz_match_xsd_integer(ptr, "recordPosition", o,
71  &rec->recordPosition))
72  ;
73  else if (yaz_match_xsd_element(ptr, "recordData"))
74  {
75  /* we assume XML packing, if any element nodes exist below
76  recordData. Unfortunately, in SRU 2.0 recordPacking
77  means something different */
78  xmlNode *p = ptr->children;
79  for (; p; p = p->next)
80  if (p->type == XML_ELEMENT_NODE)
81  break;
82  if (p)
83  {
85  ptr, "recordData", o,
86  &rec->recordData_buf, &rec->recordData_len, 1);
88  }
89  else
90  {
92  ptr, "recordData", o,
93  &rec->recordData_buf, &rec->recordData_len);
95  }
96  }
97  else if (yaz_match_xsd_XML_n(ptr, "extraRecordData", o,
99  &ex.extraRecordData_len) )
100  ;
101  else
102  yaz_match_xsd_string(ptr, "recordIdentifier", o,
103  &ex.recordIdentifier);
104  }
106  {
107  *extra = (Z_SRW_extra_record *)
108  odr_malloc(o, sizeof(Z_SRW_extra_record));
109  memcpy(*extra, &ex, sizeof(Z_SRW_extra_record));
110  }
111  }
112  else if (o->direction == ODR_ENCODE)
113  {
114  xmlNodePtr ptr = pptr;
115  int pack = rec->recordPacking;
116  const char *spack = yaz_srw_pack_to_str(pack);
117 
118  /* recordSchema and recordData are required */
119  if (!rec->recordSchema)
120  xmlNewChild(ptr, 0, BAD_CAST "recordSchema", 0);
121  else
122  add_xsd_string(ptr, "recordSchema", rec->recordSchema);
123  if (spack)
124  {
125  if (version2)
126  add_xsd_string(ptr, "recordXMLEscaping", spack);
127  else
128  add_xsd_string(ptr, "recordPacking", spack);
129  }
130  if (!rec->recordData_buf)
131  xmlNewChild(ptr, 0, BAD_CAST "recordData", 0);
132  else
133  {
134  switch (pack)
135  {
137  add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
138  rec->recordData_len);
139  break;
141  add_XML_n(ptr, "recordData", rec->recordData_buf,
142  rec->recordData_len, 0);
143  break;
145  add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
146  rec->recordData_len);
147  break;
148  }
149  }
150  if (rec->recordPosition)
151  add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
152  if (extra && *extra)
153  {
154  if ((*extra)->recordIdentifier)
155  add_xsd_string(ptr, "recordIdentifier",
156  (*extra)->recordIdentifier);
157  if ((*extra)->extraRecordData_buf)
158  add_XML_n(ptr, "extraRecordData",
159  (*extra)->extraRecordData_buf,
160  (*extra)->extraRecordData_len, 0);
161  }
162  }
163  return 0;
164 }
165 
166 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
167  Z_SRW_extra_record ***extra,
168  int *num, void *client_data, int version2)
169 {
170  if (o->direction == ODR_DECODE)
171  {
172  int i;
173  xmlNodePtr ptr;
174  *num = 0;
175  for (ptr = pptr->children; ptr; ptr = ptr->next)
176  {
177  if (ptr->type == XML_ELEMENT_NODE &&
178  !xmlStrcmp(ptr->name, BAD_CAST "record"))
179  (*num)++;
180  }
181  if (!*num)
182  return 1;
183  *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
184  *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
185  for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
186  {
187  if (ptr->type == XML_ELEMENT_NODE &&
188  !xmlStrcmp(ptr->name, BAD_CAST "record"))
189  {
190  yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, 0);
191  i++;
192  }
193  }
194  }
195  else if (o->direction == ODR_ENCODE)
196  {
197  int i;
198  for (i = 0; i < *num; i++)
199  {
200  xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
201  0);
202  yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
203  client_data, version2);
204  }
205  }
206  return 0;
207 }
208 
209 static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec,
210  void *client_data, const char *ns)
211 {
212  if (o->direction == ODR_DECODE)
213  {
214  xmlNodePtr ptr;
215  rec->versionType = 0;
216  rec->versionValue = 0;
217  for (ptr = pptr->children; ptr; ptr = ptr->next)
218  {
219 
220  if (yaz_match_xsd_string(ptr, "versionType", o,
221  &rec->versionType))
222  ;
223  else
224  yaz_match_xsd_string(ptr, "versionValue", o,
225  &rec->versionValue);
226  }
227  }
228  else if (o->direction == ODR_ENCODE)
229  {
230  xmlNodePtr ptr = pptr;
231  add_xsd_string(ptr, "versionType", rec->versionType);
232  add_xsd_string(ptr, "versionValue", rec->versionValue);
233  }
234  return 0;
235 }
236 
237 static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
238  Z_SRW_recordVersion **vers,
239  int *num, void *client_data, const char *ns)
240 {
241  if (o->direction == ODR_DECODE)
242  {
243  int i;
244  xmlNodePtr ptr;
245  *num = 0;
246  for (ptr = pptr->children; ptr; ptr = ptr->next)
247  {
248  if (ptr->type == XML_ELEMENT_NODE &&
249  !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
250  (*num)++;
251  }
252  if (!*num)
253  return 1;
254  *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers));
255  for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
256  {
257  if (ptr->type == XML_ELEMENT_NODE &&
258  !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
259  {
260  yaz_srw_version(o, ptr, *vers + i, client_data, ns);
261  i++;
262  }
263  }
264  }
265  else if (o->direction == ODR_ENCODE)
266  {
267  int i;
268  for (i = 0; i < *num; i++)
269  {
270  xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version",
271  0);
272  yaz_srw_version(o, rptr, (*vers)+i, client_data, ns);
273  }
274  }
275  return 0;
276 }
277 
279 {
280  Odr_int freq;
281  Z_FacetTerm *facet_term;
282  const char *freq_string = yaz_element_attribute_value_get(
283  node, "facetvalue", "est_representation");
284  if (freq_string)
285  freq = odr_atoi(freq_string);
286  else
287  freq = -1;
288 
289  facet_term = facet_term_create_cstr(odr,
290  nmem_text_node_cdata(node->children, odr_getmem(odr)), freq);
291  return facet_term;
292 }
293 
295 {
296  Z_AttributeList *list;
297  Z_FacetField *facet_field;
298  int num_terms = 0;
299  int index = 0;
300  xmlNodePtr node;
301  /* USE attribute */
302  const char* name = yaz_element_attribute_value_get(ptr, "facet", "code");
303  yaz_log(YLOG_DEBUG, "sru-proxy facet type: %s", name);
304 
306  for (node = ptr->children; node; node = node->next) {
307  if (yaz_match_xsd_element(node, "facetvalue"))
308  num_terms++;
309  }
310  facet_field = facet_field_create(odr, list, num_terms);
311  index = 0;
312  for (node = ptr->children; node; node = node->next)
313  {
314  if (yaz_match_xsd_element(node, "facetvalue"))
315  {
316  facet_field_term_set(odr, facet_field,
318  index);
319  index++;
320  }
321  }
322  return facet_field;
323 }
324 
325 static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root,
326  Z_FacetList **facetList)
327 {
328  xmlNodePtr ptr;
329 
330  for (ptr = root->children; ptr; ptr = ptr->next)
331  {
332  if (yaz_match_xsd_element(ptr, "facets"))
333  {
334  xmlNodePtr node;
335  Z_FacetList *facet_list;
336  int num_facets = 0;
337  for (node = ptr->children; node; node= node->next)
338  {
339  if (node->type == XML_ELEMENT_NODE)
340  num_facets++;
341  }
342  facet_list = facet_list_create(o, num_facets);
343  num_facets = 0;
344  for (node = ptr->children; node; node= node->next)
345  {
346  if (yaz_match_xsd_element(node, "facet"))
347  {
349  o, facet_list,
350  yaz_sru_proxy_decode_facet_field(o, node), num_facets);
351  num_facets++;
352  }
353  }
354  *facetList = facet_list;
355  break;
356  }
357  }
358  return 0;
359 }
360 
361 
362 
363 static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
364  Z_SRW_diagnostic **recs, int *num,
365  void *client_data, const char *ns)
366 {
367  int i;
368  xmlNodePtr ptr;
369  *num = 0;
370  for (ptr = pptr; ptr; ptr = ptr->next)
371  {
372  if (ptr->type == XML_ELEMENT_NODE &&
373  !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
374  (*num)++;
375  }
376  if (!*num)
377  return 1;
378  *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
379  for (i = 0; i < *num; i++)
380  {
381  (*recs)[i].uri = 0;
382  (*recs)[i].details = 0;
383  (*recs)[i].message = 0;
384  }
385  for (i = 0, ptr = pptr; ptr; ptr = ptr->next)
386  {
387  if (ptr->type == XML_ELEMENT_NODE &&
388  !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
389  {
390  xmlNodePtr rptr;
391  (*recs)[i].uri = 0;
392  (*recs)[i].details = 0;
393  (*recs)[i].message = 0;
394  for (rptr = ptr->children; rptr; rptr = rptr->next)
395  {
396  if (yaz_match_xsd_string(rptr, "uri", o, &(*recs)[i].uri))
397  ;
398  else if (yaz_match_xsd_string(rptr, "details", o,
399  &(*recs)[i].details))
400  ;
401  else
402  yaz_match_xsd_string(rptr, "message", o,
403  &(*recs)[i].message);
404  }
405  i++;
406  }
407  }
408  return 0;
409 }
410 
411 int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
412  Z_SRW_diagnostic **diag,
413  int *num, ODR odr)
414 {
415  int ret = 0;
416  xmlDocPtr doc = xmlParseMemory(buf, len);
417  if (doc)
418  {
419  xmlNodePtr ptr = xmlDocGetRootElement(doc);
420  while (ptr && ptr->type != XML_ELEMENT_NODE)
421  ptr = ptr->next;
422  if (ptr && ptr->ns
423  && !xmlStrcmp(ptr->ns->href,
424  BAD_CAST "http://www.loc.gov/zing/srw/diagnostic/"))
425  {
426  ret = yaz_srw_decode_diagnostics(odr, ptr, diag, num, 0, 0);
427  }
428  xmlFreeDoc(doc);
429  }
430  return ret;
431 }
432 
433 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
434  int *num, void *client_data, const char *ns,
435  int version2)
436 {
437  if (o->direction == ODR_DECODE)
438  {
439  return yaz_srw_decode_diagnostics(o, pptr->children, recs, num, client_data, ns);
440  }
441  else if (o->direction == ODR_ENCODE)
442  {
443  int i;
444  xmlNsPtr ns_diag =
445  xmlNewNs(pptr, BAD_CAST (version2 ?
447  BAD_CAST "diag" );
448  for (i = 0; i < *num; i++)
449  {
450  const char *std_diag = "info:srw/diagnostic/1/";
451  const char *ucp_diag = "info:srw/diagnostic/12/";
452  xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
453  BAD_CAST "diagnostic", 0);
454  add_xsd_string(rptr, "uri", (*recs)[i].uri);
455  add_xsd_string(rptr, "details", (*recs)[i].details);
456  if ((*recs)[i].message)
457  add_xsd_string(rptr, "message", (*recs)[i].message);
458  else if ((*recs)[i].uri )
459  {
460  if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
461  {
462  int no = atoi((*recs)[i].uri + strlen(std_diag));
463  const char *message = yaz_diag_srw_str(no);
464  if (message)
465  add_xsd_string(rptr, "message", message);
466  }
467  else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
468  {
469  int no = atoi((*recs)[i].uri + strlen(ucp_diag));
470  const char *message = yaz_diag_sru_update_str(no);
471  if (message)
472  add_xsd_string(rptr, "message", message);
473  }
474  }
475  }
476  }
477  return 0;
478 }
479 
480 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
481  void *client_data, const char *ns)
482 {
483  if (o->direction == ODR_DECODE)
484  {
485  xmlNodePtr ptr;
486  term->value = 0;
487  term->numberOfRecords = 0;
488  term->displayTerm = 0;
489  term->whereInList = 0;
490  for (ptr = pptr->children; ptr; ptr = ptr->next)
491  {
492  if (yaz_match_xsd_string(ptr, "value", o, &term->value))
493  ;
494  else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o,
495  &term->numberOfRecords))
496  ;
497  else if (yaz_match_xsd_string(ptr, "displayTerm", o,
498  &term->displayTerm))
499  ;
500  else
501  yaz_match_xsd_string(ptr, "whereInList", o, &term->whereInList);
502  }
503  }
504  else if (o->direction == ODR_ENCODE)
505  {
506  xmlNodePtr ptr = pptr;
507  add_xsd_string(ptr, "value", term->value);
508  add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
509  add_xsd_string(ptr, "displayTerm", term->displayTerm);
510  add_xsd_string(ptr, "whereInList", term->whereInList);
511  }
512  return 0;
513 }
514 
515 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
516  int *num, void *client_data, const char *ns)
517 {
518  if (o->direction == ODR_DECODE)
519  {
520  int i;
521  xmlNodePtr ptr;
522  *num = 0;
523  for (ptr = pptr->children; ptr; ptr = ptr->next)
524  {
525  if (ptr->type == XML_ELEMENT_NODE &&
526  !xmlStrcmp(ptr->name, BAD_CAST "term"))
527  (*num)++;
528  }
529  if (!*num)
530  return 1;
531  *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
532  for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
533  {
534  if (ptr->type == XML_ELEMENT_NODE &&
535  !xmlStrcmp(ptr->name, BAD_CAST "term"))
536  yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
537  }
538  }
539  else if (o->direction == ODR_ENCODE)
540  {
541  int i;
542  for (i = 0; i < *num; i++)
543  {
544  xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
545  yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
546  }
547  }
548  return 0;
549 }
550 
551 static void encode_echoed_args(xmlNodePtr ptr, Z_SRW_PDU *p, const char *name)
552 {
553  Z_SRW_extra_arg *ea = p->extra_args;
554  if (ea)
555  {
556  xmlNode *p1 = xmlNewChild(ptr, 0, BAD_CAST name, 0);
557  xmlNode *p2 = 0;
558  for (; ea; ea = ea->next)
559  {
560  if (ea->name && ea->name[0] == 'x' && ea->name[1] == '-')
561  {
562  /* not really according to XSD as of July 2014 */
563  if (!p2)
564  p2 = xmlNewChild(p1, 0,
565  BAD_CAST "extraRequestData", 0);
566  /* skip +2: "x-" in element */
567  add_xsd_string(p2, ea->name + 2, ea->value);
568  }
569  else
570  add_xsd_string(p1, ea->name, ea->value);
571  }
572  }
573 }
574 
575 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
576  void *client_data, const char *ns)
577 {
578  xmlNodePtr pptr = (xmlNodePtr) vptr;
579  if (o->direction == ODR_DECODE)
580  {
581  Z_SRW_PDU **p = handler_data;
582  xmlNodePtr method = pptr->children;
583  char *neg_version;
584 
585  while (method && method->type == XML_TEXT_NODE)
586  method = method->next;
587 
588  if (!method)
589  return -1;
590  if (method->type != XML_ELEMENT_NODE)
591  return -1;
592 
593  *p = yaz_srw_get_core_v_2_0(o);
594 
595  if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
596  {
597  xmlNodePtr ptr = method->children;
599  char *recordPacking = 0;
600  char *recordXMLEscaping = 0;
601  const char *facetLimit = 0;
602  const char *facetStart = 0;
603  const char *facetSort = 0;
604 
605  (*p)->which = Z_SRW_searchRetrieve_request;
606  req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
607  odr_malloc(o, sizeof(*req));
608  req->queryType = "cql";
609  req->query = 0;
611  req->sort.none = 0;
612  req->startRecord = 0;
613  req->maximumRecords = 0;
614  req->recordSchema = 0;
615  req->recordPacking = 0;
616  req->packing = 0;
617  req->recordXPath = 0;
618  req->resultSetTTL = 0;
619  req->stylesheet = 0;
620  req->database = 0;
621 
622  for (; ptr; ptr = ptr->next)
623  {
624  if (yaz_match_xsd_string(ptr, "version", o,
625  &(*p)->srw_version))
626  ;
627  else if (yaz_match_xsd_string(ptr, "queryType", o,
628  &req->queryType))
629  ;
630  else if (yaz_match_xsd_string(ptr, "query", o,
631  &req->query))
632  ;
633  else if (yaz_match_xsd_string(ptr, "pQuery", o,
634  &req->query))
635  req->queryType = "pqf";
636  else if (yaz_match_xsd_string(ptr, "xQuery", o,
637  &req->query))
638  req->queryType = "xcql";
639  else if (yaz_match_xsd_integer(ptr, "startRecord", o,
640  &req->startRecord))
641  ;
642  else if (yaz_match_xsd_integer(ptr, "maximumRecords", o,
643  &req->maximumRecords))
644  ;
645  else if (yaz_match_xsd_string(ptr, "recordPacking", o,
646  &recordPacking))
647  ;
648  else if (yaz_match_xsd_string(ptr, "recordXMLEscaping", o,
649  &recordXMLEscaping))
650  ;
651  else if (yaz_match_xsd_string(ptr, "recordSchema", o,
652  &req->recordSchema))
653  ;
654  else if (yaz_match_xsd_string(ptr, "recordXPath", o,
655  &req->recordXPath))
656  ;
657  else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o,
658  &req->resultSetTTL))
659  ;
660  else if (yaz_match_xsd_string(ptr, "sortKeys", o,
661  &req->sort.sortKeys))
663  else if (yaz_match_xsd_string(ptr, "stylesheet", o,
664  &req->stylesheet))
665  ;
666  else if (yaz_match_xsd_string(ptr, "database", o,
667  &req->database))
668  ;
669  else if (yaz_match_xsd_string(ptr, "facetLimit", o,
670  (char**) &facetLimit))
671  ;
672  else if (yaz_match_xsd_string(ptr, "facetStart", o,
673  (char**) &facetStart))
674  ;
675  else if (yaz_match_xsd_string(ptr, "facetSort", o,
676  (char**) &facetSort))
677  ;
678  else
679  ;
680  }
681  if (!req->query)
682  {
683  /* should put proper diagnostic here */
684  return -1;
685  }
686  if (!strcmp((*p)->srw_version, "2.0"))
687  {
688  req->recordPacking = recordXMLEscaping;
689  req->packing = recordPacking;
690  }
691  else
692  {
693  req->recordPacking = recordPacking;
694  }
695  yaz_sru_facet_request(o, &req->facetList, &facetLimit, &facetStart,
696  &facetSort);
697  }
698  else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
699  {
700  xmlNodePtr ptr = method->children;
702 
703  (*p)->which = Z_SRW_searchRetrieve_response;
704  res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
705  odr_malloc(o, sizeof(*res));
706 
707  res->numberOfRecords = 0;
708  res->resultCountPrecision = 0;
709  res->resultSetId = 0;
710  res->resultSetIdleTime = 0;
711  res->records = 0;
712  res->num_records = 0;
713  res->diagnostics = 0;
714  res->num_diagnostics = 0;
715  res->nextRecordPosition = 0;
716  res->facetList = 0;
717  res->suggestions = 0;
718 
719  for (; ptr; ptr = ptr->next)
720  {
721  if (yaz_match_xsd_string(ptr, "version", o,
722  &(*p)->srw_version))
723  ;
724  else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
725  &(*p)->extraResponseData_buf,
726  &(*p)->extraResponseData_len))
727  ;
728  else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o,
729  &res->numberOfRecords))
730  ;
731  else if (yaz_match_xsd_string(ptr, "resultCountPrecision", o,
732  &res->resultCountPrecision))
733  ;
734  else if (yaz_match_xsd_string(ptr, "resultSetId", o,
735  &res->resultSetId))
736  ;
737  else if (yaz_match_xsd_integer(ptr, "resultSetIdleTime", o,
738  &res->resultSetIdleTime))
739  ;
740  else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o,
741  &res->resultSetIdleTime))
742  ;
743  else if (yaz_match_xsd_element(ptr, "records"))
744  yaz_srw_records(o, ptr, &res->records,
745  &res->extra_records,
746  &res->num_records, client_data, 0);
747  else if (yaz_match_xsd_integer(ptr, "nextRecordPosition", o,
748  &res->nextRecordPosition))
749  ;
750  else if (yaz_match_xsd_element(ptr, "diagnostics"))
751  yaz_srw_diagnostics(o, ptr, &res->diagnostics,
752  &res->num_diagnostics,
753  client_data, ns, 0);
754  else if (yaz_match_xsd_element(ptr, "facet_analysis"))
755  yaz_sru_proxy_decode_facets(o, ptr, &res->facetList);
756  else if (yaz_match_xsd_element(ptr, "facetedResults"))
757  yaz_sru_facet_response(o, &res->facetList, ptr);
758  }
759  }
760  else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
761  {
763  xmlNodePtr ptr = method->children;
764 
765  (*p)->which = Z_SRW_explain_request;
766  req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
767  odr_malloc(o, sizeof(*req));
768  req->recordPacking = 0;
769  req->packing = 0;
770  req->database = 0;
771  req->stylesheet = 0;
772  for (; ptr; ptr = ptr->next)
773  {
774  if (yaz_match_xsd_string(ptr, "version", o,
775  &(*p)->srw_version))
776  ;
777  else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
778  &(*p)->extraResponseData_buf,
779  &(*p)->extraResponseData_len))
780  ;
781  else if (yaz_match_xsd_string(ptr, "stylesheet", o,
782  &req->stylesheet))
783  ;
784  else if (yaz_match_xsd_string(ptr, "recordPacking", o,
785  &req->recordPacking))
786  ;
787  else
788  yaz_match_xsd_string(ptr, "database", o, &req->database);
789  }
790  }
791  else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
792  {
794  xmlNodePtr ptr = method->children;
795 
796  (*p)->which = Z_SRW_explain_response;
797  res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
798  odr_malloc(o, sizeof(*res));
799  res->diagnostics = 0;
800  res->num_diagnostics = 0;
801  res->record.recordSchema = 0;
802  res->record.recordData_buf = 0;
803  res->record.recordData_len = 0;
804  res->record.recordPosition = 0;
805 
806  for (; ptr; ptr = ptr->next)
807  {
808  if (yaz_match_xsd_string(ptr, "version", o,
809  &(*p)->srw_version))
810  ;
811  else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
812  &(*p)->extraResponseData_buf,
813  &(*p)->extraResponseData_len))
814  ;
815  else if (yaz_match_xsd_element(ptr, "record"))
816  yaz_srw_record(o, ptr, &res->record, &res->extra_record,
817  client_data, 0);
818  else if (yaz_match_xsd_element(ptr, "diagnostics"))
819  yaz_srw_diagnostics(o, ptr, &res->diagnostics,
820  &res->num_diagnostics,
821  client_data, ns, 0);
822  ;
823  }
824  }
825  else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
826  {
827  Z_SRW_scanRequest *req;
828  xmlNodePtr ptr = method->children;
829 
830  (*p)->which = Z_SRW_scan_request;
831  req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
832  odr_malloc(o, sizeof(*req));
833  req->queryType = "cql";
834  req->scanClause = 0;
835  req->responsePosition = 0;
836  req->maximumTerms = 0;
837  req->stylesheet = 0;
838  req->database = 0;
839 
840  for (; ptr; ptr = ptr->next)
841  {
842  if (yaz_match_xsd_string(ptr, "version", o,
843  &(*p)->srw_version))
844  ;
845  else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
846  &(*p)->extraResponseData_buf,
847  &(*p)->extraResponseData_len))
848  ;
849  else if (yaz_match_xsd_string(ptr, "scanClause", o,
850  &req->scanClause))
851  ;
852  else if (yaz_match_xsd_string(ptr, "pScanClause", o,
853  &req->scanClause))
854  {
855  req->queryType = "pqf";
856  }
857  else if (yaz_match_xsd_integer(ptr, "responsePosition", o,
858  &req->responsePosition))
859  ;
860  else if (yaz_match_xsd_integer(ptr, "maximumTerms", o,
861  &req->maximumTerms))
862  ;
863  else if (yaz_match_xsd_string(ptr, "stylesheet", o,
864  &req->stylesheet))
865  ;
866  else
867  yaz_match_xsd_string(ptr, "database", o, &req->database);
868  }
869  }
870  else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
871  {
872  Z_SRW_scanResponse *res;
873  xmlNodePtr ptr = method->children;
874 
875  (*p)->which = Z_SRW_scan_response;
876  res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
877  odr_malloc(o, sizeof(*res));
878  res->terms = 0;
879  res->num_terms = 0;
880  res->diagnostics = 0;
881  res->num_diagnostics = 0;
882 
883  for (; ptr; ptr = ptr->next)
884  {
885  if (yaz_match_xsd_string(ptr, "version", o,
886  &(*p)->srw_version))
887  ;
888  else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
889  &(*p)->extraResponseData_buf,
890  &(*p)->extraResponseData_len))
891  ;
892  else if (yaz_match_xsd_element(ptr, "terms"))
893  yaz_srw_terms(o, ptr, &res->terms,
894  &res->num_terms, client_data,
895  ns);
896  else if (yaz_match_xsd_element(ptr, "diagnostics"))
897  yaz_srw_diagnostics(o, ptr, &res->diagnostics,
898  &res->num_diagnostics,
899  client_data, ns, 0);
900  }
901  }
902  else
903  {
904  *p = 0;
905  return -1;
906  }
907  neg_version = yaz_negotiate_sru_version((*p)->srw_version);
908  if (neg_version)
909  (*p)->srw_version = neg_version;
910  }
911  else if (o->direction == ODR_ENCODE)
912  {
913  Z_SRW_PDU **p = handler_data;
914  xmlNsPtr ns_srw;
915  xmlNodePtr ptr = 0;
916  int version2 = !(*p)->srw_version ||
917  strcmp((*p)->srw_version, "2.") > 0;
918  if ((*p)->which == Z_SRW_searchRetrieve_request)
919  {
920  Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
921  const char *queryType = req->queryType;
922  if (version2)
923  ns = "http://docs.oasis-open.org/ns/search-ws/sruRequest";
924  ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveRequest", 0);
925  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
926  xmlSetNs(ptr, ns_srw);
927 
928  if (!version2)
929  add_xsd_string(ptr, "version", (*p)->srw_version);
930  if (version2)
931  {
932  add_xsd_string(ptr, "query", req->query);
933  }
934  else
935  {
936  if (!queryType || !strcmp(queryType, "cql"))
937  add_xsd_string(ptr, "query", req->query);
938  else if (!strcmp(queryType, "xcql"))
939  add_xsd_string(ptr, "xQuery", req->query);
940  else if (!strcmp(queryType, "pqf"))
941  add_xsd_string(ptr, "pQuery", req->query);
942  queryType = 0;
943  }
944  add_xsd_integer(ptr, "startRecord", req->startRecord);
945  add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
946  if (version2)
947  add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking);
948  else
949  add_xsd_string(ptr, "recordPacking", req->recordPacking);
950  add_xsd_string(ptr, "recordSchema", req->recordSchema);
951  add_xsd_string(ptr, "recordXPath", req->recordXPath);
952  add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
953  add_xsd_string(ptr, "stylesheet", req->stylesheet);
954  add_xsd_string(ptr, "queryType", queryType);
955  switch (req->sort_type)
956  {
958  break;
960  add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
961  break;
963  add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
964  break;
965  }
966  /* still unsupported are: renderedBy, httpAccept, responseType */
967  add_xsd_string(ptr, "database", req->database);
968  if (version2)
969  add_xsd_string(ptr, "recordPacking", req->packing);
970  {
971  const char *limit = 0;
972  const char *start = 0;
973  const char *sort = 0;
974  yaz_sru_facet_request(o, &req->facetList, &limit, &start,
975  &sort);
976  add_xsd_string(ptr, "facetLimit", limit);
977  add_xsd_string(ptr, "facetStart", start);
978  add_xsd_string(ptr, "facetSort", sort);
979  }
980  }
981  else if ((*p)->which == Z_SRW_searchRetrieve_response)
982  {
983  Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
984  if (version2)
985  ns = "http://docs.oasis-open.org/ns/search-ws/sruResponse";
986  ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveResponse", 0);
987  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
988  xmlSetNs(ptr, ns_srw);
989 
990  if (!version2)
991  add_xsd_string(ptr, "version", (*p)->srw_version);
992  add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
993  add_xsd_string(ptr, "resultSetId", res->resultSetId);
994  if (!version2)
995  add_xsd_integer(ptr, "resultSetIdleTime",
996  res->resultSetIdleTime);
997  if (res->num_records)
998  {
999  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
1000  yaz_srw_records(o, rptr, &res->records, &res->extra_records,
1001  &res->num_records,
1002  client_data, version2);
1003  }
1004  add_xsd_integer(ptr, "nextRecordPosition",
1005  res->nextRecordPosition);
1006  encode_echoed_args(ptr, *p, "echoedSearchRetrieveRequest");
1007  if (res->num_diagnostics)
1008  {
1009  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1010  0);
1011  yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1012  &res->num_diagnostics, client_data, ns,
1013  version2);
1014  }
1015  if (version2)
1016  {
1017  if (ptr && (*p)->extraResponseData_len)
1018  add_XML_n(ptr, "extraResponseData",
1019  (*p)->extraResponseData_buf,
1020  (*p)->extraResponseData_len, ns_srw);
1021  add_xsd_integer(ptr, "resultSetTTL", res->resultSetIdleTime);
1022  add_xsd_string(ptr, "resultCountPrecision",
1023  res->resultCountPrecision);
1024  yaz_sru_facet_response(o, &res->facetList, ptr);
1025  return 0; /* so we don't make extra response data twice */
1026  }
1027  }
1028  else if ((*p)->which == Z_SRW_explain_request)
1029  {
1030  Z_SRW_explainRequest *req = (*p)->u.explain_request;
1031  if (version2)
1032  ns = "http://docs.oasis-open.org/ns/search-ws/sruRequest";
1033  ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest", 0);
1034  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1035  xmlSetNs(ptr, ns_srw);
1036 
1037  if (!version2)
1038  add_xsd_string(ptr, "version", (*p)->srw_version);
1039  if (version2)
1040  {
1041  add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking);
1042  add_xsd_string(ptr, "recordPacking", req->packing);
1043  }
1044  else
1045  add_xsd_string(ptr, "recordPacking", req->recordPacking);
1046  add_xsd_string(ptr, "stylesheet", req->stylesheet);
1047  add_xsd_string(ptr, "database", req->database);
1048  }
1049  else if ((*p)->which == Z_SRW_explain_response)
1050  {
1051  Z_SRW_explainResponse *res = (*p)->u.explain_response;
1052  if (version2)
1053  ns = "http://docs.oasis-open.org/ns/search-ws/sruResponse";
1054  ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse", 0);
1055  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1056  xmlSetNs(ptr, ns_srw);
1057 
1058  add_xsd_string(ptr, "version", (*p)->srw_version);
1059  if (1)
1060  {
1061  xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1062  yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
1063  client_data, version2);
1064  }
1065  encode_echoed_args(ptr, *p, "echoedExplainRequest");
1066  if (res->num_diagnostics)
1067  {
1068  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1069  0);
1070  yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1071  &res->num_diagnostics, client_data, ns,
1072  version2);
1073  }
1074  }
1075  else if ((*p)->which == Z_SRW_scan_request)
1076  {
1077  Z_SRW_scanRequest *req = (*p)->u.scan_request;
1078  const char *queryType = req->queryType;
1079  if (version2)
1080  ns = "http://docs.oasis-open.org/ns/search-ws/scan";
1081  ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
1082  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1083  xmlSetNs(ptr, ns_srw);
1084 
1085  if (!version2)
1086  add_xsd_string(ptr, "version", (*p)->srw_version);
1087 
1088  if (version2)
1089  {
1090  if (queryType && strcmp(queryType, "cql"))
1091  add_xsd_string(ptr, "queryType", queryType);
1092  add_xsd_string(ptr, "scanClause", req->scanClause);
1093  }
1094  else
1095  {
1096  if (!queryType || !strcmp(queryType, "cql"))
1097  add_xsd_string(ptr, "scanClause", req->scanClause);
1098  else if (!strcmp(queryType, "pqf"))
1099  add_xsd_string(ptr, "pScanClause", req->scanClause);
1100  }
1101  add_xsd_integer(ptr, "responsePosition", req->responsePosition);
1102  add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
1103  add_xsd_string(ptr, "stylesheet", req->stylesheet);
1104  add_xsd_string(ptr, "database", req->database);
1105  }
1106  else if ((*p)->which == Z_SRW_scan_response)
1107  {
1108  Z_SRW_scanResponse *res = (*p)->u.scan_response;
1109  if (version2)
1110  ns = "http://docs.oasis-open.org/ns/search-ws/scan";
1111  ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
1112  ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1113  xmlSetNs(ptr, ns_srw);
1114 
1115  if (!version2)
1116  add_xsd_string(ptr, "version", (*p)->srw_version);
1117  if (res->num_terms)
1118  {
1119  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
1120  yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
1121  client_data, ns);
1122  }
1123  if (res->num_diagnostics)
1124  {
1125  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1126  0);
1127  yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1128  &res->num_diagnostics, client_data, ns,
1129  version2);
1130  }
1131  }
1132  else
1133  return -1;
1134  if (ptr && (*p)->extraResponseData_len)
1135  add_XML_n(ptr, "extraResponseData",
1136  (*p)->extraResponseData_buf,
1137  (*p)->extraResponseData_len, ns_srw);
1138 
1139 
1140  }
1141  return 0;
1142 }
1143 
1144 int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1145  void *client_data, const char *ns_ucp_str)
1146 {
1147  xmlNodePtr pptr = (xmlNodePtr) vptr;
1148  const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1;
1149  if (o->direction == ODR_DECODE)
1150  {
1151  Z_SRW_PDU **p = handler_data;
1152  xmlNodePtr method = pptr->children;
1153 
1154  while (method && method->type == XML_TEXT_NODE)
1155  method = method->next;
1156 
1157  if (!method)
1158  return -1;
1159  if (method->type != XML_ELEMENT_NODE)
1160  return -1;
1161 
1162  *p = yaz_srw_get_core_v_2_0(o);
1163 
1164  if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1165  {
1166  xmlNodePtr ptr = method->children;
1167  Z_SRW_updateRequest *req;
1168  char *oper = 0;
1169 
1170  (*p)->which = Z_SRW_update_request;
1171  req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1172  odr_malloc(o, sizeof(*req));
1173  req->database = 0;
1174  req->operation = 0;
1175  req->recordId = 0;
1176  req->recordVersions = 0;
1177  req->num_recordVersions = 0;
1178  req->record = 0;
1179  req->extra_record = 0;
1180  req->extraRequestData_buf = 0;
1181  req->extraRequestData_len = 0;
1182  req->stylesheet = 0;
1183 
1184  for (; ptr; ptr = ptr->next)
1185  {
1186  if (yaz_match_xsd_string(ptr, "version", o,
1187  &(*p)->srw_version))
1188  ;
1189  else if (yaz_match_xsd_string(ptr, "action", o,
1190  &oper)){
1191  if (oper)
1192  {
1193  if (!strcmp(oper, "info:srw/action/1/delete"))
1194  req->operation = "delete";
1195  else if (!strcmp(oper,"info:srw/action/1/replace" ))
1196  req->operation = "replace";
1197  else if (!strcmp(oper, "info:srw/action/1/create"))
1198  req->operation = "insert";
1199  }
1200  }
1201  else if (yaz_match_xsd_string(ptr, "recordIdentifier", o,
1202  &req->recordId))
1203  ;
1204  else if (yaz_match_xsd_element(ptr, "recordVersions" ) )
1205  yaz_srw_versions( o, ptr, &req->recordVersions,
1206  &req->num_recordVersions, client_data,
1207  ns_ucp_str);
1208  else if (yaz_match_xsd_element(ptr, "record"))
1209  {
1210  req->record = yaz_srw_get_record(o);
1211  yaz_srw_record(o, ptr, req->record, &req->extra_record,
1212  client_data, 0);
1213  }
1214  else if (yaz_match_xsd_string(ptr, "stylesheet", o,
1215  &req->stylesheet))
1216  ;
1217  else
1218  yaz_match_xsd_string(ptr, "database", o, &req->database);
1219  }
1220  }
1221  else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1222  {
1223  xmlNodePtr ptr = method->children;
1224  Z_SRW_updateResponse *res;
1225 
1226  (*p)->which = Z_SRW_update_response;
1227  res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1228  odr_malloc(o, sizeof(*res));
1229 
1230  res->operationStatus = 0;
1231  res->recordId = 0;
1232  res->recordVersions = 0;
1233  res->num_recordVersions = 0;
1234  res->diagnostics = 0;
1235  res->num_diagnostics = 0;
1236  res->record = 0;
1237  res->extra_record = 0;
1238  res->extraResponseData_buf = 0;
1239  res->extraResponseData_len = 0;
1240 
1241  for (; ptr; ptr = ptr->next)
1242  {
1243  if (yaz_match_xsd_string(ptr, "version", o,
1244  &(*p)->srw_version))
1245  ;
1246  else if (yaz_match_xsd_string(ptr, "operationStatus", o,
1247  &res->operationStatus ))
1248  ;
1249  else if (yaz_match_xsd_string(ptr, "recordIdentifier", o,
1250  &res->recordId))
1251  ;
1252  else if (yaz_match_xsd_element(ptr, "recordVersions" ))
1253  yaz_srw_versions(o, ptr, &res->recordVersions,
1254  &res->num_recordVersions,
1255  client_data, ns_ucp_str);
1256  else if (yaz_match_xsd_element(ptr, "record"))
1257  {
1258  res->record = yaz_srw_get_record(o);
1259  yaz_srw_record(o, ptr, res->record, &res->extra_record,
1260  client_data, 0);
1261  }
1262  else if (yaz_match_xsd_element(ptr, "diagnostics"))
1263  yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1264  &res->num_diagnostics,
1265  client_data, ns_ucp_str, 0);
1266  }
1267  }
1268  else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1269  {
1270  }
1271  else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1272  {
1273  }
1274  else
1275  {
1276  *p = 0;
1277  return -1;
1278  }
1279  }
1280  else if (o->direction == ODR_ENCODE)
1281  {
1282  Z_SRW_PDU **p = handler_data;
1283  xmlNsPtr ns_ucp, ns_srw;
1284 
1285  if ((*p)->which == Z_SRW_update_request)
1286  {
1287  Z_SRW_updateRequest *req = (*p)->u.update_request;
1288  xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1289  ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1290  xmlSetNs(ptr, ns_ucp);
1291  ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1292 
1293  add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1294  add_xsd_string(ptr, "action", req->operation);
1295  add_xsd_string(ptr, "recordIdentifier", req->recordId );
1296  if (req->recordVersions)
1297  yaz_srw_versions( o, ptr, &req->recordVersions,
1298  &req->num_recordVersions,
1299  client_data, ns_ucp_str);
1300  if (req->record && req->record->recordData_len)
1301  {
1302  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1303  xmlSetNs(rptr, ns_srw);
1304  yaz_srw_record(o, rptr, req->record, &req->extra_record,
1305  client_data, 0);
1306  }
1307  if (req->extraRequestData_len)
1308  {
1309  add_XML_n(ptr, "extraRequestData",
1310  req->extraRequestData_buf,
1311  req->extraRequestData_len, ns_srw);
1312  }
1313  add_xsd_string(ptr, "stylesheet", req->stylesheet);
1314  add_xsd_string(ptr, "database", req->database);
1315  }
1316  else if ((*p)->which == Z_SRW_update_response)
1317  {
1318  Z_SRW_updateResponse *res = (*p)->u.update_response;
1319  xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1320  "updateResponse", 0);
1321  ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1322  xmlSetNs(ptr, ns_ucp);
1323  ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1324 
1325  add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1326  add_xsd_string(ptr, "operationStatus", res->operationStatus );
1327  add_xsd_string(ptr, "recordIdentifier", res->recordId );
1328  if (res->recordVersions)
1329  yaz_srw_versions(o, ptr, &res->recordVersions,
1330  &res->num_recordVersions,
1331  client_data, ns_ucp_str);
1332  if (res->record && res->record->recordData_len)
1333  {
1334  xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1335  xmlSetNs(rptr, ns_srw);
1336  yaz_srw_record(o, rptr, res->record, &res->extra_record,
1337  client_data, 0);
1338  }
1339  if (res->num_diagnostics)
1340  {
1341  xmlNsPtr ns_diag =
1342  xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1,
1343  BAD_CAST "diag" );
1344 
1345  xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0);
1346  yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1347  &res->num_diagnostics, client_data,
1348  ns_ucp_str, 0);
1349  }
1350  if (res->extraResponseData_len)
1351  add_XML_n(ptr, "extraResponseData",
1352  res->extraResponseData_buf,
1353  res->extraResponseData_len, ns_srw);
1354  }
1355  else
1356  return -1;
1357  }
1358  return 0;
1359 }
1360 
1361 #endif
1362 
1363 
1364 /*
1365  * Local variables:
1366  * c-basic-offset: 4
1367  * c-file-style: "Stroustrup"
1368  * indent-tabs-mode: nil
1369  * End:
1370  * vim: shiftwidth=4 tabstop=8 expandtab
1371  */
1372 
static int node(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data)
Definition: cql2ccl.c:86
const char * yaz_diag_sru_update_str(int code)
const char * yaz_diag_srw_str(int code)
Definition: diagsrw.c:110
Z_FacetField * facet_field_create(ODR odr, Z_AttributeList *attributes, int num_terms)
Definition: facet.c:198
Z_FacetTerm * facet_term_create_cstr(ODR odr, const char *cstr, Odr_int freq)
Definition: facet.c:189
Z_FacetList * facet_list_create(ODR odr, int num_facets)
Definition: facet.c:215
void facet_field_term_set(ODR odr, Z_FacetField *field, Z_FacetTerm *facet_term, int index)
Definition: facet.c:208
void facet_list_field_set(ODR odr, Z_FacetList *list, Z_FacetField *field, int index)
Definition: facet.c:224
Header for the facet utilities.
char * name
Definition: initopt.c:18
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition: log.c:487
#define YLOG_DEBUG
log level: debugging
Definition: log.h:44
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
#define ODR_DECODE
Definition: odr.h:95
#define odr_getmem(o)
Definition: odr.h:216
nmem_int_t Odr_int
Definition: odr.h:47
#define ODR_ENCODE
Definition: odr.h:96
Odr_int odr_atoi(const char *s)
Definition: odr_mem.c:146
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
Z_AttributeList * zget_AttributeList_use_string(ODR o, const char *name)
creates AttributeList with type=1(use) and string value
Definition: pquery.c:310
Header for Z39.50 Protocol.
SRU private header.
int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem)
Definition: xml_match.c:17
xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, xmlNsPtr ns_ptr)
Definition: xml_add.c:48
int yaz_match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len, int fixup_root)
Definition: xml_match.c:76
void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, xmlNsPtr ns_ptr)
Definition: xml_add.c:19
void add_xsd_integer(xmlNodePtr ptr, const char *elem, const Odr_int *val)
Definition: xml_add.c:66
xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
Definition: xml_add.c:61
const char * yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name)
Definition: srwutil.c:71
void yaz_sru_facet_request(ODR, Z_FacetList **facetList, const char **limit, const char **start, const char **sort)
Definition: sru_facet.c:60
int yaz_match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len)
Definition: xml_match.c:120
int yaz_match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len)
Definition: xml_match.c:65
void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
Definition: sru_facet.c:189
int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val)
Definition: xml_match.c:71
xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, int len)
Definition: xml_add.c:35
int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, Odr_int **val)
Definition: xml_match.c:126
int sru_decode_surrogate_diagnostics(const char *buf, size_t len, Z_SRW_diagnostic **diag, int *num, ODR odr)
Definition: srw.c:411
static void encode_echoed_args(xmlNodePtr ptr, Z_SRW_PDU *p, const char *name)
Definition: srw.c:551
static Z_FacetField * yaz_sru_proxy_decode_facet_field(ODR odr, xmlNodePtr ptr)
Definition: srw.c:294
static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec, void *client_data, const char *ns)
Definition: srw.c:209
static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns, int version2)
Definition: srw.c:433
int yaz_ucp_codec(ODR o, void *vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns_ucp_str)
Definition: srw.c:1144
static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, Z_SRW_extra_record ***extra, int *num, void *client_data, int version2)
Definition: srw.c:166
static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns)
Definition: srw.c:363
static int yaz_srw_versions(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion **vers, int *num, void *client_data, const char *ns)
Definition: srw.c:237
char * yaz_negotiate_sru_version(char *input_ver)
Definition: srw.c:26
Z_FacetTerm * yaz_sru_proxy_get_facet_term_count(ODR odr, xmlNodePtr node)
Definition: srw.c:278
static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms, int *num, void *client_data, const char *ns)
Definition: srw.c:515
static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term, void *client_data, const char *ns)
Definition: srw.c:480
static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root, Z_FacetList **facetList)
Definition: srw.c:325
int yaz_srw_codec(ODR o, void *vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns)
Definition: srw.c:575
static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, Z_SRW_extra_record **extra, void *client_data, int version2)
Definition: srw.c:39
Header for SRW/SRU.
#define Z_SRW_recordPacking_XML
Definition: srw.h:55
#define Z_SRW_searchRetrieve_response
Definition: srw.h:192
#define Z_SRW_explain_request
Definition: srw.h:193
#define Z_SRW_update_request
Definition: srw.h:197
#define Z_SRW_scan_request
Definition: srw.h:195
#define YAZ_XMLNS_DIAG_v1_1
Definition: srw.h:329
#define YAZ_XMLNS_SRU_v1_1
Definition: srw.h:328
#define Z_SRW_sort_type_none
Definition: srw.h:74
#define Z_SRW_recordPacking_string
Definition: srw.h:54
#define Z_SRW_recordPacking_URL
Definition: srw.h:56
#define Z_SRW_update_response
Definition: srw.h:198
#define YAZ_XMLNS_DIAG_v2
Definition: srw.h:330
#define Z_SRW_sort_type_sort
Definition: srw.h:75
#define Z_SRW_explain_response
Definition: srw.h:194
#define Z_SRW_scan_response
Definition: srw.h:196
#define Z_SRW_sort_type_xSort
Definition: srw.h:76
#define Z_SRW_searchRetrieve_request
Definition: srw.h:191
const char * yaz_srw_pack_to_str(int pack)
Definition: srwutil.c:1210
Z_SRW_PDU * yaz_srw_get_core_v_2_0(ODR o)
Definition: srwutil.c:750
Z_SRW_record * yaz_srw_get_record(ODR o)
Definition: srwutil.c:733
Definition: srw.h:200
char * srw_version
Definition: srw.h:212
Z_SRW_extra_arg * extra_args
Definition: srw.h:219
char * packing
Definition: srw.h:117
char * database
Definition: srw.h:118
char * stylesheet
Definition: srw.h:119
char * recordPacking
Definition: srw.h:116
Z_SRW_diagnostic * diagnostics
Definition: srw.h:124
Z_SRW_record record
Definition: srw.h:123
Z_SRW_extra_record * extra_record
Definition: srw.h:126
char * value
Definition: srw.h:174
Z_SRW_extra_arg * next
Definition: srw.h:175
char * name
Definition: srw.h:173
int extraRecordData_len
Definition: srw.h:46
char * extraRecordData_buf
Definition: srw.h:45
char * recordIdentifier
Definition: srw.h:47
char * versionValue
Definition: srw.h:155
char * versionType
Definition: srw.h:154
char * recordData_buf
Definition: srw.h:58
int recordPacking
Definition: srw.h:53
char * recordSchema
Definition: srw.h:51
int recordData_len
Definition: srw.h:59
Odr_int * recordPosition
Definition: srw.h:60
Odr_int * responsePosition
Definition: srw.h:132
Odr_int * maximumTerms
Definition: srw.h:133
char * queryType
Definition: srw.h:130
char * scanClause
Definition: srw.h:131
char * stylesheet
Definition: srw.h:134
char * database
Definition: srw.h:135
Z_SRW_diagnostic * diagnostics
Definition: srw.h:148
Z_SRW_scanTerm * terms
Definition: srw.h:146
int num_diagnostics
Definition: srw.h:149
char * displayTerm
Definition: srw.h:141
char * whereInList
Definition: srw.h:142
Odr_int * numberOfRecords
Definition: srw.h:140
char * value
Definition: srw.h:139
Odr_int * resultSetTTL
Definition: srw.h:93
Z_FacetList * facetList
Definition: srw.h:94
Odr_int * maximumRecords
Definition: srw.h:84
Odr_int * startRecord
Definition: srw.h:83
union Z_SRW_searchRetrieveRequest::@29 sort
Z_SRW_record * records
Definition: srw.h:103
Odr_int * numberOfRecords
Definition: srw.h:98
Z_SRW_diagnostic * diagnostics
Definition: srw.h:106
char * resultCountPrecision
Definition: srw.h:99
Odr_int * nextRecordPosition
Definition: srw.h:108
Odr_int * resultSetIdleTime
Definition: srw.h:101
Z_SRW_extra_record ** extra_records
Definition: srw.h:110
Z_FacetList * facetList
Definition: srw.h:111
char * database
Definition: srw.h:159
int extraRequestData_len
Definition: srw.h:167
char * operation
Definition: srw.h:160
char * stylesheet
Definition: srw.h:168
char * recordId
Definition: srw.h:161
Z_SRW_extra_record * extra_record
Definition: srw.h:165
Z_SRW_recordVersion * recordVersions
Definition: srw.h:162
int num_recordVersions
Definition: srw.h:163
Z_SRW_record * record
Definition: srw.h:164
char * extraRequestData_buf
Definition: srw.h:166
char * operationStatus
Definition: srw.h:179
int num_diagnostics
Definition: srw.h:188
char * recordId
Definition: srw.h:180
Z_SRW_diagnostic * diagnostics
Definition: srw.h:187
Z_SRW_record * record
Definition: srw.h:183
int extraResponseData_len
Definition: srw.h:186
int num_recordVersions
Definition: srw.h:182
Z_SRW_recordVersion * recordVersions
Definition: srw.h:181
char * extraResponseData_buf
Definition: srw.h:185
Z_SRW_extra_record * extra_record
Definition: srw.h:184
Definition: odr.h:125
int direction
Definition: odr.h:126
Header for WRBUF (growing buffer)