Added utility program yaz-xmlquery.
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 23 Feb 2006 10:40:59 +0000 (10:40 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 23 Feb 2006 10:40:59 +0000 (10:40 +0000)
util/Makefile.am
util/yaz-xmlquery.c [new file with mode: 0644]

index eca8ee3..a53da0b 100644 (file)
@@ -1,6 +1,6 @@
-## Copyright (C) 1994-2004, Index Data
+## Copyright (C) 1994-2006, Index Data
 ## All rights reserved.
-## $Id: Makefile.am,v 1.28 2004-08-07 08:18:20 adam Exp $
+## $Id: Makefile.am,v 1.29 2006-02-23 10:40:59 adam Exp $
 
 bin_SCRIPTS = yaz-asncomp yaz-config
 
@@ -11,7 +11,7 @@ DISTCLEANFILES = yaz-config
 AM_CPPFLAGS=-I$(top_srcdir)/include $(XML2_CFLAGS)
 
 bin_PROGRAMS = yaz-marcdump yaz-iconv
-noinst_PROGRAMS = cclsh cql2pqf cql2xcql srwtst yaz-benchmark
+noinst_PROGRAMS = cclsh cql2pqf cql2xcql srwtst yaz-benchmark yaz-xmlquery
 
 # MARC dumper utility
 yaz_marcdump_SOURCES = marcdump.c
@@ -36,3 +36,5 @@ cql2xcql_LDADD = ../src/libyaz.la
 yaz_benchmark_SOURCES = benchmark.c
 yaz_benchmark_LDADD = ../src/libyaz.la
 
+yaz_xmlquery_SOURCES = yaz-xmlquery.c
+yaz_xmlquery_LDADD = ../src/libyaz.la
diff --git a/util/yaz-xmlquery.c b/util/yaz-xmlquery.c
new file mode 100644 (file)
index 0000000..6612183
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 1995-2005, Index Data ApS
+ * See the file LICENSE for details.
+ *
+ * $Id: yaz-xmlquery.c,v 1.1 2006-02-23 10:40:59 adam Exp $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <yaz/options.h>
+#include <yaz/querytowrbuf.h>
+#include <yaz/xmlquery.h>
+#include <yaz/pquery.h>
+#include <yaz/test.h>
+
+#if HAVE_XML2
+#include <libxml/parser.h>
+#endif
+
+static char *prog = "yaz-xmlquery";
+
+#if HAVE_XML2
+void pqftoxmlquery(const char *pqf)
+{
+    YAZ_PQF_Parser parser = yaz_pqf_create();
+    ODR odr = odr_createmem(ODR_ENCODE);
+    Z_RPNQuery *rpn;
+
+    if (!parser)
+    {
+       fprintf(stderr, "%s: cannot create parser\n", prog);
+       exit(1);
+    }
+
+    if (!odr)
+    {
+       fprintf(stderr, "%s: cannot create parser\n", prog);
+       exit(1);
+    }
+
+    rpn = yaz_pqf_parse(parser, odr, pqf);
+
+    yaz_pqf_destroy(parser);
+
+    if (!rpn)
+    {
+       fprintf(stderr, "%s: pqf parse error for query %s\n", prog, pqf);
+       exit(2);
+    }
+    else
+    {
+       xmlDocPtr doc = 0;
+       
+        yaz_rpnquery2xml(rpn, &doc);
+        
+        if (!doc)
+       {
+           fprintf(stderr, "%s: yaz_rpnquery2xml failed for query %s\n",
+                   prog, pqf);
+           exit(3);
+       }
+        else
+        {
+            char *buf_out = 0;
+            int len_out = 0;
+
+            xmlDocDumpMemory(doc, (xmlChar **) &buf_out, &len_out);
+
+            if (!len_out || !buf_out)
+           {
+               fprintf(stderr, "%s: xmlDocDumpMemory failed for query %s\n",
+                       prog, pqf);
+               exit(4);
+           }
+           else
+               fwrite(buf_out, len_out, 1, stdout);
+            xmlFreeDoc(doc);
+       }
+    }    
+    odr_destroy(odr);
+}
+
+
+void xmlquerytopqf(const char *xmlstr)
+{
+    xmlDocPtr doc;
+
+    doc = xmlParseMemory(xmlstr, strlen(xmlstr));
+    if (!doc)
+    {
+       fprintf(stderr, "%s: xml parse error for XML:\n%s\n", prog, xmlstr);
+       exit(1);
+    }
+    else
+    {
+       int error_code = 0;
+       const char *addinfo = 0;
+       Z_Query *query = 0;
+       ODR odr = odr_createmem(ODR_ENCODE);
+
+       const xmlNode *root_element = xmlDocGetRootElement(doc);
+       yaz_xml2query(root_element, &query, odr, &error_code, &addinfo);
+       if (error_code)
+       {
+           fprintf(stderr, "%s: yaz_xml2query failed code=%d addinfo=%s\n",
+                   prog, error_code, addinfo);
+           exit(1);
+       }
+       else if (!query)
+       {
+           fprintf(stderr, "%s: yaz_xml2query no query result\n",
+                   prog);
+           exit(1);
+       }
+       else
+       {
+           WRBUF w = wrbuf_alloc();
+           yaz_query_to_wrbuf(w, query);
+           printf("%s\n", wrbuf_buf(w));
+           wrbuf_free(w, 1);
+       }
+       odr_destroy(odr);
+       xmlFreeDoc(doc);
+    }
+}
+
+void xmlfiletopqf(const char *xmlfile)
+{
+    long sz;
+    char *xmlstr;
+    FILE *f = fopen(xmlfile, "rb");
+    if (!f)
+    {
+       fprintf(stderr, "%s: cannot open %s\n", prog, xmlfile);
+       exit(1);
+    }
+    fseek(f, 0, SEEK_END);
+    sz = ftell(f);
+    if (sz <= 0 || sz >= 1<<18)
+    {
+       fprintf(stderr, "%s: bad size for file %s\n", prog, xmlfile);
+       exit(1);
+    }
+    rewind(f);
+    xmlstr = xmalloc(sz);
+    fread(xmlstr, sz, 1, f);
+    fclose(f);
+    
+    xmlquerytopqf(xmlstr);
+    xfree(xmlstr);
+}
+#endif
+
+void usage()
+{
+    fprintf(stderr, "%s [-p pqf] [-x xmlfile]\n", prog);
+    fprintf(stderr, " -p pqf      reads pqf. write xml to stdout\n");
+    fprintf(stderr, " -x xmlfile  reads XML from file. write pqf to stdout\n");
+    exit(1);
+}
+
+int main (int argc, char **argv)
+{
+#if HAVE_XML2
+    char *arg;
+    int r;
+    int active = 0;
+
+    while ((r = options("-p:x:", argv, argc, &arg)) != -2)
+    {
+       switch(r)
+       {
+       case 'p':
+           pqftoxmlquery(arg);
+           active = 1;
+           break;
+       case 'x':
+           xmlfiletopqf(arg);
+           active = 1;
+           break;
+       case 0:
+           break;
+       }
+    }
+    if (!active)
+    {
+       fprintf(stderr, "%s: nothing to do\n", prog);
+       usage();
+    }
+#else
+    fprintf(stderr, "%s: XML support not enabled.\n", prog);
+    exit(1);
+#endif
+    return 0;
+}
+