2 * Sherlock Library -- A simple XML parser
4 * (c) 2007 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 #include "sherlock/sherlock.h"
11 #include "sherlock/xml/xml.h"
12 #include "lib/getopt.h"
13 #include "lib/fastbuf.h"
18 static char *shortopts = "sp" CF_SHORT_OPTS;
19 static struct option longopts[] = {
22 { "pull", 0, 0, 'p' },
31 Usage: xml-test [options] < in.xml\n\
36 -s, --pull Test PULL interface\n\
37 -s, --sax Test SAX interface\n\
38 -d, --dom Test DOM interface\n\
46 static struct fastbuf *out;
49 node_type(struct xml_node *node)
53 case XML_NODE_ELEM: return "element";
54 case XML_NODE_COMMENT: return "comment";
55 case XML_NODE_PI: return "pi";
56 case XML_NODE_CDATA: return "chars";
57 default: return "unknown";
62 show_node(struct xml_node *node)
67 bprintf(out, " <%s>", node->name);
68 SLIST_FOR_EACH(struct xml_attr *, a, node->attrs)
69 bprintf(out, " %s='%s'", a->name, a->val);
72 case XML_NODE_COMMENT:
73 bprintf(out, " text='%s'\n", node->text);
76 bprintf(out, " target=%s text='%s'\n", node->name, node->text);
79 bprintf(out, " text='%s'\n", node->text);
87 show_tree(struct xml_node *node, uns level)
92 for (uns i = 0; i < level; i++)
94 bputs(out, node_type(node));
96 if (node->type == XML_NODE_ELEM)
97 CLIST_FOR_EACH(struct xml_node *, son, node->sons)
98 show_tree(son, level + 1);
102 h_error(struct xml_context *ctx)
104 bprintf(out, "SAX: %s at %u: %s\n", (ctx->err_code < XML_ERR_ERROR) ? "warn" : "error", xml_row(ctx), ctx->err_msg);
108 h_document_start(struct xml_context *ctx UNUSED)
110 bputs(out, "SAX: document_start\n");
114 h_document_end(struct xml_context *ctx UNUSED)
116 bputs(out, "SAX: document_end\n");
120 h_xml_decl(struct xml_context *ctx)
122 bprintf(out, "SAX: xml_decl version=%s standalone=%d\n", ctx->version_str, ctx->standalone);
126 h_doctype_decl(struct xml_context *ctx)
128 bprintf(out, "SAX: doctype_decl type=%s public='%s' system='%s' extsub=%d intsub=%d\n",
129 ctx->document_type, ctx->eid.public_id ? : "", ctx->eid.system_id ? : "",
130 !!(ctx->flags & XML_FLAG_HAS_EXTERNAL_SUBSET), !!(ctx->flags & XML_FLAG_HAS_INTERNAL_SUBSET));
134 h_comment(struct xml_context *ctx)
136 bputs(out, "SAX: comment");
137 show_node(ctx->node);
141 h_pi(struct xml_context *ctx)
143 bprintf(out, "SAX: pi");
144 show_node(ctx->node);
148 h_element_start(struct xml_context *ctx)
150 bprintf(out, "SAX: element_start");
151 show_node(ctx->node);
155 h_element_end(struct xml_context *ctx)
157 bprintf(out, "SAX: element_end </%s>\n", ctx->node->name);
161 h_chars(struct xml_context *ctx)
163 bprintf(out, "SAX: chars");
164 show_node(ctx->node);
168 main(int argc, char **argv)
171 cf_def_file = NULL; // FIXME
173 while ((opt = cf_getopt(argc, argv, shortopts, longopts, NULL)) >= 0)
191 out = bfdopen_shared(1, 4096);
192 struct xml_context ctx;
194 ctx.h_warn = ctx.h_error = ctx.h_fatal = h_error;
197 ctx.h_document_start = h_document_start;
198 ctx.h_document_end = h_document_end;
199 ctx.h_xml_decl = h_xml_decl;
200 ctx.h_doctype_decl = h_doctype_decl;
201 ctx.h_comment = h_comment;
203 ctx.h_element_start = h_element_start;
204 ctx.h_element_end = h_element_end;
205 ctx.h_chars = h_chars;
208 ctx.want = XML_WANT_CHARS | XML_WANT_STAG | XML_WANT_ETAG | XML_WANT_COMMENT | XML_WANT_PI;
210 ctx.flags &= ~XML_DOM_FREE;
211 xml_set_source(&ctx, bfdopen_shared(0, 4096));
213 bprintf(out, "PULL: start\n");
214 while ((state = xml_next(&ctx)) >= 0 && state != XML_STATE_EOF)
217 case XML_STATE_CHARS:
218 bprintf(out, "PULL: chars");
222 bprintf(out, "PULL: element_start");
226 bprintf(out, "PULL: element_end </%s>\n", ctx.node->name);
228 case XML_STATE_COMMENT:
229 bprintf(out, "PULL: comment");
233 bprintf(out, "PULL: pi");
237 case XML_STATE_CDATA:
238 bprintf(out, "PULL: cdata [%s]\n", ctx.node->text);
242 if (state != XML_STATE_EOF)
243 bprintf(out, "PULL: fatal error\n");
245 bprintf(out, "PULL: eof\n");
248 show_tree(ctx.root, 0);