2 * Copyright (C) 1995-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srw.c,v 1.53 2006-12-07 19:06:11 adam Exp $
9 * \brief Implements SRW/SRU package encoding and decoding
14 #include <libxml/parser.h>
15 #include <libxml/tree.h>
18 static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len,
23 xmlDocPtr doc = xmlParseMemory(val,len);
26 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
27 xmlNodePtr t = xmlDocGetRootElement(doc);
28 xmlAddChild(c, xmlCopyNode(t,1));
34 xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
39 xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0);
40 xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len);
47 xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val,
52 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
53 xmlNodePtr t = xmlNewText(BAD_CAST val);
60 xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
62 return add_xsd_string_ns(ptr, elem, val, 0);
65 static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val)
70 sprintf(str, "%d", *val);
71 xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str);
75 static int match_element(xmlNodePtr ptr, const char *elem)
77 if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem))
86 static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
90 struct _xmlAttr *attr;
92 if (!match_element(ptr, elem))
95 for (attr = ptr->properties; attr; attr = attr->next)
96 if (!strcmp(attr->name, "type") &&
97 attr->children && attr->children->type == XML_TEXT_NODE)
99 const char *t = strchr(attr->children->content, ':');
103 t = attr->children->content;
104 if (!strcmp(t, "string"))
111 if (!ptr || ptr->type != XML_TEXT_NODE)
116 *val = odr_strdup(o, (const char *) ptr->content);
118 *len = xmlStrlen(ptr->content);
123 static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
126 return match_xsd_string_n(ptr, elem, o, val, 0);
129 static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
130 char **val, int *len)
135 if (!match_element(ptr, elem))
139 while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE))
144 /* copy node to get NS right (bug #740). */
145 tmp = xmlCopyNode(ptr, 1);
147 buf = xmlBufferCreate();
149 xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
153 *val = odr_malloc(o, buf->use+1);
154 memcpy (*val, buf->content, buf->use);
155 (*val)[buf->use] = '\0';
165 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
168 struct _xmlAttr *attr;
170 if (!match_element(ptr, elem))
173 for (attr = ptr->properties; attr; attr = attr->next)
174 if (!strcmp(attr->name, "type") &&
175 attr->children && attr->children->type == XML_TEXT_NODE)
177 const char *t = strchr(attr->children->content, ':');
181 t = attr->children->content;
182 if (!strcmp(t, "integer"))
189 if (!ptr || ptr->type != XML_TEXT_NODE)
191 *val = odr_intdup(o, atoi((const char *) ptr->content));
195 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
196 Z_SRW_extra_record **extra,
197 void *client_data, const char *ns)
199 if (o->direction == ODR_DECODE)
201 Z_SRW_extra_record ex;
204 int pack = Z_SRW_recordPacking_string;
206 xmlNodePtr data_ptr = 0;
207 rec->recordSchema = 0;
208 rec->recordData_buf = 0;
209 rec->recordData_len = 0;
210 rec->recordPosition = 0;
213 ex.extraRecordData_buf = 0;
214 ex.extraRecordData_len = 0;
215 ex.recordIdentifier = 0;
217 for (ptr = pptr->children; ptr; ptr = ptr->next)
220 if (match_xsd_string(ptr, "recordSchema", o,
223 else if (match_xsd_string(ptr, "recordPacking", o, &spack))
225 if (spack && !strcmp(spack, "xml"))
226 pack = Z_SRW_recordPacking_XML;
227 if (spack && !strcmp(spack, "url"))
228 pack = Z_SRW_recordPacking_URL;
229 if (spack && !strcmp(spack, "string"))
230 pack = Z_SRW_recordPacking_string;
232 else if (match_xsd_integer(ptr, "recordPosition", o,
233 &rec->recordPosition))
235 else if (match_element(ptr, "recordData"))
237 /* save position of Data until after the loop
238 then we will know the packing (hopefully), and
239 unpacking is done once
243 else if (match_xsd_XML_n(ptr, "extraRecordData", o,
244 &ex.extraRecordData_buf,
245 &ex.extraRecordData_len) )
247 else if (match_xsd_string(ptr, "recordIdentifier", o,
248 &ex.recordIdentifier))
256 case Z_SRW_recordPacking_XML:
257 match_xsd_XML_n(data_ptr, "recordData", o,
258 &rec->recordData_buf, &rec->recordData_len);
260 case Z_SRW_recordPacking_URL:
261 /* just store it as a string.
262 leave it to the backend to collect the document */
263 match_xsd_string_n(data_ptr, "recordData", o,
264 &rec->recordData_buf, &rec->recordData_len);
266 case Z_SRW_recordPacking_string:
267 match_xsd_string_n(data_ptr, "recordData", o,
268 &rec->recordData_buf, &rec->recordData_len);
272 rec->recordPacking = pack;
273 if (ex.extraRecordData_buf || ex.recordIdentifier)
275 *extra = (Z_SRW_extra_record *)
276 odr_malloc(o, sizeof(Z_SRW_extra_record));
277 memcpy(*extra, &ex, sizeof(Z_SRW_extra_record));
280 else if (o->direction == ODR_ENCODE)
282 xmlNodePtr ptr = pptr;
283 int pack = rec->recordPacking;
284 add_xsd_string(ptr, "recordSchema", rec->recordSchema);
288 case Z_SRW_recordPacking_string:
289 add_xsd_string(ptr, "recordPacking", "string");
290 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
291 rec->recordData_len);
293 case Z_SRW_recordPacking_XML:
294 add_xsd_string(ptr, "recordPacking", "xml");
295 add_XML_n(ptr, "recordData", rec->recordData_buf,
296 rec->recordData_len, 0);
298 case Z_SRW_recordPacking_URL:
299 add_xsd_string(ptr, "recordPacking", "url");
300 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
301 rec->recordData_len);
304 if (rec->recordPosition)
305 add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
308 if ((*extra)->recordIdentifier)
309 add_xsd_string(ptr, "recordIdentifier",
310 (*extra)->recordIdentifier);
311 if ((*extra)->extraRecordData_buf)
312 add_XML_n(ptr, "extraRecordData",
313 (*extra)->extraRecordData_buf,
314 (*extra)->extraRecordData_len, 0);
320 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
321 Z_SRW_extra_record ***extra,
322 int *num, void *client_data, const char *ns)
324 if (o->direction == ODR_DECODE)
329 for (ptr = pptr->children; ptr; ptr = ptr->next)
331 if (ptr->type == XML_ELEMENT_NODE &&
332 !xmlStrcmp(ptr->name, BAD_CAST "record"))
337 *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
338 *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
339 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
341 if (ptr->type == XML_ELEMENT_NODE &&
342 !xmlStrcmp(ptr->name, BAD_CAST "record"))
344 yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, ns);
349 else if (o->direction == ODR_ENCODE)
352 for (i = 0; i < *num; i++)
354 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
356 yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
363 static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec,
364 void *client_data, const char *ns)
366 if (o->direction == ODR_DECODE)
369 rec->versionType = 0;
370 rec->versionValue = 0;
371 for (ptr = pptr->children; ptr; ptr = ptr->next)
374 if (match_xsd_string(ptr, "versionType", o,
377 else if (match_xsd_string(ptr, "versionValue", o,
382 else if (o->direction == ODR_ENCODE)
384 xmlNodePtr ptr = pptr;
385 add_xsd_string(ptr, "versionType", rec->versionType);
386 add_xsd_string(ptr, "versionValue", rec->versionValue);
391 static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
392 Z_SRW_recordVersion **vers,
393 int *num, void *client_data, const char *ns)
395 if (o->direction == ODR_DECODE)
400 for (ptr = pptr->children; ptr; ptr = ptr->next)
402 if (ptr->type == XML_ELEMENT_NODE &&
403 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
408 *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers));
409 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
411 if (ptr->type == XML_ELEMENT_NODE &&
412 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
414 yaz_srw_version(o, ptr, *vers + i, client_data, ns);
419 else if (o->direction == ODR_ENCODE)
422 for (i = 0; i < *num; i++)
424 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version",
426 yaz_srw_version(o, rptr, (*vers)+i, client_data, ns);
432 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
433 int *num, void *client_data, const char *ns)
435 if (o->direction == ODR_DECODE)
440 for (ptr = pptr->children; ptr; ptr = ptr->next)
442 if (ptr->type == XML_ELEMENT_NODE &&
443 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
448 *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
449 for (i = 0; i < *num; i++)
452 (*recs)[i].details = 0;
453 (*recs)[i].message = 0;
455 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
457 if (ptr->type == XML_ELEMENT_NODE &&
458 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
462 (*recs)[i].details = 0;
463 (*recs)[i].message = 0;
464 for (rptr = ptr->children; rptr; rptr = rptr->next)
466 if (match_xsd_string(rptr, "uri", o,
469 else if (match_xsd_string(rptr, "details", o,
470 &(*recs)[i].details))
472 else if (match_xsd_string(rptr, "message", o,
473 &(*recs)[i].message))
480 else if (o->direction == ODR_ENCODE)
484 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1, BAD_CAST "diag" );
485 for (i = 0; i < *num; i++)
487 const char *std_diag = "info:srw/diagnostic/1/";
488 const char *ucp_diag = "info:srw/diagnostic/12/";
489 xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
490 BAD_CAST "diagnostic", 0);
491 add_xsd_string(rptr, "uri", (*recs)[i].uri);
492 if ((*recs)[i].message)
493 add_xsd_string(rptr, "message", (*recs)[i].message);
494 else if ((*recs)[i].uri )
496 if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
498 int no = atoi((*recs)[i].uri + strlen(std_diag));
499 const char *message = yaz_diag_srw_str(no);
501 add_xsd_string(rptr, "message", message);
503 else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
505 int no = atoi((*recs)[i].uri + strlen(ucp_diag));
506 const char *message = yaz_diag_sru_update_str(no);
508 add_xsd_string(rptr, "message", message);
511 add_xsd_string(rptr, "details", (*recs)[i].details);
517 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
518 void *client_data, const char *ns)
520 if (o->direction == ODR_DECODE)
524 term->numberOfRecords = 0;
525 term->displayTerm = 0;
526 term->whereInList = 0;
527 for (ptr = pptr->children; ptr; ptr = ptr->next)
529 if (match_xsd_string(ptr, "value", o, &term->value))
531 else if (match_xsd_integer(ptr, "numberOfRecords", o,
532 &term->numberOfRecords))
534 else if (match_xsd_string(ptr, "displayTerm", o,
537 else if (match_xsd_string(ptr, "whereInList", o,
542 else if (o->direction == ODR_ENCODE)
544 xmlNodePtr ptr = pptr;
545 add_xsd_string(ptr, "value", term->value);
546 add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
547 add_xsd_string(ptr, "displayTerm", term->displayTerm);
548 add_xsd_string(ptr, "whereInList", term->whereInList);
553 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
554 int *num, void *client_data, const char *ns)
556 if (o->direction == ODR_DECODE)
561 for (ptr = pptr->children; ptr; ptr = ptr->next)
563 if (ptr->type == XML_ELEMENT_NODE &&
564 !xmlStrcmp(ptr->name, BAD_CAST "term"))
569 *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
570 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
572 if (ptr->type == XML_ELEMENT_NODE &&
573 !xmlStrcmp(ptr->name, BAD_CAST "term"))
574 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
577 else if (o->direction == ODR_ENCODE)
580 for (i = 0; i < *num; i++)
582 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
583 yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
589 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
590 void *client_data, const char *ns)
592 xmlNodePtr pptr = (xmlNodePtr) vptr;
593 if (o->direction == ODR_DECODE)
595 Z_SRW_PDU **p = handler_data;
596 xmlNodePtr method = pptr->children;
598 while (method && method->type == XML_TEXT_NODE)
599 method = method->next;
603 if (method->type != XML_ELEMENT_NODE)
606 *p = yaz_srw_get_core_v_1_1(o);
608 if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
610 xmlNodePtr ptr = method->children;
611 Z_SRW_searchRetrieveRequest *req;
613 (*p)->which = Z_SRW_searchRetrieve_request;
614 req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
615 odr_malloc(o, sizeof(*req));
616 req->query_type = Z_SRW_query_type_cql;
618 req->sort_type = Z_SRW_sort_type_none;
620 req->startRecord = 0;
621 req->maximumRecords = 0;
622 req->recordSchema = 0;
623 req->recordPacking = 0;
624 req->recordXPath = 0;
625 req->resultSetTTL = 0;
629 for (; ptr; ptr = ptr->next)
631 if (match_xsd_string(ptr, "version", o,
634 else if (match_xsd_string(ptr, "query", o,
636 req->query_type = Z_SRW_query_type_cql;
637 else if (match_xsd_string(ptr, "pQuery", o,
639 req->query_type = Z_SRW_query_type_pqf;
640 else if (match_xsd_string(ptr, "xQuery", o,
642 req->query_type = Z_SRW_query_type_xcql;
643 else if (match_xsd_integer(ptr, "startRecord", o,
646 else if (match_xsd_integer(ptr, "maximumRecords", o,
647 &req->maximumRecords))
649 else if (match_xsd_string(ptr, "recordPacking", o,
650 &req->recordPacking))
652 else if (match_xsd_string(ptr, "recordSchema", o,
655 else if (match_xsd_string(ptr, "recordXPath", o,
658 else if (match_xsd_integer(ptr, "resultSetTTL", o,
661 else if (match_xsd_string(ptr, "sortKeys", o,
662 &req->sort.sortKeys))
663 req->sort_type = Z_SRW_sort_type_sort;
664 else if (match_xsd_string(ptr, "stylesheet", o,
667 else if (match_xsd_string(ptr, "database", o,
671 if (!req->query.cql && !req->query.pqf && !req->query.xcql)
673 /* should put proper diagnostic here */
677 else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
679 xmlNodePtr ptr = method->children;
680 Z_SRW_searchRetrieveResponse *res;
682 (*p)->which = Z_SRW_searchRetrieve_response;
683 res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
684 odr_malloc(o, sizeof(*res));
686 res->numberOfRecords = 0;
687 res->resultSetId = 0;
688 res->resultSetIdleTime = 0;
690 res->num_records = 0;
691 res->diagnostics = 0;
692 res->num_diagnostics = 0;
693 res->nextRecordPosition = 0;
695 for (; ptr; ptr = ptr->next)
697 if (match_xsd_string(ptr, "version", o,
700 else if (match_xsd_integer(ptr, "numberOfRecords", o,
701 &res->numberOfRecords))
703 else if (match_xsd_string(ptr, "resultSetId", o,
706 else if (match_xsd_integer(ptr, "resultSetIdleTime", o,
707 &res->resultSetIdleTime))
709 else if (match_element(ptr, "records"))
710 yaz_srw_records(o, ptr, &res->records,
712 &res->num_records, client_data, ns);
713 else if (match_xsd_integer(ptr, "nextRecordPosition", o,
714 &res->nextRecordPosition))
716 else if (match_element(ptr, "diagnostics"))
717 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
718 &res->num_diagnostics,
722 else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
724 Z_SRW_explainRequest *req;
725 xmlNodePtr ptr = method->children;
727 (*p)->which = Z_SRW_explain_request;
728 req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
729 odr_malloc(o, sizeof(*req));
730 req->recordPacking = 0;
733 for (; ptr; ptr = ptr->next)
735 if (match_xsd_string(ptr, "version", o,
738 else if (match_xsd_string(ptr, "stylesheet", o,
741 else if (match_xsd_string(ptr, "recordPacking", o,
742 &req->recordPacking))
744 else if (match_xsd_string(ptr, "database", o,
749 else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
751 Z_SRW_explainResponse *res;
752 xmlNodePtr ptr = method->children;
754 (*p)->which = Z_SRW_explain_response;
755 res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
756 odr_malloc(o, sizeof(*res));
757 res->diagnostics = 0;
758 res->num_diagnostics = 0;
759 res->record.recordSchema = 0;
760 res->record.recordData_buf = 0;
761 res->record.recordData_len = 0;
762 res->record.recordPosition = 0;
764 for (; ptr; ptr = ptr->next)
766 if (match_xsd_string(ptr, "version", o,
769 else if (match_element(ptr, "record"))
770 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
772 else if (match_element(ptr, "diagnostics"))
773 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
774 &res->num_diagnostics,
779 else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
781 Z_SRW_scanRequest *req;
782 xmlNodePtr ptr = method->children;
784 (*p)->which = Z_SRW_scan_request;
785 req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
786 odr_malloc(o, sizeof(*req));
787 req->query_type = Z_SRW_query_type_cql;
788 req->scanClause.cql = 0;
789 req->responsePosition = 0;
790 req->maximumTerms = 0;
794 for (; ptr; ptr = ptr->next)
796 if (match_xsd_string(ptr, "version", o,
799 else if (match_xsd_string(ptr, "scanClause", o,
800 &req->scanClause.cql))
802 else if (match_xsd_string(ptr, "pScanClause", o,
803 &req->scanClause.pqf))
805 req->query_type = Z_SRW_query_type_pqf;
807 else if (match_xsd_integer(ptr, "responsePosition", o,
808 &req->responsePosition))
810 else if (match_xsd_integer(ptr, "maximumTerms", o,
813 else if (match_xsd_string(ptr, "stylesheet", o,
816 else if (match_xsd_string(ptr, "database", o,
821 else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
823 Z_SRW_scanResponse *res;
824 xmlNodePtr ptr = method->children;
826 (*p)->which = Z_SRW_scan_response;
827 res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
828 odr_malloc(o, sizeof(*res));
831 res->diagnostics = 0;
832 res->num_diagnostics = 0;
834 for (; ptr; ptr = ptr->next)
836 if (match_xsd_string(ptr, "version", o,
839 else if (match_element(ptr, "terms"))
840 yaz_srw_terms(o, ptr, &res->terms,
841 &res->num_terms, client_data,
843 else if (match_element(ptr, "diagnostics"))
844 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
845 &res->num_diagnostics,
855 else if (o->direction == ODR_ENCODE)
857 Z_SRW_PDU **p = handler_data;
860 if ((*p)->which == Z_SRW_searchRetrieve_request)
862 Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
863 xmlNodePtr ptr = xmlNewChild(pptr, 0,
864 BAD_CAST "searchRetrieveRequest", 0);
865 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
866 xmlSetNs(ptr, ns_srw);
868 if ((*p)->srw_version)
869 add_xsd_string(ptr, "version", (*p)->srw_version);
870 switch(req->query_type)
872 case Z_SRW_query_type_cql:
873 add_xsd_string(ptr, "query", req->query.cql);
875 case Z_SRW_query_type_xcql:
876 add_xsd_string(ptr, "xQuery", req->query.xcql);
878 case Z_SRW_query_type_pqf:
879 add_xsd_string(ptr, "pQuery", req->query.pqf);
882 add_xsd_integer(ptr, "startRecord", req->startRecord);
883 add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
884 add_xsd_string(ptr, "recordPacking", req->recordPacking);
885 add_xsd_string(ptr, "recordSchema", req->recordSchema);
886 add_xsd_string(ptr, "recordXPath", req->recordXPath);
887 add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
888 switch(req->sort_type)
890 case Z_SRW_sort_type_none:
892 case Z_SRW_sort_type_sort:
893 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
895 case Z_SRW_sort_type_xSort:
896 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
899 add_xsd_string(ptr, "stylesheet", req->stylesheet);
900 add_xsd_string(ptr, "database", req->database);
902 else if ((*p)->which == Z_SRW_searchRetrieve_response)
904 Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
905 xmlNodePtr ptr = xmlNewChild(pptr, 0,
906 BAD_CAST "searchRetrieveResponse", 0);
907 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
908 xmlSetNs(ptr, ns_srw);
910 if ((*p)->srw_version)
911 add_xsd_string(ptr, "version", (*p)->srw_version);
912 add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
913 add_xsd_string(ptr, "resultSetId", res->resultSetId);
914 add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
915 if (res->num_records)
917 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
918 yaz_srw_records(o, rptr, &res->records, &res->extra_records,
922 add_xsd_integer(ptr, "nextRecordPosition",
923 res->nextRecordPosition);
924 if (res->num_diagnostics)
926 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
928 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
929 &res->num_diagnostics, client_data, ns);
932 else if ((*p)->which == Z_SRW_explain_request)
934 Z_SRW_explainRequest *req = (*p)->u.explain_request;
935 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest",
937 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
938 xmlSetNs(ptr, ns_srw);
940 add_xsd_string(ptr, "version", (*p)->srw_version);
941 add_xsd_string(ptr, "recordPacking", req->recordPacking);
942 add_xsd_string(ptr, "stylesheet", req->stylesheet);
943 add_xsd_string(ptr, "database", req->database);
945 else if ((*p)->which == Z_SRW_explain_response)
947 Z_SRW_explainResponse *res = (*p)->u.explain_response;
948 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse",
950 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
951 xmlSetNs(ptr, ns_srw);
953 add_xsd_string(ptr, "version", (*p)->srw_version);
956 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
957 yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
960 if (res->num_diagnostics)
962 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
964 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
965 &res->num_diagnostics, client_data, ns);
968 else if ((*p)->which == Z_SRW_scan_request)
970 Z_SRW_scanRequest *req = (*p)->u.scan_request;
971 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
972 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
973 xmlSetNs(ptr, ns_srw);
975 add_xsd_string(ptr, "version", (*p)->srw_version);
976 switch(req->query_type)
978 case Z_SRW_query_type_cql:
979 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
981 case Z_SRW_query_type_pqf:
982 add_xsd_string(ptr, "pScanClause", req->scanClause.pqf);
985 add_xsd_integer(ptr, "responsePosition", req->responsePosition);
986 add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
987 add_xsd_string(ptr, "stylesheet", req->stylesheet);
988 add_xsd_string(ptr, "database", req->database);
990 else if ((*p)->which == Z_SRW_scan_response)
992 Z_SRW_scanResponse *res = (*p)->u.scan_response;
993 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
994 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
995 xmlSetNs(ptr, ns_srw);
997 add_xsd_string(ptr, "version", (*p)->srw_version);
1001 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
1002 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
1005 if (res->num_diagnostics)
1007 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1009 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1010 &res->num_diagnostics, client_data, ns);
1020 int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1021 void *client_data, const char *ns_ucp_str)
1023 xmlNodePtr pptr = (xmlNodePtr) vptr;
1024 const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1;
1025 if (o->direction == ODR_DECODE)
1027 Z_SRW_PDU **p = handler_data;
1028 xmlNodePtr method = pptr->children;
1030 while (method && method->type == XML_TEXT_NODE)
1031 method = method->next;
1035 if (method->type != XML_ELEMENT_NODE)
1038 *p = yaz_srw_get_core_v_1_1(o);
1040 if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1042 xmlNodePtr ptr = method->children;
1043 Z_SRW_updateRequest *req;
1046 (*p)->which = Z_SRW_update_request;
1047 req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1048 odr_malloc(o, sizeof(*req));
1052 req->recordVersions = 0;
1053 req->num_recordVersions = 0;
1055 req->extra_record = 0;
1056 req->extraRequestData_buf = 0;
1057 req->extraRequestData_len = 0;
1058 req->stylesheet = 0;
1060 for (; ptr; ptr = ptr->next)
1062 if (match_xsd_string(ptr, "version", o,
1063 &(*p)->srw_version))
1065 else if (match_xsd_string(ptr, "action", o,
1068 if ( !strcmp(oper, "info:srw/action/1/delete"))
1069 req->operation = "delete";
1070 else if (!strcmp(oper,"info:srw/action/1/replace" ))
1071 req->operation = "replace";
1072 else if ( !strcmp( oper, "info:srw/action/1/create"))
1073 req->operation = "insert";
1076 else if (match_xsd_string(ptr, "recordIdentifier", o,
1079 else if (match_element(ptr, "recordVersions" ) )
1080 yaz_srw_versions( o, ptr, &req->recordVersions,
1081 &req->num_recordVersions, client_data,
1083 else if (match_element(ptr, "record"))
1085 req->record = yaz_srw_get_record(o);
1086 yaz_srw_record(o, ptr, req->record, &req->extra_record,
1087 client_data, ns_ucp_str);
1089 else if (match_xsd_string(ptr, "stylesheet", o,
1092 else if (match_xsd_string(ptr, "database", o,
1097 else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1099 xmlNodePtr ptr = method->children;
1100 Z_SRW_updateResponse *res;
1102 (*p)->which = Z_SRW_update_response;
1103 res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1104 odr_malloc(o, sizeof(*res));
1106 res->operationStatus = 0;
1108 res->recordVersions = 0;
1109 res->num_recordVersions = 0;
1110 res->diagnostics = 0;
1111 res->num_diagnostics = 0;
1113 res->extra_record = 0;
1114 res->extraResponseData_buf = 0;
1115 res->extraResponseData_len = 0;
1117 for (; ptr; ptr = ptr->next)
1119 if (match_xsd_string(ptr, "version", o,
1120 &(*p)->srw_version))
1122 else if (match_xsd_string(ptr, "operationStatus", o,
1123 &res->operationStatus ))
1125 else if (match_xsd_string(ptr, "recordIdentifier", o,
1128 else if (match_element(ptr, "recordVersions" ))
1129 yaz_srw_versions(o, ptr, &res->recordVersions,
1130 &res->num_recordVersions,
1131 client_data, ns_ucp_str);
1132 else if (match_element(ptr, "record"))
1134 res->record = yaz_srw_get_record(o);
1135 yaz_srw_record(o, ptr, res->record, &res->extra_record,
1136 client_data, ns_ucp_str);
1138 else if (match_element(ptr, "diagnostics"))
1139 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1140 &res->num_diagnostics,
1141 client_data, ns_ucp_str);
1144 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1147 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1156 else if (o->direction == ODR_ENCODE)
1158 Z_SRW_PDU **p = handler_data;
1159 xmlNsPtr ns_ucp, ns_srw;
1162 if ((*p)->which == Z_SRW_update_request)
1164 Z_SRW_updateRequest *req = (*p)->u.update_request;
1165 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1166 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1167 xmlSetNs(ptr, ns_ucp);
1168 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1170 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1171 add_xsd_string(ptr, "action", req->operation);
1172 add_xsd_string(ptr, "recordIdentifier", req->recordId );
1173 if (req->recordVersions)
1174 yaz_srw_versions( o, ptr, &req->recordVersions,
1175 &req->num_recordVersions,
1176 client_data, ns_ucp_str);
1177 if (req->record && req->record->recordData_len)
1179 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1180 xmlSetNs(rptr, ns_srw);
1181 yaz_srw_record(o, rptr, req->record, &req->extra_record,
1182 client_data, ns_ucp_str);
1184 if (req->extraRequestData_len)
1186 add_XML_n(ptr, "extraRequestData",
1187 req->extraRequestData_buf,
1188 req->extraRequestData_len, ns_srw);
1190 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1191 add_xsd_string(ptr, "database", req->database);
1193 else if ((*p)->which == Z_SRW_update_response)
1195 Z_SRW_updateResponse *res = (*p)->u.update_response;
1196 xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1197 "updateResponse", 0);
1198 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1199 xmlSetNs(ptr, ns_ucp);
1200 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1202 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1203 add_xsd_string(ptr, "operationStatus", res->operationStatus );
1204 add_xsd_string(ptr, "recordIdentifier", res->recordId );
1205 if (res->recordVersions)
1206 yaz_srw_versions(o, ptr, &res->recordVersions,
1207 &res->num_recordVersions,
1208 client_data, ns_ucp_str);
1209 if (res->record && res->record->recordData_len)
1211 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1212 xmlSetNs(rptr, ns_srw);
1213 yaz_srw_record(o, rptr, res->record, &res->extra_record,
1214 client_data, ns_ucp_str);
1216 if (res->num_diagnostics)
1219 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1,
1222 xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0);
1223 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1224 &res->num_diagnostics, client_data,
1227 if (res->extraResponseData_len)
1228 add_XML_n(ptr, "extraResponseData",
1229 res->extraResponseData_buf,
1230 res->extraResponseData_len, ns_srw);
1245 * indent-tabs-mode: nil
1247 * vim: shiftwidth=4 tabstop=8 expandtab