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