Added whereInList member to SRW Scan Term
[yaz-moved-to-github.git] / src / srw.c
1 /*
2  * Copyright (c) 2002-2005, Index Data.
3  * See the file LICENSE for details.
4  *
5  * $Id: srw.c,v 1.30 2005-01-09 21:52:49 adam Exp $
6  */
7 /**
8  * \file srw.c
9  * \brief Implements SRW/SRU package encoding and decoding
10  */
11
12 #include <yaz/srw.h>
13
14 #if HAVE_XML2
15 #include <libxml/parser.h>
16 #include <libxml/tree.h>
17
18 static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len)
19 {
20     if (val)
21     {
22         xmlDocPtr doc = xmlParseMemory(val,len);
23         if (doc)
24         {
25             xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0);
26             xmlNodePtr t = xmlDocGetRootElement(doc);
27             xmlAddChild(c, xmlCopyNode(t,1));
28             xmlFreeDoc(doc);
29         }
30     }
31 }
32
33 xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
34                             int len)
35 {
36     if (val)
37     {
38         xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0);
39         xmlNodePtr t = xmlNewTextLen(val, len);
40         xmlAddChild(c, t);
41         return t;
42     }
43     return 0;
44 }
45
46 xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
47 {
48     if (val)
49         return xmlNewTextChild(ptr, 0, elem, val);
50     return 0;
51 }
52
53 static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val)
54 {
55     if (val)
56     {
57         char str[30];
58         sprintf(str, "%d", *val);
59         xmlNewTextChild(ptr, 0, elem, str);
60     }
61 }
62
63 static int match_element(xmlNodePtr ptr, const char *elem)
64 {
65     if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, elem))
66         return 1;
67     return 0;
68 }
69
70 #define CHECK_TYPE 0
71
72 static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
73                               char **val, int *len)
74 {
75 #if CHECK_TYPE
76     struct _xmlAttr *attr;
77 #endif
78     if (!match_element(ptr, elem))
79         return 0;
80 #if CHECK_TYPE
81     for (attr = ptr->properties; attr; attr = attr->next)
82         if (!strcmp(attr->name, "type") &&
83             attr->children && attr->children->type == XML_TEXT_NODE)
84         {
85             const char *t = strchr(attr->children->content, ':');
86             if (t)
87                 t = t + 1;
88             else
89                 t = attr->children->content;
90             if (!strcmp(t, "string"))
91                 break;
92         }
93     if (!attr)
94         return 0;
95 #endif
96     ptr = ptr->children;
97     if (!ptr || ptr->type != XML_TEXT_NODE)
98         return 0;
99     *val = odr_strdup(o, ptr->content);
100     if (len)
101         *len = strlen(ptr->content);
102     return 1;
103 }
104
105
106 static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
107                             char **val)
108 {
109     return match_xsd_string_n(ptr, elem, o, val, 0);
110 }
111
112 static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
113                            char **val, int *len)
114 {
115     xmlBufferPtr buf;
116
117     if (!match_element(ptr, elem))
118         return 0;
119     ptr = ptr->children;
120     while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE))
121         ptr = ptr->next;
122     if (!ptr)
123         return 0;
124     buf = xmlBufferCreate();
125     
126     xmlNodeDump(buf, ptr->doc, ptr, 0, 0);
127     
128     *val = odr_malloc(o, buf->use+1);
129     memcpy (*val, buf->content, buf->use);
130     (*val)[buf->use] = '\0';
131
132     if (len)
133         *len = buf->use;
134
135     xmlBufferFree(buf);
136
137     return 1;
138 }
139                      
140 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
141 {
142 #if CHECK_TYPE
143     struct _xmlAttr *attr;
144 #endif
145     if (!match_element(ptr, elem))
146         return 0;
147 #if CHECK_TYPE
148     for (attr = ptr->properties; attr; attr = attr->next)
149         if (!strcmp(attr->name, "type") &&
150             attr->children && attr->children->type == XML_TEXT_NODE)
151         {
152             const char *t = strchr(attr->children->content, ':');
153             if (t)
154                 t = t + 1;
155             else
156                 t = attr->children->content;
157             if (!strcmp(t, "integer"))
158                 break;
159         }
160     if (!attr)
161         return 0;
162 #endif
163     ptr = ptr->children;
164     if (!ptr || ptr->type != XML_TEXT_NODE)
165         return 0;
166     *val = odr_intdup(o, atoi(ptr->content));
167     return 1;
168 }
169
170 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
171                           void *client_data, const char *ns)
172 {
173     if (o->direction == ODR_DECODE)
174     {
175         int pack = Z_SRW_recordPacking_string;
176         xmlNodePtr ptr;
177         rec->recordSchema = 0;
178         rec->recordData_buf = 0;
179         rec->recordData_len = 0;
180         rec->recordPosition = 0;
181         for (ptr = pptr->children; ptr; ptr = ptr->next)
182         {
183             char *spack = 0;
184             
185             if (match_xsd_string(ptr, "recordSchema", o, 
186                                  &rec->recordSchema))
187                 ;
188             else if (match_xsd_string(ptr, "recordPacking", o, &spack))
189             {
190                 if (spack && !strcmp(spack, "xml"))
191                     pack = Z_SRW_recordPacking_XML;
192                 if (spack && !strcmp(spack, "string"))
193                     pack = Z_SRW_recordPacking_string;
194             }
195             else if (match_xsd_integer(ptr, "recordPosition", o, 
196                                        &rec->recordPosition))
197                 ;
198             else 
199             {
200                 if (pack == Z_SRW_recordPacking_XML)
201                     match_xsd_XML_n(ptr, "recordData", o, 
202                                     &rec->recordData_buf,
203                                     &rec->recordData_len);
204                 if (pack == Z_SRW_recordPacking_string)
205                     match_xsd_string_n(ptr, "recordData", o, 
206                                        &rec->recordData_buf,
207                                        &rec->recordData_len);
208             }
209         }
210         rec->recordPacking = pack;
211     }
212     else if (o->direction == ODR_ENCODE)
213     {
214         xmlNodePtr ptr = pptr;
215         add_xsd_string(ptr, "recordSchema", rec->recordSchema);
216         switch(rec->recordPacking)
217         {
218         case Z_SRW_recordPacking_string:
219             add_xsd_string(ptr, "recordPacking", "string");
220             add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
221                              rec->recordData_len);
222             break;
223         case Z_SRW_recordPacking_XML:
224             add_xsd_string(ptr, "recordPacking", "xml");
225             add_XML_n(ptr, "recordData", rec->recordData_buf,
226                       rec->recordData_len);
227             break;
228         }
229         add_xsd_integer(ptr, "recordPosition", rec->recordPosition);
230     }
231     return 0;
232 }
233
234 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
235                            int *num, void *client_data, const char *ns)
236 {
237     if (o->direction == ODR_DECODE)
238     {
239         int i;
240         xmlNodePtr ptr;
241         *num = 0;
242         for (ptr = pptr->children; ptr; ptr = ptr->next)
243         {
244             if (ptr->type == XML_ELEMENT_NODE &&
245                 !strcmp(ptr->name, "record"))
246                 (*num)++;
247         }
248         if (!*num)
249             return 1;
250         *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
251         for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
252         {
253             if (ptr->type == XML_ELEMENT_NODE &&
254                 !strcmp(ptr->name, "record"))
255             {
256                 yaz_srw_record(o, ptr, (*recs)+i, client_data, ns);
257                 i++;
258             }
259         }
260     }
261     else if (o->direction == ODR_ENCODE)
262     {
263         int i;
264         for (i = 0; i < *num; i++)
265         {
266             xmlNodePtr rptr = xmlNewChild(pptr, 0, "record", 0);
267             yaz_srw_record(o, rptr, (*recs)+i, client_data, ns);
268         }
269     }
270     return 0;
271 }
272
273 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
274                                int *num, void *client_data, const char *ns)
275 {
276     if (o->direction == ODR_DECODE)
277     {
278         int i;
279         xmlNodePtr ptr;
280         *num = 0;
281         for (ptr = pptr->children; ptr; ptr = ptr->next)
282         {
283             if (ptr->type == XML_ELEMENT_NODE &&
284                 !strcmp(ptr->name, "diagnostic"))
285                 (*num)++;
286         }
287         if (!*num)
288             return 1;
289         *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
290         for (i = 0; i < *num; i++)
291         {
292             (*recs)[i].uri = 0;
293             (*recs)[i].details = 0;
294             (*recs)[i].message = 0;
295         } 
296         for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
297         {
298             if (ptr->type == XML_ELEMENT_NODE &&
299                 !strcmp(ptr->name, "diagnostic"))
300             {
301                 xmlNodePtr rptr;
302                 (*recs)[i].uri = 0;
303                 (*recs)[i].details = 0;
304                 (*recs)[i].message = 0;
305                 for (rptr = ptr->children; rptr; rptr = rptr->next)
306                 {
307                     if (match_xsd_string(rptr, "uri", o, 
308                                          &(*recs)[i].uri))
309                         ;
310                     else if (match_xsd_string(rptr, "details", o, 
311                                               &(*recs)[i].details))
312                         ;
313                     else if (match_xsd_string(rptr, "message", o, 
314                                               &(*recs)[i].message))
315                         ;
316                 }
317                 i++;
318             }
319         }
320     }
321     else if (o->direction == ODR_ENCODE)
322     {
323         int i;
324         xmlNsPtr ns_diag =
325             xmlNewNs(pptr, "info:srw/schema/1/diagnostic-v1.1", 0);
326         for (i = 0; i < *num; i++)
327         {
328             const char *std_diag = "info:srw/diagnostic/1/";
329             xmlNodePtr rptr = xmlNewChild(pptr, ns_diag, "diagnostic", 0);
330             add_xsd_string(rptr, "uri", (*recs)[i].uri);
331             if ((*recs)[i].message)
332                 add_xsd_string(rptr, "message", (*recs)[i].message);
333             else if ((*recs)[i].uri && 
334                      !strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
335             {
336                 int no = atoi((*recs)[i].uri + strlen(std_diag));
337                 const char *message = yaz_diag_srw_str(no);
338                 if (message)
339                     add_xsd_string(rptr, "message", message);
340             }
341             add_xsd_string(rptr, "details", (*recs)[i].details);
342         }
343     }
344     return 0;
345 }
346
347 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
348                         void *client_data, const char *ns)
349 {
350     if (o->direction == ODR_DECODE)
351     {
352         xmlNodePtr ptr;
353         term->value = 0;
354         term->numberOfRecords = 0;
355         term->displayTerm = 0;
356         term->whereInList = 0;
357         for (ptr = pptr->children; ptr; ptr = ptr->next)
358         {
359             if (match_xsd_string(ptr, "value", o,  &term->value))
360                 ;
361             else if (match_xsd_integer(ptr, "numberOfRecords", o, 
362                                    &term->numberOfRecords))
363                 ;
364             else if (match_xsd_string(ptr, "displayTerm", o, 
365                                       &term->displayTerm))
366                 ;
367             else if (match_xsd_string(ptr, "whereInList", o, 
368                                       &term->whereInList))
369                 ;
370         }
371     }
372     else if (o->direction == ODR_ENCODE)
373     {
374         xmlNodePtr ptr = pptr;
375         add_xsd_string(ptr, "value", term->value);
376         add_xsd_integer(ptr, "value", term->numberOfRecords);
377         add_xsd_string(ptr, "displayTerm", term->displayTerm);
378         add_xsd_string(ptr, "whereInList", term->whereInList);
379     }
380     return 0;
381 }
382
383 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
384                          int *num, void *client_data, const char *ns)
385 {
386     if (o->direction == ODR_DECODE)
387     {
388         int i;
389         xmlNodePtr ptr;
390         *num = 0;
391         for (ptr = pptr->children; ptr; ptr = ptr->next)
392         {
393             if (ptr->type == XML_ELEMENT_NODE &&
394                 !strcmp(ptr->name, "term"))
395                 (*num)++;
396         }
397         if (!*num)
398             return 1;
399         *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
400         for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
401         {
402             if (ptr->type == XML_ELEMENT_NODE &&
403                 !strcmp(ptr->name, "term"))
404                 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
405         }
406     }
407     else if (o->direction == ODR_ENCODE)
408     {
409         int i;
410         for (i = 0; i < *num; i++)
411         {
412             xmlNodePtr rptr = xmlNewChild(pptr, 0, "term", 0);
413             yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
414         }
415     }
416     return 0;
417 }
418
419 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
420                   void *client_data, const char *ns)
421 {
422     xmlNodePtr pptr = (xmlNodePtr) vptr;
423     if (o->direction == ODR_DECODE)
424     {
425         Z_SRW_PDU **p = handler_data;
426         xmlNodePtr method = pptr->children;
427
428         while (method && method->type == XML_TEXT_NODE)
429             method = method->next;
430         
431         if (!method)
432             return -1;
433         if (method->type != XML_ELEMENT_NODE)
434             return -1;
435
436         *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(**p));
437         (*p)->srw_version = odr_strdup(o, "1.1");
438         
439         if (!strcmp(method->name, "searchRetrieveRequest"))
440         {
441             xmlNodePtr ptr = method->children;
442             Z_SRW_searchRetrieveRequest *req;
443
444             (*p)->which = Z_SRW_searchRetrieve_request;
445             req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
446                 odr_malloc(o, sizeof(*req));
447             req->query_type = Z_SRW_query_type_cql;
448             req->query.cql = 0;
449             req->sort_type = Z_SRW_sort_type_none;
450             req->sort.none = 0;
451             req->startRecord = 0;
452             req->maximumRecords = 0;
453             req->recordSchema = 0;
454             req->recordPacking = 0;
455             req->recordXPath = 0;
456             req->resultSetTTL = 0;
457             req->stylesheet = 0;
458             req->database = 0;
459
460             for (; ptr; ptr = ptr->next)
461             {
462                 if (match_xsd_string(ptr, "version", o,
463                                      &(*p)->srw_version))
464                     ;
465                 else if (match_xsd_string(ptr, "query", o, 
466                                      &req->query.cql))
467                     req->query_type = Z_SRW_query_type_cql;
468                 else if (match_xsd_string(ptr, "pQuery", o, 
469                                      &req->query.pqf))
470                     req->query_type = Z_SRW_query_type_pqf;
471                 else if (match_xsd_string(ptr, "xQuery", o, 
472                                      &req->query.xcql))
473                     req->query_type = Z_SRW_query_type_xcql;
474                 else if (match_xsd_integer(ptr, "startRecord", o,
475                                            &req->startRecord))
476                     ;
477                 else if (match_xsd_integer(ptr, "maximumRecords", o,
478                                            &req->maximumRecords))
479                     ;
480                 else if (match_xsd_string(ptr, "recordPacking", o,
481                                           &req->recordPacking))
482                     ;
483                 else if (match_xsd_string(ptr, "recordSchema", o, 
484                                           &req->recordSchema))
485                     ;
486                 else if (match_xsd_string(ptr, "recordXPath", o,
487                                           &req->recordXPath))
488                     ;
489                 else if (match_xsd_string(ptr, "resultSetTTL", o,
490                                            &req->database))
491                     ;
492                 else if (match_xsd_string(ptr, "sortKeys", o, 
493                                           &req->sort.sortKeys))
494                     req->sort_type = Z_SRW_sort_type_sort;
495                 else if (match_xsd_string(ptr, "stylesheet", o,
496                                            &req->stylesheet))
497                     ;
498                 else if (match_xsd_string(ptr, "database", o,
499                                            &req->database))
500                     ;
501                 /* missing is xQuery, xSortKeys .. */
502             }
503         }
504         else if (!strcmp(method->name, "searchRetrieveResponse"))
505         {
506             xmlNodePtr ptr = method->children;
507             Z_SRW_searchRetrieveResponse *res;
508
509             (*p)->which = Z_SRW_searchRetrieve_response;
510             res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
511                 odr_malloc(o, sizeof(*res));
512
513             res->numberOfRecords = 0;
514             res->resultSetId = 0;
515             res->resultSetIdleTime = 0;
516             res->records = 0;
517             res->num_records = 0;
518             res->diagnostics = 0;
519             res->num_diagnostics = 0;
520             res->nextRecordPosition = 0;
521
522             for (; ptr; ptr = ptr->next)
523             {
524                 if (match_xsd_string(ptr, "version", o,
525                                      &(*p)->srw_version))
526                     ;
527                 else if (match_xsd_integer(ptr, "numberOfRecords", o, 
528                                       &res->numberOfRecords))
529                     ;
530                 else if (match_xsd_string(ptr, "resultSetId", o, 
531                                           &res->resultSetId))
532                     ;
533                 else if (match_xsd_integer(ptr, "resultSetIdleTime", o, 
534                                            &res->resultSetIdleTime))
535                     ;
536                 else if (match_element(ptr, "records"))
537                     yaz_srw_records(o, ptr, &res->records,
538                                     &res->num_records, client_data,
539                                     ns);
540                 else if (match_xsd_integer(ptr, "nextRecordPosition", o,
541                                            &res->nextRecordPosition))
542                     ;
543                 else if (match_element(ptr, "diagnostics"))
544                     yaz_srw_diagnostics(o, ptr, &res->diagnostics,
545                                         &res->num_diagnostics,
546                                         client_data, ns);
547             }
548         }
549         else if (!strcmp(method->name, "explainRequest"))
550         {
551             Z_SRW_explainRequest *req;
552             xmlNodePtr ptr = method->children;
553             
554             (*p)->which = Z_SRW_explain_request;
555             req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
556                 odr_malloc(o, sizeof(*req));
557             req->recordPacking = 0;
558             req->database = 0;
559             req->stylesheet = 0;
560             for (; ptr; ptr = ptr->next)
561             {
562                 if (match_xsd_string(ptr, "version", o,
563                                            &(*p)->srw_version))
564                     ;
565                 else if (match_xsd_string(ptr, "stylesheet", o,
566                                           &req->stylesheet))
567                     ;
568                 else if (match_xsd_string(ptr, "recordPacking", o,
569                                      &req->recordPacking))
570                     ;
571                 else if (match_xsd_string(ptr, "database", o,
572                                      &req->database))
573                     ;
574             }
575         }
576         else if (!strcmp(method->name, "explainResponse"))
577         {
578             Z_SRW_explainResponse *res;
579             xmlNodePtr ptr = method->children;
580
581             (*p)->which = Z_SRW_explain_response;
582             res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
583                 odr_malloc(o, sizeof(*res));
584             res->diagnostics = 0;
585             res->num_diagnostics = 0;
586             res->record.recordSchema = 0;
587             res->record.recordData_buf = 0;
588             res->record.recordData_len = 0;
589             res->record.recordPosition = 0;
590
591             for (; ptr; ptr = ptr->next)
592             {
593                 if (match_xsd_string(ptr, "version", o,
594                                            &(*p)->srw_version))
595                     ;
596                 else if (match_element(ptr, "record"))
597                     yaz_srw_record(o, ptr, &res->record, client_data, ns);
598                 else if (match_element(ptr, "diagnostics"))
599                     yaz_srw_diagnostics(o, ptr, &res->diagnostics,
600                                         &res->num_diagnostics,
601                                         client_data, ns);
602                 ;
603             }
604         }
605         else if (!strcmp(method->name, "scanRequest"))
606         {
607             Z_SRW_scanRequest *req;
608             xmlNodePtr ptr = method->children;
609
610             (*p)->which = Z_SRW_scan_request;
611             req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
612                 odr_malloc(o, sizeof(*req));
613             req->query_type = Z_SRW_query_type_cql;
614             req->scanClause.cql = 0;
615             req->responsePosition = 0;
616             req->maximumTerms = 0;
617             req->stylesheet = 0;
618             req->database = 0;
619             
620             for (; ptr; ptr = ptr->next)
621             {
622                 if (match_xsd_string(ptr, "version", o,
623                                      &(*p)->srw_version))
624                     ;
625                 else if (match_xsd_string(ptr, "scanClause", o,
626                                      &req->scanClause.cql))
627                     ;
628                 else if (match_xsd_integer(ptr, "responsePosition", o,
629                                            &req->responsePosition))
630                     ;
631                 else if (match_xsd_integer(ptr, "maximumTerms", o,
632                                            &req->maximumTerms))
633                     ;
634                 else if (match_xsd_string(ptr, "stylesheet", o,
635                                           &req->stylesheet))
636                     ;
637                 else if (match_xsd_string(ptr, "database", o,
638                                           &req->database))
639                     ;
640             }
641         }
642         else if (!strcmp(method->name, "scanResponse"))
643         {
644             Z_SRW_scanResponse *res;
645             xmlNodePtr ptr = method->children;
646
647             (*p)->which = Z_SRW_scan_response;
648             res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
649                 odr_malloc(o, sizeof(*res));
650             res->terms = 0;
651             res->num_terms = 0;
652             res->diagnostics = 0;
653             res->num_diagnostics = 0;
654             
655             for (; ptr; ptr = ptr->next)
656             {
657                 if (match_xsd_string(ptr, "version", o,
658                                      &(*p)->srw_version))
659                     ;
660                 else if (match_element(ptr, "terms"))
661                     yaz_srw_terms(o, ptr, &res->terms,
662                                   &res->num_terms, client_data,
663                                   ns);
664                 else if (match_element(ptr, "diagnostics"))
665                     yaz_srw_diagnostics(o, ptr, &res->diagnostics,
666                                         &res->num_diagnostics,
667                                         client_data, ns);
668             }
669         }
670         else
671         {
672             *p = 0;
673             return -1;
674         }
675     }
676     else if (o->direction == ODR_ENCODE)
677     {
678         Z_SRW_PDU **p = handler_data;
679         xmlNsPtr ns_srw;
680         
681         if ((*p)->which == Z_SRW_searchRetrieve_request)
682         {
683             Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
684             xmlNodePtr ptr = xmlNewChild(pptr, 0,
685                                          "searchRetrieveRequest", 0);
686             ns_srw = xmlNewNs(ptr, ns, "zs");
687             xmlSetNs(ptr, ns_srw);
688
689             if ((*p)->srw_version)
690                 add_xsd_string(ptr, "version", (*p)->srw_version);
691             switch(req->query_type)
692             {
693             case Z_SRW_query_type_cql:
694                 add_xsd_string(ptr, "query", req->query.cql);
695                 break;
696             case Z_SRW_query_type_xcql:
697                 add_xsd_string(ptr, "xQuery", req->query.xcql);
698                 break;
699             case Z_SRW_query_type_pqf:
700                 add_xsd_string(ptr, "pQuery", req->query.pqf);
701                 break;
702             }
703             add_xsd_integer(ptr, "startRecord", req->startRecord);
704             add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
705             add_xsd_string(ptr, "recordPacking", req->recordPacking);
706             add_xsd_string(ptr, "recordSchema", req->recordSchema);
707             add_xsd_string(ptr, "recordXPath", req->recordXPath);
708             add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
709             switch(req->sort_type)
710             {
711             case Z_SRW_sort_type_none:
712                 break;
713             case Z_SRW_sort_type_sort:
714                 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
715                 break;
716             case Z_SRW_sort_type_xSort:
717                 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
718                 break;
719             }
720             add_xsd_string(ptr, "stylesheet", req->stylesheet);
721             add_xsd_string(ptr, "database", req->database);
722         }
723         else if ((*p)->which == Z_SRW_searchRetrieve_response)
724         {
725             Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
726             xmlNodePtr ptr = xmlNewChild(pptr, 0,
727                                          "searchRetrieveResponse", 0);
728             ns_srw = xmlNewNs(ptr, ns, "zs");
729             xmlSetNs(ptr, ns_srw);
730
731             if ((*p)->srw_version)
732                 add_xsd_string(ptr, "version", (*p)->srw_version);
733             add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
734             add_xsd_string(ptr, "resultSetId", res->resultSetId);
735             add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
736             if (res->num_records)
737             {
738                 xmlNodePtr rptr = xmlNewChild(ptr, 0, "records", 0);
739                 yaz_srw_records(o, rptr, &res->records, &res->num_records,
740                                 client_data, ns);
741             }
742             add_xsd_integer(ptr, "nextRecordPosition",
743                             res->nextRecordPosition);
744             if (res->num_diagnostics)
745             {
746                 xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0);
747                 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
748                                     &res->num_diagnostics, client_data, ns);
749             }
750         }
751         else if ((*p)->which == Z_SRW_explain_request)
752         {
753             Z_SRW_explainRequest *req = (*p)->u.explain_request;
754             xmlNodePtr ptr = xmlNewChild(pptr, 0, "explainRequest", 0);
755             ns_srw = xmlNewNs(ptr, ns, "zs");
756             xmlSetNs(ptr, ns_srw);
757
758             add_xsd_string(ptr, "version", (*p)->srw_version);
759             add_xsd_string(ptr, "recordPacking", req->recordPacking);
760             add_xsd_string(ptr, "stylesheet", req->stylesheet);
761             add_xsd_string(ptr, "database", req->database);
762         }
763         else if ((*p)->which == Z_SRW_explain_response)
764         {
765             Z_SRW_explainResponse *res = (*p)->u.explain_response;
766             xmlNodePtr ptr = xmlNewChild(pptr, 0, "explainResponse", 0);
767             ns_srw = xmlNewNs(ptr, ns, "zs");
768             xmlSetNs(ptr, ns_srw);
769
770             add_xsd_string(ptr, "version", (*p)->srw_version);
771             if (1)
772             {
773                 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, "record", 0);
774                 yaz_srw_record(o, ptr1, &res->record, client_data, ns);
775             }
776             if (res->num_diagnostics)
777             {
778                 xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0);
779                 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
780                                     &res->num_diagnostics, client_data, ns);
781             }
782         }
783         else if ((*p)->which == Z_SRW_scan_request)
784         {
785             Z_SRW_scanRequest *req = (*p)->u.scan_request;
786             xmlNodePtr ptr = xmlNewChild(pptr, 0, "scanRequest", 0);
787             ns_srw = xmlNewNs(ptr, ns, "zs");
788             xmlSetNs(ptr, ns_srw);
789
790             add_xsd_string(ptr, "version", (*p)->srw_version);
791             switch(req->query_type)
792             {
793             case Z_SRW_query_type_cql:
794                 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
795                 break;
796             case Z_SRW_query_type_pqf:
797                 add_xsd_string(ptr, "pScanClause", req->scanClause.pqf);
798                 break;
799             }
800             add_xsd_integer(ptr, "responsePosition", req->responsePosition);
801             add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
802             add_xsd_string(ptr, "stylesheet", req->stylesheet);
803             add_xsd_string(ptr, "database", req->database);
804         }
805         else if ((*p)->which == Z_SRW_scan_response)
806         {
807             Z_SRW_scanResponse *res = (*p)->u.scan_response;
808             xmlNodePtr ptr = xmlNewChild(pptr, 0, "scanResponse", 0);
809             ns_srw = xmlNewNs(ptr, ns, "zs");
810             xmlSetNs(ptr, ns_srw);
811
812             add_xsd_string(ptr, "version", (*p)->srw_version);
813
814             if (res->num_terms)
815             {
816                 xmlNodePtr rptr = xmlNewChild(ptr, 0, "terms", 0);
817                 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
818                               client_data, ns);
819             }
820             if (res->num_diagnostics)
821             {
822                 xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0);
823                 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
824                                     &res->num_diagnostics, client_data, ns);
825             }
826         }
827         else
828             return -1;
829
830     }
831     return 0;
832 }
833
834 #endif
835
836