Added utility program yaz-xmlquery.
[yaz-moved-to-github.git] / util / yaz-xmlquery.c
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: yaz-xmlquery.c,v 1.1 2006-02-23 10:40:59 adam Exp $
6  */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 #include <yaz/options.h>
12 #include <yaz/querytowrbuf.h>
13 #include <yaz/xmlquery.h>
14 #include <yaz/pquery.h>
15 #include <yaz/test.h>
16
17 #if HAVE_XML2
18 #include <libxml/parser.h>
19 #endif
20
21 static char *prog = "yaz-xmlquery";
22
23 #if HAVE_XML2
24 void pqftoxmlquery(const char *pqf)
25 {
26     YAZ_PQF_Parser parser = yaz_pqf_create();
27     ODR odr = odr_createmem(ODR_ENCODE);
28     Z_RPNQuery *rpn;
29
30     if (!parser)
31     {
32         fprintf(stderr, "%s: cannot create parser\n", prog);
33         exit(1);
34     }
35
36     if (!odr)
37     {
38         fprintf(stderr, "%s: cannot create parser\n", prog);
39         exit(1);
40     }
41
42     rpn = yaz_pqf_parse(parser, odr, pqf);
43
44     yaz_pqf_destroy(parser);
45
46     if (!rpn)
47     {
48         fprintf(stderr, "%s: pqf parse error for query %s\n", prog, pqf);
49         exit(2);
50     }
51     else
52     {
53         xmlDocPtr doc = 0;
54         
55         yaz_rpnquery2xml(rpn, &doc);
56         
57         if (!doc)
58         {
59             fprintf(stderr, "%s: yaz_rpnquery2xml failed for query %s\n",
60                     prog, pqf);
61             exit(3);
62         }
63         else
64         {
65             char *buf_out = 0;
66             int len_out = 0;
67
68             xmlDocDumpMemory(doc, (xmlChar **) &buf_out, &len_out);
69
70             if (!len_out || !buf_out)
71             {
72                 fprintf(stderr, "%s: xmlDocDumpMemory failed for query %s\n",
73                         prog, pqf);
74                 exit(4);
75             }
76             else
77                 fwrite(buf_out, len_out, 1, stdout);
78             xmlFreeDoc(doc);
79         }
80     }    
81     odr_destroy(odr);
82 }
83
84
85 void xmlquerytopqf(const char *xmlstr)
86 {
87     xmlDocPtr doc;
88
89     doc = xmlParseMemory(xmlstr, strlen(xmlstr));
90     if (!doc)
91     {
92         fprintf(stderr, "%s: xml parse error for XML:\n%s\n", prog, xmlstr);
93         exit(1);
94     }
95     else
96     {
97         int error_code = 0;
98         const char *addinfo = 0;
99         Z_Query *query = 0;
100         ODR odr = odr_createmem(ODR_ENCODE);
101
102         const xmlNode *root_element = xmlDocGetRootElement(doc);
103         yaz_xml2query(root_element, &query, odr, &error_code, &addinfo);
104         if (error_code)
105         {
106             fprintf(stderr, "%s: yaz_xml2query failed code=%d addinfo=%s\n",
107                     prog, error_code, addinfo);
108             exit(1);
109         }
110         else if (!query)
111         {
112             fprintf(stderr, "%s: yaz_xml2query no query result\n",
113                     prog);
114             exit(1);
115         }
116         else
117         {
118             WRBUF w = wrbuf_alloc();
119             yaz_query_to_wrbuf(w, query);
120             printf("%s\n", wrbuf_buf(w));
121             wrbuf_free(w, 1);
122         }
123         odr_destroy(odr);
124         xmlFreeDoc(doc);
125     }
126 }
127
128 void xmlfiletopqf(const char *xmlfile)
129 {
130     long sz;
131     char *xmlstr;
132     FILE *f = fopen(xmlfile, "rb");
133     if (!f)
134     {
135         fprintf(stderr, "%s: cannot open %s\n", prog, xmlfile);
136         exit(1);
137     }
138     fseek(f, 0, SEEK_END);
139     sz = ftell(f);
140     if (sz <= 0 || sz >= 1<<18)
141     {
142         fprintf(stderr, "%s: bad size for file %s\n", prog, xmlfile);
143         exit(1);
144     }
145     rewind(f);
146     xmlstr = xmalloc(sz);
147     fread(xmlstr, sz, 1, f);
148     fclose(f);
149     
150     xmlquerytopqf(xmlstr);
151     xfree(xmlstr);
152 }
153 #endif
154
155 void usage()
156 {
157     fprintf(stderr, "%s [-p pqf] [-x xmlfile]\n", prog);
158     fprintf(stderr, " -p pqf      reads pqf. write xml to stdout\n");
159     fprintf(stderr, " -x xmlfile  reads XML from file. write pqf to stdout\n");
160     exit(1);
161 }
162
163 int main (int argc, char **argv)
164 {
165 #if HAVE_XML2
166     char *arg;
167     int r;
168     int active = 0;
169
170     while ((r = options("-p:x:", argv, argc, &arg)) != -2)
171     {
172         switch(r)
173         {
174         case 'p':
175             pqftoxmlquery(arg);
176             active = 1;
177             break;
178         case 'x':
179             xmlfiletopqf(arg);
180             active = 1;
181             break;
182         case 0:
183             break;
184         }
185     }
186     if (!active)
187     {
188         fprintf(stderr, "%s: nothing to do\n", prog);
189         usage();
190     }
191 #else
192     fprintf(stderr, "%s: XML support not enabled.\n", prog);
193     exit(1);
194 #endif
195     return 0;
196 }
197