00001
00002
00003
00004
00005
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <assert.h>
00013
00014 #if YAZ_HAVE_XML2
00015 #include <libxml/parser.h>
00016 #include <libxml/tree.h>
00017
00018 #include <yaz/logrpn.h>
00019 #include <yaz/xmlquery.h>
00020 #include <yaz/nmem_xml.h>
00021 #include <yaz/oid_db.h>
00022
00023 void yaz_query2xml_attribute_element(const Z_AttributeElement *element,
00024 xmlNodePtr parent)
00025 {
00026 char formstr[30];
00027 const char *setname = 0;
00028 char oid_name_str[OID_STR_MAX];
00029
00030 if (element->attributeSet)
00031 {
00032 setname = yaz_oid_to_string_buf(element->attributeSet,
00033 0, oid_name_str);
00034 }
00035
00036 if (element->which == Z_AttributeValue_numeric)
00037 {
00038 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
00039
00040 if (setname)
00041 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
00042
00043 sprintf(formstr, "%d", *element->attributeType);
00044 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
00045
00046 sprintf(formstr, "%d", *element->value.numeric);
00047 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
00048 }
00049 else if (element->which == Z_AttributeValue_complex)
00050 {
00051 int i;
00052 for (i = 0; i<element->value.complex->num_list; i++)
00053 {
00054 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
00055
00056 if (setname)
00057 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
00058
00059 sprintf(formstr, "%d", *element->attributeType);
00060 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
00061
00062 if (element->value.complex->list[i]->which ==
00063 Z_StringOrNumeric_string)
00064 {
00065 xmlNewProp(node, BAD_CAST "value", BAD_CAST
00066 element->value.complex->list[i]->u.string);
00067 }
00068 else if (element->value.complex->list[i]->which ==
00069 Z_StringOrNumeric_numeric)
00070 {
00071 sprintf(formstr, "%d",
00072 *element->value.complex->list[i]->u.numeric);
00073 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
00074 }
00075 }
00076 }
00077 }
00078
00079
00080 xmlNodePtr yaz_query2xml_term(const Z_Term *term,
00081 xmlNodePtr parent)
00082 {
00083 xmlNodePtr t = 0;
00084 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "term", 0);
00085 char formstr[20];
00086 const char *type = 0;
00087
00088 switch (term->which)
00089 {
00090 case Z_Term_general:
00091 type = "general";
00092 t = xmlNewTextLen(BAD_CAST term->u.general->buf, term->u.general->len);
00093 break;
00094 case Z_Term_numeric:
00095 type = "numeric";
00096 sprintf(formstr, "%d", *term->u.numeric);
00097 t = xmlNewText(BAD_CAST formstr);
00098 break;
00099 case Z_Term_characterString:
00100 type = "string";
00101 t = xmlNewText(BAD_CAST term->u.characterString);
00102 break;
00103 case Z_Term_oid:
00104 type = "oid";
00105 break;
00106 case Z_Term_dateTime:
00107 type = "dateTime";
00108 break;
00109 case Z_Term_external:
00110 type = "external";
00111 break;
00112 case Z_Term_integerAndUnit:
00113 type ="integerAndUnit";
00114 break;
00115 case Z_Term_null:
00116 type = "null";
00117 break;
00118 default:
00119 break;
00120 }
00121 if (t)
00122 xmlAddChild(node, t);
00123 if (type)
00124 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
00125 return node;
00126 }
00127
00128 xmlNodePtr yaz_query2xml_apt(const Z_AttributesPlusTerm *zapt,
00129 xmlNodePtr parent)
00130 {
00131 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "apt", 0);
00132 int num_attributes = zapt->attributes->num_attributes;
00133 int i;
00134 for (i = 0; i<num_attributes; i++)
00135 yaz_query2xml_attribute_element(zapt->attributes->attributes[i], node);
00136 yaz_query2xml_term(zapt->term, node);
00137
00138 return node;
00139 }
00140
00141
00142 void yaz_query2xml_operator(Z_Operator *op, xmlNodePtr node)
00143 {
00144 const char *type = 0;
00145 switch(op->which)
00146 {
00147 case Z_Operator_and:
00148 type = "and";
00149 break;
00150 case Z_Operator_or:
00151 type = "or";
00152 break;
00153 case Z_Operator_and_not:
00154 type = "not";
00155 break;
00156 case Z_Operator_prox:
00157 type = "prox";
00158 break;
00159 default:
00160 return;
00161 }
00162 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
00163
00164 if (op->which == Z_Operator_prox)
00165 {
00166 char formstr[30];
00167
00168 if (op->u.prox->exclusion)
00169 {
00170 if (*op->u.prox->exclusion)
00171 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "true");
00172 else
00173 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "false");
00174 }
00175 sprintf(formstr, "%d", *op->u.prox->distance);
00176 xmlNewProp(node, BAD_CAST "distance", BAD_CAST formstr);
00177
00178 if (*op->u.prox->ordered)
00179 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "true");
00180 else
00181 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "false");
00182
00183 sprintf(formstr, "%d", *op->u.prox->relationType);
00184 xmlNewProp(node, BAD_CAST "relationType", BAD_CAST formstr);
00185
00186 switch(op->u.prox->which)
00187 {
00188 case Z_ProximityOperator_known:
00189 sprintf(formstr, "%d", *op->u.prox->u.known);
00190 xmlNewProp(node, BAD_CAST "knownProximityUnit",
00191 BAD_CAST formstr);
00192 break;
00193 case Z_ProximityOperator_private:
00194 default:
00195 xmlNewProp(node, BAD_CAST "privateProximityUnit",
00196 BAD_CAST "private");
00197 break;
00198 }
00199 }
00200 }
00201
00202 xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
00203 xmlNodePtr parent)
00204 {
00205 if (zs->which == Z_RPNStructure_complex)
00206 {
00207 Z_Complex *zc = zs->u.complex;
00208
00209 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "operator", 0);
00210 if (zc->roperator)
00211 yaz_query2xml_operator(zc->roperator, node);
00212 yaz_query2xml_rpnstructure(zc->s1, node);
00213 yaz_query2xml_rpnstructure(zc->s2, node);
00214 return node;
00215 }
00216 else if (zs->which == Z_RPNStructure_simple)
00217 {
00218 if (zs->u.simple->which == Z_Operand_APT)
00219 return yaz_query2xml_apt(zs->u.simple->u.attributesPlusTerm,
00220 parent);
00221 else if (zs->u.simple->which == Z_Operand_resultSetId)
00222 return xmlNewChild(parent, 0, BAD_CAST "rset",
00223 BAD_CAST zs->u.simple->u.resultSetId);
00224 }
00225 return 0;
00226 }
00227
00228 xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
00229 {
00230 if (rpn->attributeSetId)
00231 {
00232 char oid_name_str[OID_STR_MAX];
00233 const char *setname = yaz_oid_to_string_buf(rpn->attributeSetId,
00234 0, oid_name_str);
00235 if (setname)
00236 xmlNewProp(parent, BAD_CAST "set", BAD_CAST setname);
00237 }
00238 return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
00239 }
00240
00241 xmlNodePtr yaz_query2xml_ccl(const Odr_oct *ccl, xmlNodePtr node)
00242 {
00243 return 0;
00244 }
00245
00246 xmlNodePtr yaz_query2xml_z3958(const Odr_oct *ccl, xmlNodePtr node)
00247 {
00248 return 0;
00249 }
00250
00251 xmlNodePtr yaz_query2xml_cql(const char *cql, xmlNodePtr node)
00252 {
00253 return 0;
00254 }
00255
00256 void yaz_rpnquery2xml(const Z_RPNQuery *rpn, xmlDocPtr *docp)
00257 {
00258 Z_Query query;
00259
00260 query.which = Z_Query_type_1;
00261 query.u.type_1 = (Z_RPNQuery *) rpn;
00262 yaz_query2xml(&query, docp);
00263 }
00264
00265 void yaz_query2xml(const Z_Query *q, xmlDocPtr *docp)
00266 {
00267 xmlNodePtr top_node, q_node = 0, child_node = 0;
00268
00269 assert(q);
00270 assert(docp);
00271
00272 top_node = xmlNewNode(0, BAD_CAST "query");
00273
00274 switch (q->which)
00275 {
00276 case Z_Query_type_1:
00277 case Z_Query_type_101:
00278 q_node = xmlNewChild(top_node, 0, BAD_CAST "rpn", 0);
00279 child_node = yaz_query2xml_rpn(q->u.type_1, q_node);
00280 break;
00281 case Z_Query_type_2:
00282 q_node = xmlNewChild(top_node, 0, BAD_CAST "ccl", 0);
00283 child_node = yaz_query2xml_ccl(q->u.type_2, q_node);
00284 break;
00285 case Z_Query_type_100:
00286 q_node = xmlNewChild(top_node, 0, BAD_CAST "z39.58", 0);
00287 child_node = yaz_query2xml_z3958(q->u.type_100, q_node);
00288 break;
00289 case Z_Query_type_104:
00290 if (q->u.type_104->which == Z_External_CQL)
00291 {
00292 q_node = xmlNewChild(top_node, 0, BAD_CAST "cql", 0);
00293 child_node = yaz_query2xml_cql(q->u.type_104->u.cql, q_node);
00294 }
00295 }
00296 if (child_node && q_node)
00297 {
00298 *docp = xmlNewDoc(BAD_CAST "1.0");
00299 xmlDocSetRootElement(*docp, top_node);
00300 }
00301 else
00302 {
00303 *docp = 0;
00304 xmlFreeNode(top_node);
00305 }
00306 }
00307
00308 bool_t *boolVal(ODR odr, const char *str)
00309 {
00310 if (*str == '\0' || strchr("0fF", *str))
00311 return odr_intdup(odr, 0);
00312 return odr_intdup(odr, 1);
00313 }
00314
00315 int *intVal(ODR odr, const char *str)
00316 {
00317 return odr_intdup(odr, atoi(str));
00318 }
00319
00320 void yaz_xml2query_operator(const xmlNode *ptr, Z_Operator **op,
00321 ODR odr, int *error_code, const char **addinfo)
00322 {
00323 const char *type = (const char *)
00324 xmlGetProp((xmlNodePtr) ptr, BAD_CAST "type");
00325 if (!type)
00326 {
00327 *error_code = 1;
00328 *addinfo = "no operator type";
00329 return;
00330 }
00331 *op = (Z_Operator*) odr_malloc(odr, sizeof(Z_Operator));
00332 if (!strcmp(type, "and"))
00333 {
00334 (*op)->which = Z_Operator_and;
00335 (*op)->u.op_and = odr_nullval();
00336 }
00337 else if (!strcmp(type, "or"))
00338 {
00339 (*op)->which = Z_Operator_or;
00340 (*op)->u.op_or = odr_nullval();
00341 }
00342 else if (!strcmp(type, "not"))
00343 {
00344 (*op)->which = Z_Operator_and_not;
00345 (*op)->u.and_not = odr_nullval();
00346 }
00347 else if (!strcmp(type, "prox"))
00348 {
00349 const char *atval;
00350 Z_ProximityOperator *pop = (Z_ProximityOperator *)
00351 odr_malloc(odr, sizeof(Z_ProximityOperator));
00352
00353 (*op)->which = Z_Operator_prox;
00354 (*op)->u.prox = pop;
00355
00356 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00357 BAD_CAST "exclusion");
00358 if (atval)
00359 pop->exclusion = boolVal(odr, atval);
00360 else
00361 pop->exclusion = 0;
00362
00363 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00364 BAD_CAST "distance");
00365 if (atval)
00366 pop->distance = intVal(odr, atval);
00367 else
00368 pop->distance = odr_intdup(odr, 1);
00369
00370 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00371 BAD_CAST "ordered");
00372 if (atval)
00373 pop->ordered = boolVal(odr, atval);
00374 else
00375 pop->ordered = odr_intdup(odr, 1);
00376
00377 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00378 BAD_CAST "relationType");
00379 if (atval)
00380 pop->relationType = intVal(odr, atval);
00381 else
00382 pop->relationType =
00383 odr_intdup(odr, Z_ProximityOperator_Prox_lessThanOrEqual);
00384
00385 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00386 BAD_CAST "knownProximityUnit");
00387 if (atval)
00388 {
00389 pop->which = Z_ProximityOperator_known;
00390 pop->u.known = intVal(odr, atval);
00391 }
00392 else
00393 {
00394 pop->which = Z_ProximityOperator_known;
00395 pop->u.known = odr_intdup(odr, Z_ProxUnit_word);
00396 }
00397
00398 atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
00399 BAD_CAST "privateProximityUnit");
00400 if (atval)
00401 {
00402 pop->which = Z_ProximityOperator_private;
00403 pop->u.zprivate = intVal(odr, atval);
00404 }
00405 }
00406 else
00407 {
00408 *error_code = 1;
00409 *addinfo = "bad operator type";
00410 }
00411 }
00412
00413 void yaz_xml2query_attribute_element(const xmlNode *ptr,
00414 Z_AttributeElement **elem, ODR odr,
00415 int *error_code, const char **addinfo)
00416 {
00417 int i;
00418 xmlChar *set = 0;
00419 xmlChar *type = 0;
00420 xmlChar *value = 0;
00421 int num_values = 0;
00422 struct _xmlAttr *attr;
00423 for (attr = ptr->properties; attr; attr = attr->next)
00424 {
00425 if (!xmlStrcmp(attr->name, BAD_CAST "set") &&
00426 attr->children && attr->children->type == XML_TEXT_NODE)
00427 set = attr->children->content;
00428 else if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
00429 attr->children && attr->children->type == XML_TEXT_NODE)
00430 type = attr->children->content;
00431 else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
00432 attr->children && attr->children->type == XML_TEXT_NODE)
00433 {
00434 value = attr->children->content;
00435 num_values++;
00436 }
00437 else
00438 {
00439 *error_code = 1;
00440 *addinfo = "bad attribute for attr content";
00441 return;
00442 }
00443 }
00444 if (!type)
00445 {
00446 *error_code = 1;
00447 *addinfo = "missing type attribute for att content";
00448 return;
00449 }
00450 if (!value)
00451 {
00452 *error_code = 1;
00453 *addinfo = "missing value attribute for att content";
00454 return;
00455 }
00456
00457 *elem = (Z_AttributeElement *) odr_malloc(odr, sizeof(**elem));
00458 if (set)
00459 (*elem)->attributeSet = yaz_string_to_oid_odr(yaz_oid_std(),
00460 CLASS_ATTSET,
00461 (const char *) set,
00462 odr);
00463 else
00464 (*elem)->attributeSet = 0;
00465 (*elem)->attributeType = intVal(odr, (const char *) type);
00466
00467
00468 for (i = 0; value[i] && value[i] >= '0' && value[i] <= '9'; i++)
00469 ;
00470 if (num_values > 1 || value[i])
00471 {
00472 (*elem)->which = Z_AttributeValue_complex;
00473 (*elem)->value.complex =
00474 (Z_ComplexAttribute*) odr_malloc(odr, sizeof(Z_ComplexAttribute));
00475 (*elem)->value.complex->num_list = num_values;
00476 (*elem)->value.complex->list = (Z_StringOrNumeric **)
00477 odr_malloc(odr, sizeof(Z_StringOrNumeric*) * num_values);
00478
00479
00480 i = 0;
00481 for (attr = ptr->properties; attr; attr = attr->next)
00482 {
00483 if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
00484 attr->children && attr->children->type == XML_TEXT_NODE)
00485 {
00486 const char *val = (const char *) attr->children->content;
00487 assert (i < num_values);
00488 (*elem)->value.complex->list[i] = (Z_StringOrNumeric *)
00489 odr_malloc(odr, sizeof(Z_StringOrNumeric));
00490 (*elem)->value.complex->list[i]->which =
00491 Z_StringOrNumeric_string;
00492 (*elem)->value.complex->list[i]->u.string =
00493 odr_strdup(odr, val);
00494 i++;
00495 }
00496 }
00497 (*elem)->value.complex->num_semanticAction = 0;
00498 (*elem)->value.complex->semanticAction = 0;
00499 }
00500 else
00501 {
00502 (*elem)->which = Z_AttributeValue_numeric;
00503 (*elem)->value.numeric = intVal(odr, (const char *) value);
00504 }
00505 }
00506
00507 char *strVal(const xmlNode *ptr_cdata, ODR odr)
00508 {
00509 return nmem_text_node_cdata(ptr_cdata, odr_getmem(odr));
00510 }
00511
00512 void yaz_xml2query_term(const xmlNode *ptr,
00513 Z_Term **term, ODR odr,
00514 int *error_code, const char **addinfo)
00515 {
00516 xmlChar *type = 0;
00517 struct _xmlAttr *attr;
00518 char *cdata = strVal(ptr->children, odr);
00519
00520 for (attr = ptr->properties; attr; attr = attr->next)
00521 {
00522 if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
00523 attr->children && attr->children->type == XML_TEXT_NODE)
00524 type = attr->children->content;
00525 else
00526 {
00527 *error_code = 1;
00528 *addinfo = "bad attribute for attr content";
00529 return;
00530 }
00531 }
00532 *term = (Z_Term *) odr_malloc(odr, sizeof(Z_Term));
00533
00534 if (!type || !xmlStrcmp(type, BAD_CAST "general"))
00535 {
00536 (*term)->which = Z_Term_general;
00537 (*term)->u.general =
00538 odr_create_Odr_oct(odr, (unsigned char *)cdata, strlen(cdata));
00539 }
00540 else if (!xmlStrcmp(type, BAD_CAST "numeric"))
00541 {
00542 (*term)->which = Z_Term_numeric;
00543 (*term)->u.numeric = intVal(odr, cdata);
00544 }
00545 else if (!xmlStrcmp(type, BAD_CAST "string"))
00546 {
00547 (*term)->which = Z_Term_characterString;
00548 (*term)->u.characterString = cdata;
00549 }
00550 else if (!xmlStrcmp(type, BAD_CAST "oid"))
00551 {
00552 *error_code = 1;
00553 *addinfo = "unhandled term type: oid";
00554 }
00555 else if (!xmlStrcmp(type, BAD_CAST "dateTime"))
00556 {
00557 *error_code = 1;
00558 *addinfo = "unhandled term type: dateTime";
00559 }
00560 else if (!xmlStrcmp(type, BAD_CAST "integerAndUnit"))
00561 {
00562 *error_code = 1;
00563 *addinfo = "unhandled term type: integerAndUnit";
00564 }
00565 else if (!xmlStrcmp(type, BAD_CAST "null"))
00566 {
00567 (*term)->which = Z_Term_null;
00568 (*term)->u.null = odr_nullval();
00569 }
00570 else
00571 {
00572 *error_code = 1;
00573 *addinfo = "unhandled term type";
00574 }
00575 }
00576
00577 void yaz_xml2query_apt(const xmlNode *ptr_apt,
00578 Z_AttributesPlusTerm **zapt, ODR odr,
00579 int *error_code, const char **addinfo)
00580 {
00581 const xmlNode *ptr = ptr_apt->children;
00582 int i, num_attr = 0;
00583
00584 *zapt = (Z_AttributesPlusTerm *)
00585 odr_malloc(odr, sizeof(Z_AttributesPlusTerm));
00586
00587
00588 (*zapt)->attributes = (Z_AttributeList*)
00589 odr_malloc(odr, sizeof(Z_AttributeList));
00590
00591
00592 for (; ptr; ptr = ptr->next)
00593 if (ptr->type == XML_ELEMENT_NODE)
00594 {
00595 if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
00596 num_attr++;
00597 else
00598 break;
00599 }
00600
00601
00602 (*zapt)->attributes->num_attributes = num_attr;
00603 (*zapt)->attributes->attributes = (Z_AttributeElement **)
00604 odr_malloc(odr, sizeof(Z_AttributeElement*) * num_attr);
00605
00606 i = 0;
00607 ptr = ptr_apt->children;
00608 for (; ptr; ptr = ptr->next)
00609 if (ptr->type == XML_ELEMENT_NODE)
00610 {
00611 if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
00612 {
00613 yaz_xml2query_attribute_element(
00614 ptr, &(*zapt)->attributes->attributes[i], odr,
00615 error_code, addinfo);
00616 i++;
00617 }
00618 else
00619 break;
00620 }
00621 if (ptr && ptr->type == XML_ELEMENT_NODE)
00622 {
00623 if (!xmlStrcmp(ptr->name, BAD_CAST "term"))
00624 {
00625
00626 yaz_xml2query_term(ptr, &(*zapt)->term, odr, error_code, addinfo);
00627 }
00628 else
00629 {
00630 *error_code = 1;
00631 *addinfo = "bad element in apt content";
00632 }
00633 }
00634 else
00635 {
00636 *error_code = 1;
00637 *addinfo = "missing term node in apt content";
00638 }
00639 }
00640
00641 void yaz_xml2query_rset(const xmlNode *ptr, Z_ResultSetId **rset,
00642 ODR odr, int *error_code, const char **addinfo)
00643 {
00644 if (ptr->children)
00645 {
00646 *rset = strVal(ptr->children, odr);
00647 }
00648 else
00649 {
00650 *error_code = 1;
00651 *addinfo = "missing rset content";
00652 }
00653 }
00654
00655 void yaz_xml2query_rpnstructure(const xmlNode *ptr, Z_RPNStructure **zs,
00656 ODR odr, int *error_code, const char **addinfo)
00657 {
00658 while (ptr && ptr->type != XML_ELEMENT_NODE)
00659 ptr = ptr->next;
00660
00661 if (!ptr || ptr->type != XML_ELEMENT_NODE)
00662 {
00663 *error_code = 1;
00664 *addinfo = "missing rpn operator, rset, apt node";
00665 return;
00666 }
00667 *zs = (Z_RPNStructure *) odr_malloc(odr, sizeof(Z_RPNStructure));
00668 if (!xmlStrcmp(ptr->name, BAD_CAST "operator"))
00669 {
00670 Z_Complex *zc = (Z_Complex *) odr_malloc(odr, sizeof(Z_Complex));
00671
00672 (*zs)->which = Z_RPNStructure_complex;
00673 (*zs)->u.complex = zc;
00674
00675 yaz_xml2query_operator(ptr, &zc->roperator, odr, error_code, addinfo);
00676
00677 ptr = ptr->children;
00678 while (ptr && ptr->type != XML_ELEMENT_NODE)
00679 ptr = ptr->next;
00680 yaz_xml2query_rpnstructure(ptr, &zc->s1, odr, error_code, addinfo);
00681 if (ptr)
00682 ptr = ptr->next;
00683 while (ptr && ptr->type != XML_ELEMENT_NODE)
00684 ptr = ptr->next;
00685 yaz_xml2query_rpnstructure(ptr, &zc->s2, odr, error_code, addinfo);
00686 }
00687 else
00688 {
00689 Z_Operand *s = (Z_Operand *) odr_malloc(odr, sizeof(Z_Operand));
00690 (*zs)->which = Z_RPNStructure_simple;
00691 (*zs)->u.simple = s;
00692 if (!xmlStrcmp(ptr->name, BAD_CAST "apt"))
00693 {
00694 s->which = Z_Operand_APT;
00695 yaz_xml2query_apt(ptr, &s->u.attributesPlusTerm,
00696 odr, error_code, addinfo);
00697 }
00698 else if (!xmlStrcmp(ptr->name, BAD_CAST "rset"))
00699 {
00700 s->which = Z_Operand_resultSetId;
00701 yaz_xml2query_rset(ptr, &s->u.resultSetId,
00702 odr, error_code, addinfo);
00703 }
00704 else
00705 {
00706 *error_code = 1;
00707 *addinfo = "bad element: expected binary, apt or rset";
00708 }
00709 }
00710 }
00711
00712 void yaz_xml2query_rpn(const xmlNode *ptr, Z_RPNQuery **query, ODR odr,
00713 int *error_code, const char **addinfo)
00714 {
00715 const char *set = (const char *)
00716 xmlGetProp((xmlNodePtr) ptr, BAD_CAST "set");
00717
00718 *query = (Z_RPNQuery*) odr_malloc(odr, sizeof(Z_RPNQuery));
00719 if (set)
00720 (*query)->attributeSetId = yaz_string_to_oid_odr(yaz_oid_std(),
00721 CLASS_ATTSET, set, odr);
00722 else
00723 (*query)->attributeSetId = 0;
00724 yaz_xml2query_rpnstructure(ptr->children, &(*query)->RPNStructure,
00725 odr, error_code, addinfo);
00726 }
00727
00728 static void yaz_xml2query_(const xmlNode *ptr, Z_Query **query, ODR odr,
00729 int *error_code, const char **addinfo)
00730 {
00731 if (ptr && ptr->type == XML_ELEMENT_NODE &&
00732 !xmlStrcmp(ptr->name, BAD_CAST "query"))
00733 {
00734 const char *type;
00735 ptr = ptr->children;
00736 while (ptr && ptr->type != XML_ELEMENT_NODE)
00737 ptr = ptr->next;
00738 if (!ptr || ptr->type != XML_ELEMENT_NODE)
00739 {
00740 *error_code = 1;
00741 *addinfo = "missing query content";
00742 return;
00743 }
00744 type = (const char *) ptr->name;
00745
00746 *query = (Z_Query*) odr_malloc(odr, sizeof(Z_Query));
00747 if (!type || !strcmp(type, "rpn"))
00748 {
00749 (*query)->which = Z_Query_type_1;
00750 yaz_xml2query_rpn(ptr, &(*query)->u.type_1, odr,
00751 error_code, addinfo);
00752 }
00753 else if (!strcmp(type, "ccl"))
00754 {
00755 *error_code = 1;
00756 *addinfo = "ccl not supported yet";
00757 }
00758 else if (!strcmp(type, "z39.58"))
00759 {
00760 *error_code = 1;
00761 *addinfo = "z39.58 not supported yet";
00762 }
00763 else if (!strcmp(type, "cql"))
00764 {
00765 *error_code = 1;
00766 *addinfo = "cql not supported yet";
00767 }
00768 else
00769 {
00770 *error_code = 1;
00771 *addinfo = "unsupported query type";
00772 }
00773 }
00774 else
00775 {
00776 *error_code = 1;
00777 *addinfo = "missing query element";
00778 }
00779 }
00780
00781 void yaz_xml2query(const xmlNode *xmlnodep, Z_Query **query, ODR odr,
00782 int *error_code, const char **addinfo)
00783 {
00784 yaz_xml2query_(xmlnodep, query, odr, error_code, addinfo);
00785 }
00786
00787
00788 #endif
00789
00790
00791
00792
00793
00794
00795
00796