Comment node. Extra root level for XML parsed data1
[yaz-moved-to-github.git] / retrieval / d1_expat.c
1 /*
2  * Copyright (c) 2002, Index Data.
3  * See the file LICENSE for details.
4  *
5  * $Id: d1_expat.c,v 1.2 2002-05-21 07:43:16 adam Exp $
6  */
7
8 #if HAVE_EXPAT_H
9
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include <yaz/xmalloc.h>
15 #include <yaz/log.h>
16 #include <yaz/data1.h>
17
18 #include <expat.h>
19
20 struct user_info {
21     data1_node *d1_stack[256];
22     int level;
23     data1_handle dh;
24     NMEM nmem;
25 };
26
27 static void cb_start (void *user, const char *el, const char **attr)
28 {
29     struct user_info *ui = (struct user_info*) user;
30     ui->d1_stack[ui->level] = data1_mk_tag (ui->dh, ui->nmem, el, attr,
31                                                 ui->d1_stack[ui->level-1]);
32     ui->level++;
33     printf ("cb_start %s\n", el);
34 }
35
36 static void cb_end (void *user, const char *el)
37 {
38     struct user_info *ui = (struct user_info*) user;
39
40     ui->level--;
41     printf ("cb_end %s\n", el);
42 }
43
44 static void cb_chardata (void *user, const char *s, int len)
45 {
46     struct user_info *ui = (struct user_info*) user;
47     int i;
48
49     for (i = 0; i<len; i++)
50         if (!strchr ("\n\n ", s[i]))
51             break;
52     if (i != len)
53     {
54         ui->d1_stack[ui->level] = data1_mk_text_n (ui->dh, ui->nmem, s, len,
55                                                    ui->d1_stack[ui->level -1]);
56     }
57 }
58
59 static void cb_decl (void *user, const char *version, const char*encoding,
60                      int standalone)
61 {
62     printf ("decl version=%s encoding=%s\n", version ? version : "null",
63             encoding ? encoding : "null");
64 }
65
66 static void cb_processing (void *userData, const char *target,
67                            const char *data)
68 {
69     printf ("decl processing target=%s data=%s\n", target ? target : "null",
70             data ? data : "null");
71 }
72
73 static void cb_comment (void *userData, const char *data)
74 {
75     printf ("decl comment data=%s\n", data ? data : "null");
76 }
77
78 static void cb_doctype_start (void *userData, const char *doctypeName,
79                               const char *sysid, const char *pubid,
80                               int has_internal_subset)
81 {
82     printf ("doctype start doctype=%s sysid=%s pubid=%s\n",
83             doctypeName, sysid, pubid);
84 }
85
86 static void cb_doctype_end (void *userData)
87 {
88     printf ("doctype end\n");
89 }
90
91
92 static void cb_entity_decl (void *userData, const char *entityName,
93                             int is_parameter_entity,
94                             const char *value, int value_length,
95                             const char *base, const char *systemId,
96                             const char *publicId, const char *notationName)
97 {
98     printf ("entity %s is_para_entry=%d value=%.*s base=%s systemId=%s\n"
99             " publicId=%s notationName=%s\n",
100             entityName, is_parameter_entity, value_length, value,
101             base, systemId, publicId, notationName);
102     
103 }
104
105 #define XML_CHUNK 1024
106
107 data1_node *data1_read_xml (data1_handle dh,
108                             int (*rf)(void *, char *, size_t), void *fh,
109                             NMEM m)
110 {
111     XML_Parser parser;
112     struct user_info uinfo;
113     int done = 0;
114
115     uinfo.level = 1;
116     uinfo.dh = dh;
117     uinfo.nmem = m;
118     uinfo.d1_stack[0] = data1_mk_root (dh, m, "root");
119     uinfo.d1_stack[1] = 0; /* indicate no children (see end of routine) */
120     
121     parser = XML_ParserCreate (0 /* encoding */);
122     
123     XML_SetElementHandler (parser, cb_start, cb_end);
124     XML_SetCharacterDataHandler (parser, cb_chardata);
125     XML_SetXmlDeclHandler (parser, cb_decl);
126     XML_SetProcessingInstructionHandler (parser, cb_processing);
127     XML_SetUserData (parser, &uinfo);
128     XML_SetCommentHandler (parser, cb_comment);
129     XML_SetDoctypeDeclHandler (parser, cb_doctype_start, cb_doctype_end);
130     XML_SetEntityDeclHandler (parser, cb_entity_decl);
131
132     while (!done)
133     {
134         int r;
135         void *buf = XML_GetBuffer (parser, XML_CHUNK);
136         if (!buf)
137         {
138             /* error */
139             return 0;
140         }
141         r = (*rf)(fh, buf, XML_CHUNK);
142         if (r < 0)
143         {
144             /* error */
145             return 0;
146         }
147         else if (r == 0)
148             done = 1;
149         XML_ParseBuffer (parser, r, done);
150     }
151     XML_ParserFree (parser);
152     if (!uinfo.d1_stack[1])
153         return 0;
154     return uinfo.d1_stack[0];
155 }
156
157 #endif