+void yaz_xml2query_apt(const xmlNode *ptr_apt,
+ Z_AttributesPlusTerm **zapt, ODR odr,
+ int *error_code, const char **addinfo)
+{
+ const xmlNode *ptr = ptr_apt->children;
+ int i, num_attr = 0;
+
+ *zapt = (Z_AttributesPlusTerm *)
+ odr_malloc(odr, sizeof(Z_AttributesPlusTerm));
+
+ /* deal with attributes */
+ (*zapt)->attributes = (Z_AttributeList*)
+ odr_malloc(odr, sizeof(Z_AttributeList));
+
+ /* how many attributes? */
+ for (; ptr; ptr = ptr->next)
+ if (ptr->type == XML_ELEMENT_NODE)
+ {
+ if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
+ num_attr++;
+ else
+ break;
+ }
+
+ /* allocate and parse for real */
+ (*zapt)->attributes->num_attributes = num_attr;
+ (*zapt)->attributes->attributes = (Z_AttributeElement **)
+ odr_malloc(odr, sizeof(Z_AttributeElement*) * num_attr);
+
+ i = 0;
+ ptr = ptr_apt->children;
+ for (; ptr; ptr = ptr->next)
+ if (ptr->type == XML_ELEMENT_NODE)
+ {
+ if (!xmlStrcmp(ptr->name, BAD_CAST "attr"))
+ {
+ yaz_xml2query_attribute_element(
+ ptr, &(*zapt)->attributes->attributes[i], odr,
+ error_code, addinfo);
+ i++;
+ }
+ else
+ break;
+ }
+ if (ptr && ptr->type == XML_ELEMENT_NODE)
+ {
+ if (!xmlStrcmp(ptr->name, BAD_CAST "term"))
+ {
+ /* deal with term */
+ yaz_xml2query_term(ptr, &(*zapt)->term, odr, error_code, addinfo);
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "bad element in apt content";
+ }
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "missing term node in apt content";
+ }
+}
+
+void yaz_xml2query_rset(const xmlNode *ptr, Z_ResultSetId **rset,
+ ODR odr, int *error_code, const char **addinfo)
+{
+ if (ptr->children)
+ {
+ *rset = strVal(ptr->children, odr);
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "missing rset content";
+ }
+}
+
+void yaz_xml2query_rpnstructure(const xmlNode *ptr, Z_RPNStructure **zs,
+ ODR odr, int *error_code, const char **addinfo)
+{
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+
+ if (!ptr || ptr->type != XML_ELEMENT_NODE)
+ {
+ *error_code = 1;
+ *addinfo = "missing rpn operator, rset, apt node";
+ return;
+ }
+ *zs = (Z_RPNStructure *) odr_malloc(odr, sizeof(Z_RPNStructure));
+ if (!xmlStrcmp(ptr->name, BAD_CAST "operator"))
+ {
+ Z_Complex *zc = odr_malloc(odr, sizeof(Z_Complex));
+
+ (*zs)->which = Z_RPNStructure_complex;
+ (*zs)->u.complex = zc;
+
+ yaz_xml2query_operator(ptr, &zc->roperator, odr, error_code, addinfo);
+
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ yaz_xml2query_rpnstructure(ptr, &zc->s1, odr, error_code, addinfo);
+ if (ptr)
+ ptr = ptr->next;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ yaz_xml2query_rpnstructure(ptr, &zc->s2, odr, error_code, addinfo);
+ }
+ else
+ {
+ Z_Operand *s = (Z_Operand *) odr_malloc(odr, sizeof(Z_Operand));
+ (*zs)->which = Z_RPNStructure_simple;
+ (*zs)->u.simple = s;
+ if (!xmlStrcmp(ptr->name, BAD_CAST "apt"))
+ {
+ s->which = Z_Operand_APT;
+ yaz_xml2query_apt(ptr, &s->u.attributesPlusTerm,
+ odr, error_code, addinfo);
+ }
+ else if (!xmlStrcmp(ptr->name, BAD_CAST "rset"))
+ {
+ s->which = Z_Operand_resultSetId;
+ yaz_xml2query_rset(ptr, &s->u.resultSetId,
+ odr, error_code, addinfo);
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "bad element: expected binary, apt or rset";
+ }
+ }
+}
+
+void yaz_xml2query_rpn(const xmlNode *ptr, Z_RPNQuery **query, ODR odr,
+ int *error_code, const char **addinfo)
+{
+ const char *set = (const char *)
+ xmlGetProp((xmlNodePtr) ptr, BAD_CAST "set");
+
+ *query = (Z_RPNQuery*) odr_malloc(odr, sizeof(Z_RPNQuery));
+ if (set)
+ (*query)->attributeSetId = yaz_str_to_z3950oid(odr, CLASS_ATTSET, set);
+ else
+ (*query)->attributeSetId = 0;
+ yaz_xml2query_rpnstructure(ptr->children, &(*query)->RPNStructure,
+ odr, error_code, addinfo);
+}
+
+static void yaz_xml2query_(const xmlNode *ptr, Z_Query **query, ODR odr,
+ int *error_code, const char **addinfo)
+{
+ if (ptr && ptr->type == XML_ELEMENT_NODE &&
+ !xmlStrcmp(ptr->name, BAD_CAST "query"))
+ {
+ const char *type;
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ if (!ptr || ptr->type != XML_ELEMENT_NODE)
+ {
+ *error_code = 1;
+ *addinfo = "missing query content";
+ return;
+ }
+ type = (const char *) ptr->name;
+
+ *query = (Z_Query*) odr_malloc(odr, sizeof(Z_Query));
+ if (!type || !strcmp(type, "rpn"))
+ {
+ (*query)->which = Z_Query_type_1;
+ yaz_xml2query_rpn(ptr, &(*query)->u.type_1, odr,
+ error_code, addinfo);
+ }
+ else if (!strcmp(type, "ccl"))
+ {
+ *error_code = 1;
+ *addinfo = "ccl not supported yet";
+ }
+ else if (!strcmp(type, "z39.58"))
+ {
+ *error_code = 1;
+ *addinfo = "z39.58 not supported yet";
+ }
+ else if (!strcmp(type, "cql"))
+ {
+ *error_code = 1;
+ *addinfo = "cql not supported yet";
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "unsupported query type";
+ }
+ }
+ else
+ {
+ *error_code = 1;
+ *addinfo = "missing query element";
+ }
+}
+
+void yaz_xml2query(const void *xmlnodep, Z_Query **query, ODR odr,
+ int *error_code, const char **addinfo)
+{
+ yaz_xml2query_(xmlnodep, query, odr, error_code, addinfo);
+}