X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fsrw.c;h=a9430b008707529d9dc86dd5859119e5612e90c8;hb=f6379872ace49628473c47d23b29e9f46b5afbe4;hp=474af627f8800c18d776fe7072d5621fa624b6cf;hpb=9a7cdcf5ae13e63eae0259f2a620119463e64f42;p=yaz-moved-to-github.git diff --git a/src/srw.c b/src/srw.c index 474af62..a9430b0 100644 --- a/src/srw.c +++ b/src/srw.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2005, Index Data ApS + * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: srw.c,v 1.38 2005-11-09 17:47:07 adam Exp $ + * $Id: srw.c,v 1.51 2006-11-30 22:58:06 adam Exp $ */ /** * \file srw.c @@ -10,9 +10,10 @@ */ #include -#if HAVE_XML2 +#if YAZ_HAVE_XML2 #include #include +#include static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len) { @@ -112,6 +113,46 @@ static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, return match_xsd_string_n(ptr, elem, o, val, 0); } + +/** \brief fixes NS for root node of record data (bug #740) */ +static void fixup_xmlns(xmlNodePtr ptr, ODR o) +{ + /* should go towards root and collect NS not defined in the record here! */ + xmlNodePtr p = ptr; + + while (p) + { + assert(p->type == XML_ELEMENT_NODE); + + p = p->parent; + while (p && p->type != XML_ELEMENT_NODE) + p = p->prev; + if (p) + { + xmlNsPtr ns = p->ns; + for (; ns; ns = ns->next) + { + xmlNsPtr n; + for (n = ptr->nsDef; n; n = n->next) + if ((n->prefix == 0 && ns->prefix == 0) + || (n->prefix && ns->prefix + && !strcmp((const char *) n->prefix, + (const char *) ns->prefix))) + { + break; + } + if (!n) + { + xmlNsPtr new_ns = xmlCopyNamespace(ns); + + new_ns->next = ptr->nsDef; + ptr->nsDef = new_ns; + } + } + } + } +} + static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len) { @@ -119,13 +160,17 @@ static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, if (!match_element(ptr, elem)) return 0; + ptr = ptr->children; while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE)) ptr = ptr->next; if (!ptr) return 0; + + fixup_xmlns(ptr, o); + buf = xmlBufferCreate(); - + xmlNodeDump(buf, ptr->doc, ptr, 0, 0); *val = odr_malloc(o, buf->use+1); @@ -188,6 +233,9 @@ static int yaz_srw_extra_record(ODR o, xmlNodePtr pptr, { if (match_xsd_string(ptr, "recordId", o, &rec->recordId )) + ; /* backward compatible */ + else if (match_xsd_string(ptr, "recordIdentifier", o, + &rec->recordId )) ; else if (match_xsd_string(ptr, "recordReviewCode", o, &rec->recordReviewCode )) @@ -210,7 +258,7 @@ static int yaz_srw_extra_record(ODR o, xmlNodePtr pptr, { xmlNodePtr ptr = pptr; if ( rec->recordId ) - add_xsd_string(ptr, "recordId", rec->recordId); + add_xsd_string(ptr, "recordIdentfier", rec->recordId); if ( rec->recordReviewCode ) add_xsd_string(ptr, "recordReviewCode", rec->recordReviewCode); if ( rec->recordReviewNote ) @@ -234,7 +282,7 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, char *spack = 0; int pack = Z_SRW_recordPacking_string; xmlNodePtr ptr; - xmlNodePtr data_ptr; + xmlNodePtr data_ptr = 0; rec->recordSchema = 0; rec->recordData_buf = 0; rec->recordData_len = 0; @@ -244,8 +292,8 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, { if (match_xsd_string(ptr, "recordSchema", o, - &rec->recordSchema)){ - } + &rec->recordSchema)) + ; else if (match_xsd_string(ptr, "recordPacking", o, &spack)) { if (spack && !strcmp(spack, "xml")) @@ -258,39 +306,40 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, else if (match_xsd_integer(ptr, "recordPosition", o, &rec->recordPosition)) ; - else if (match_element(ptr, "recordData")){ + else if (match_element(ptr, "recordData")) + { /* save position of Data until after the loop then we will know the packing (hopefully), and unpacking is done once */ data_ptr = ptr; } - else if (match_element(ptr, "extraRecordData")){ + else if (match_element(ptr, "extraRecordData")) + { *extra = (Z_SRW_extra_record *) odr_malloc(o, sizeof(Z_SRW_extra_record)); yaz_srw_extra_record(o, ptr, *extra, client_data, ns); } } - switch(pack) + if (data_ptr) { - case Z_SRW_recordPacking_XML: - match_xsd_XML_n(data_ptr, "recordData", o, - &rec->recordData_buf, &rec->recordData_len); - break; - case Z_SRW_recordPacking_URL: - /* just store it as a string. - leave it to the backend to collect the document */ - match_xsd_string_n(ptr, "recordData", o, - &rec->recordData_buf, &rec->recordData_len); - break; - case Z_SRW_recordPacking_string: - match_xsd_string_n(ptr, "recordData", o, - &rec->recordData_buf, &rec->recordData_len); - break; - default: - rec->recordData_buf = 0; - rec->recordData_len = 0; - /* need some way to signal diagnostic here */ + switch(pack) + { + case Z_SRW_recordPacking_XML: + match_xsd_XML_n(data_ptr, "recordData", o, + &rec->recordData_buf, &rec->recordData_len); + break; + case Z_SRW_recordPacking_URL: + /* just store it as a string. + leave it to the backend to collect the document */ + match_xsd_string_n(data_ptr, "recordData", o, + &rec->recordData_buf, &rec->recordData_len); + break; + case Z_SRW_recordPacking_string: + match_xsd_string_n(data_ptr, "recordData", o, + &rec->recordData_buf, &rec->recordData_len); + break; + } } rec->recordPacking = pack; } @@ -320,7 +369,7 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, } if (rec->recordPosition) add_xsd_integer(ptr, "recordPosition", rec->recordPosition ); - if (*extra) + if (extra && *extra) { xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "extraRecordData", 0); @@ -366,7 +415,8 @@ static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, { xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record", 0); - yaz_srw_record(o, rptr, (*recs)+i, *extra + i, client_data, ns); + yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0), + client_data, ns); } } return 0; @@ -429,18 +479,28 @@ static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, for (i = 0; i < *num; i++) { const char *std_diag = "info:srw/diagnostic/1/"; + const char *ucp_diag = "info:srw/diagnostic/12/"; xmlNodePtr rptr = xmlNewChild(pptr, ns_diag, BAD_CAST "diagnostic", 0); add_xsd_string(rptr, "uri", (*recs)[i].uri); if ((*recs)[i].message) add_xsd_string(rptr, "message", (*recs)[i].message); - else if ((*recs)[i].uri && - !strncmp((*recs)[i].uri, std_diag, strlen(std_diag))) + else if ((*recs)[i].uri ) { - int no = atoi((*recs)[i].uri + strlen(std_diag)); - const char *message = yaz_diag_srw_str(no); - if (message) - add_xsd_string(rptr, "message", message); + if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag))) + { + int no = atoi((*recs)[i].uri + strlen(std_diag)); + const char *message = yaz_diag_srw_str(no); + if (message) + add_xsd_string(rptr, "message", message); + } + else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag))) + { + int no = atoi((*recs)[i].uri + strlen(ucp_diag)); + const char *message = yaz_diag_sru_update_str(no); + if (message) + add_xsd_string(rptr, "message", message); + } } add_xsd_string(rptr, "details", (*recs)[i].details); } @@ -537,8 +597,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (method->type != XML_ELEMENT_NODE) return -1; - *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(**p)); - (*p)->srw_version = odr_strdup(o, "1.1"); + *p = yaz_srw_get_core_v_1_1(o); if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest")) { @@ -590,8 +649,8 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (match_xsd_string(ptr, "recordXPath", o, &req->recordXPath)) ; - else if (match_xsd_string(ptr, "resultSetTTL", o, - &req->database)) + else if (match_xsd_integer(ptr, "resultSetTTL", o, + &req->resultSetTTL)) ; else if (match_xsd_string(ptr, "sortKeys", o, &req->sort.sortKeys)) @@ -602,7 +661,11 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (match_xsd_string(ptr, "database", o, &req->database)) ; - /* missing is xQuery, xSortKeys .. */ + } + if (!req->query.cql && !req->query.pqf && !req->query.xcql) + { + /* should put proper diagnostic here */ + return -1; } } else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse")) @@ -965,8 +1028,7 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (method->type != XML_ELEMENT_NODE) return -1; - *p = (Z_SRW_PDU *) odr_malloc(o, sizeof(**p)); - (*p)->srw_version = odr_strdup(o, "1.1"); + *p = yaz_srw_get_core_v_1_1(o); if (!xmlStrcmp(method->name, BAD_CAST "updateRequest")) { @@ -997,6 +1059,7 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, ; else if (match_xsd_string(ptr, "operation", o, &oper)){ + /* backward compatible */ if ( oper ){ if ( !strcmp(oper, "delete")) req->operation = "delete"; @@ -1006,8 +1069,22 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->operation = "insert"; } } + else if (match_xsd_string(ptr, "action", o, + &oper)){ + if ( oper ){ + if ( !strcmp(oper, "info:srw/action/1/delete")) + req->operation = "delete"; + else if (!strcmp(oper,"info:srw/action/1/replace" )) + req->operation = "replace"; + else if ( !strcmp( oper, "info:srw/action/1/create")) + req->operation = "insert"; + } + } else if (match_xsd_string(ptr, "recordId", o, &req->recordId)) + ; /* backward compatible */ + else if (match_xsd_string(ptr, "recordIdentifier", o, + &req->recordId)) ; else if (match_xsd_string(ptr, "recordVersion", o, &req->recordVersion)) @@ -1055,6 +1132,9 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, ; else if (match_xsd_string(ptr, "recordId", o, &res->recordId)) + ; /* backward compatible */ + else if (match_xsd_string(ptr, "recordIdentifier", o, + &res->recordId)) ; else if (match_xsd_string(ptr, "recordVersion", o, &res->recordVersion )) @@ -1088,8 +1168,8 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if ((*p)->which == Z_SRW_update_request) { Z_SRW_updateRequest *req = (*p)->u.update_request; - xmlNodePtr ptr = xmlNewChild(pptr, 0, "updateRequest", 0); - ns_srw = xmlNewNs(ptr, ns, "zu"); + xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0); + ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu"); xmlSetNs(ptr, ns_srw); add_xsd_string(ptr, "version", (*p)->srw_version); @@ -1099,26 +1179,27 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_update_response) { Z_SRW_updateResponse *res = (*p)->u.update_response; - xmlNodePtr ptr = xmlNewChild(pptr, 0, "updateResponse", 0); - ns_srw = xmlNewNs(ptr, ns, "zu"); + xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *) + "updateResponse", 0); + ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu"); xmlSetNs(ptr, ns_srw); add_xsd_string(ptr, "version", (*p)->srw_version); add_xsd_string(ptr, "operationStatus", res->operationStatus ); - add_xsd_string(ptr, "recordId", res->recordId ); + add_xsd_string(ptr, "recordIdentifier", res->recordId ); if (res->recordVersion) add_xsd_string(ptr, "recordVersion", res->recordVersion ); if (res->recordChecksum) add_xsd_string(ptr, "recordChecksum", res->recordChecksum ); if (res->record.recordData_len) { - xmlNodePtr rptr = xmlNewChild(ptr, 0, "record", 0); + xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0); yaz_srw_record(o, rptr, &res->record, &res->extra_record, client_data, ns); } if (res->num_diagnostics) { - xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0); + xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics", 0); yaz_srw_diagnostics(o, rptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); }