* Copyright (C) 1995-2005, Index Data ApS
* All rights reserved.
*
- * $Id: xmlquery.c,v 1.1 2006-01-27 17:28:16 adam Exp $
+ * $Id: xmlquery.c,v 1.2 2006-01-30 14:02:07 adam Exp $
*/
/**
#include <yaz/logrpn.h>
#include <yaz/xmlquery.h>
-xmlNodePtr yaz_query2xml_attribute_element(const Z_AttributeElement *element,
- xmlNodePtr parent)
+void yaz_query2xml_attribute_element(const Z_AttributeElement *element,
+ xmlNodePtr parent)
{
- xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
-#if 0
- int i;
- char *setname = 0;
+ char formstr[30];
+ const char *setname = 0;
+
if (element->attributeSet)
{
oident *attrset;
attrset = oid_getentbyoid (element->attributeSet);
setname = attrset->desc;
}
- switch (element->which)
+
+ if (element->which == Z_AttributeValue_numeric)
{
- case Z_AttributeValue_numeric:
- wrbuf_printf(b,"@attr %s%s%d=%d ", setname, sep,
- *element->attributeType, *element->value.numeric);
- break;
- case Z_AttributeValue_complex:
- wrbuf_printf(b,"@attr %s%s\"%d=", setname, sep,
- *element->attributeType);
+ xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
+
+ if (setname)
+ xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
+
+ sprintf(formstr, "%d", *element->attributeType);
+ xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
+
+ sprintf(formstr, "%d", *element->value.numeric);
+ xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
+ }
+ else if (element->which == Z_AttributeValue_complex)
+ {
+ int i;
for (i = 0; i<element->value.complex->num_list; i++)
{
- if (i)
- wrbuf_printf(b,",");
+ xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
+
+ if (setname)
+ xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
+
+ sprintf(formstr, "%d", *element->attributeType);
+ xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
+
if (element->value.complex->list[i]->which ==
Z_StringOrNumeric_string)
- wrbuf_printf (b, "%s",
- element->value.complex->list[i]->u.string);
+ {
+ xmlNewProp(node, BAD_CAST "value", BAD_CAST
+ element->value.complex->list[i]->u.string);
+ }
else if (element->value.complex->list[i]->which ==
Z_StringOrNumeric_numeric)
- wrbuf_printf (b, "%d",
- *element->value.complex->list[i]->u.numeric);
+ {
+ sprintf(formstr, "%d",
+ *element->value.complex->list[i]->u.numeric);
+ xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
+ }
}
- wrbuf_printf(b, "\" ");
- break;
- default:
- wrbuf_printf (b, "@attr 1=unknown ");
}
-#endif
- return node;
}
return node;
}
-xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
- xmlNodePtr parent)
+
+void yaz_query2xml_operator(Z_Operator *op, xmlNodePtr node)
{
- if (zs->which == Z_RPNStructure_complex)
+ const char *type = 0;
+ switch(op->which)
{
- return 0;
-#if 0
- Z_Operator *op = zs->u.complex->roperator;
- wrbuf_printf(b, "@%s ", complex_op_name(op) );
- if (op->which== Z_Operator_prox)
+ case Z_Operator_and:
+ type = "and";
+ break;
+ case Z_Operator_or:
+ type = "or";
+ break;
+ case Z_Operator_and_not:
+ type = "not";
+ break;
+ case Z_Operator_prox:
+ type = "prox";
+ break;
+ default:
+ return;
+ }
+ xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
+
+ if (op->which == Z_Operator_prox)
+ {
+ char formstr[30];
+
+ if (op->u.prox->exclusion)
{
- if (!op->u.prox->exclusion)
- wrbuf_putc(b, 'n');
- else if (*op->u.prox->exclusion)
- wrbuf_putc(b, '1');
+ if (*op->u.prox->exclusion)
+ xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "true");
else
- wrbuf_putc(b, '0');
-
- wrbuf_printf(b, " %d %d %d ", *op->u.prox->distance,
- *op->u.prox->ordered,
- *op->u.prox->relationType);
+ xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "false");
+ }
+ sprintf(formstr, "%d", *op->u.prox->distance);
+ xmlNewProp(node, BAD_CAST "distance", BAD_CAST formstr);
- switch(op->u.prox->which)
- {
- case Z_ProximityOperator_known:
- wrbuf_putc(b, 'k');
- break;
- case Z_ProximityOperator_private:
- wrbuf_putc(b, 'p');
- break;
- default:
- wrbuf_printf(b, "%d", op->u.prox->which);
- }
- if (op->u.prox->u.known)
- wrbuf_printf(b, " %d ", *op->u.prox->u.known);
- else
- wrbuf_printf(b, " 0 ");
+ if (*op->u.prox->ordered)
+ xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "true");
+ else
+ xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "false");
+
+ sprintf(formstr, "%d", *op->u.prox->relationType);
+ xmlNewProp(node, BAD_CAST "relationType", BAD_CAST formstr);
+
+ switch(op->u.prox->which)
+ {
+ case Z_ProximityOperator_known:
+ sprintf(formstr, "%d", *op->u.prox->u.known);
+ xmlNewProp(node, BAD_CAST "knownProximityUnit",
+ BAD_CAST formstr);
+ break;
+ default:
+ xmlNewProp(node, BAD_CAST "privateProximityUnit",
+ BAD_CAST "private");
+ break;
}
- yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s1);
- yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s2);
-#endif
+ }
+}
+
+xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
+ xmlNodePtr parent)
+{
+ if (zs->which == Z_RPNStructure_complex)
+ {
+ Z_Complex *zc = zs->u.complex;
+
+ xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "binary", 0);
+ if (zc->roperator)
+ yaz_query2xml_operator(zc->roperator, node);
+ yaz_query2xml_rpnstructure(zc->s1, node);
+ yaz_query2xml_rpnstructure(zc->s2, node);
+ return node;
}
else if (zs->which == Z_RPNStructure_simple)
{
return yaz_query2xml_apt(zs->u.simple->u.attributesPlusTerm,
parent);
else if (zs->u.simple->which == Z_Operand_resultSetId)
- {
- return 0;
-#if 0
- yaz_term_to_wrbuf(b, zs->u.simple->u.resultSetId,
- strlen(zs->u.simple->u.resultSetId));
-#endif
- }
- else
- return 0;
+ return xmlNewChild(parent, /* NS */ 0, BAD_CAST "rset",
+ BAD_CAST zs->u.simple->u.resultSetId);
}
return 0;
}
{
oident *attrset = oid_getentbyoid (rpn->attributeSetId);
if (attrset && attrset->value)
- parent = xmlNewChild(parent, /*ns */ 0,
- BAD_CAST "attrset", BAD_CAST attrset->desc);
+ xmlNewProp(parent, BAD_CAST "set", BAD_CAST attrset->desc);
return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
}
return 0;
}
+void yaz_rpnquery2xml(const Z_RPNQuery *rpn, void *docp_void)
+{
+ Z_Query query;
+
+ query.which = Z_Query_type_1;
+ query.u.type_1 = (Z_RPNQuery *) rpn;
+ yaz_query2xml(&query, docp_void);
+}
+
void yaz_query2xml(const Z_Query *q, void *docp_void)
{
xmlDocPtr *docp = (xmlDocPtr *) docp_void;
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: tstxmlquery.c,v 1.5 2006-01-30 08:08:23 adam Exp $
+ * $Id: tstxmlquery.c,v 1.6 2006-01-30 14:02:07 adam Exp $
*/
#include <stdlib.h>
#include <yaz/pquery.h>
#include <yaz/test.h>
-static void pqf2xml_text(const char *pqf)
+#if HAVE_XML2
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#endif
+
+enum pqf2xml_status {
+ PQF_FAILED,
+ QUERY2XML_FAILED,
+ XML_NO_MATCH,
+ XML_MATCH,
+ XML_NO_ERROR
+};
+
+enum pqf2xml_status pqf2xml_text(const char *pqf, const char *expect_xml)
{
YAZ_PQF_Parser parser = yaz_pqf_create();
ODR odr = odr_createmem(ODR_ENCODE);
Z_RPNQuery *rpn;
- Z_Query *query;
+ enum pqf2xml_status status = XML_NO_ERROR;
YAZ_CHECK(parser);
rpn = yaz_pqf_parse(parser, odr, pqf);
- YAZ_CHECK(rpn);
-
yaz_pqf_destroy(parser);
- query = odr_malloc(odr, sizeof(*query));
- query->which = Z_Query_type_1;
- query->u.type_1 = rpn;
-
+ if (!rpn)
+ status = PQF_FAILED;
+ else
+ {
+ status = QUERY2XML_FAILED;
+#if HAVE_XML2
+ xmlDocPtr doc = 0;
+ yaz_rpnquery2xml(rpn, &doc);
+
+ if (!doc)
+ status = QUERY2XML_FAILED;
+ else
+ {
+ char *buf_out;
+ int len_out;
+
+ xmlDocDumpMemory(doc, (xmlChar **) &buf_out, &len_out);
+
+ if (len_out == strlen(expect_xml)
+ && memcmp(buf_out, expect_xml, len_out) == 0)
+ {
+ status = XML_MATCH;
+ }
+ else
+ {
+ printf("%.*s\n", len_out, buf_out);
+ status = XML_NO_MATCH;
+ }
+ xmlFreeDoc(doc);
+ }
+#endif
+ }
odr_destroy(odr);
+ return status;
+}
+
+void tst()
+{
+ YAZ_CHECK_EQ(pqf2xml_text("@attr 1=4 bad query", ""), PQF_FAILED);
#if HAVE_XML2
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@attr 1=4 computer",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<apt><attr type=\"1\" value=\"4\"/>"
+ "<term>computer</term></apt>"
+ "</query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@attr 2=1 @attr 1=title computer",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<apt><attr type=\"1\" value=\"title\"/>"
+ "<attr type=\"2\" value=\"1\"/>"
+ "<term>computer</term></apt>"
+ "</query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@attr 2=1 @attr exp1 1=1 computer",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<apt><attr set=\"Exp-1\" type=\"1\" value=\"1\"/>"
+ "<attr type=\"2\" value=\"1\"/>"
+ "<term>computer</term></apt>"
+ "</query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@and a b",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<binary type=\"and\">"
+ "<apt><term>a</term></apt><apt><term>b</term></apt>"
+ "</binary></query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@or @and a b c",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<binary type=\"or\">"
+ "<binary type=\"and\"><apt><term>a</term></apt>"
+ "<apt><term>b</term></apt></binary>"
+ "<apt><term>c</term></apt>"
+ "</binary></query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ "@set abe",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<rset>abe</rset></query>\n"), XML_MATCH);
+
+ YAZ_CHECK_EQ(pqf2xml_text(
+ /* exclusion, distance, ordered, relationtype,
+ knownunit, proxunit */
+ "@prox 0 3 1 2 k 2 a b",
+ "<?xml version=\"1.0\"?>\n"
+ "<query set=\"Bib-1\" type=\"rpn\">"
+ "<binary type=\"prox\" exclusion=\"false\" "
+ "distance=\"3\" "
+ "ordered=\"true\" "
+ "relationType=\"2\" "
+ "knownProximityUnit=\"2\">"
+ "<apt><term>a</term></apt><apt><term>b</term></apt>"
+ "</binary></query>\n"), XML_MATCH);
#endif
}
int main (int argc, char **argv)
{
YAZ_CHECK_INIT(argc, argv);
-
- pqf2xml_text("@attr 1=4 computer");
-
+ tst();
YAZ_CHECK_TERM;
}