File: SAX.c

package info (click to toggle)
libxml 0.30-1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 560 kB
  • ctags: 375
  • sloc: ansic: 3,942; sh: 1,824; makefile: 119
file content (223 lines) | stat: -rw-r--r-- 5,806 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 * SAX.c : Default SAX handler to build a tree.
 */

#include <stdio.h>
#include <malloc.h>
#include "tree.h"
#include "parser.h"
#include "error.h"

/* #define DEBUG_SAX */

/*
 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
 */
const CHAR *getPublicId(xmlParserCtxtPtr ctxt) {
    return(NULL);
}

/*
 * Return the system ID, basically URI or filename e.g.
 *  http://www.sgmlsource.com/dtds/memo.dtd
 */
const CHAR *getSystemId(xmlParserCtxtPtr ctxt) {
    return(ctxt->input->filename); 
}

/*
 * Return the line number of the current parsing point.
 */
int getLineNumber(xmlParserCtxtPtr ctxt) {
    return(ctxt->input->line);
}
/*
 * Return the column number of the current parsing point.
 */
int getColumnNumber(xmlParserCtxtPtr ctxt) {
    return(ctxt->input->col);
}

/*
 * The default SAX Locator.
 */

xmlSAXLocator xmlDefaultSAXLocator = {
    getPublicId, getSystemId, getLineNumber, getColumnNumber
};

/*
 * Special entity resolver, better left to the parser, it has
 * more context than the application layer.
 */
xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt, 
			    const CHAR *publicId, const CHAR *systemId) {

#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
#endif
    return(NULL);
}

/*
 * What to do when a notation declaration has been parsed.
 * TODO Not handled currently.
 */
void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
		  const CHAR *publicId, const CHAR *systemId) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
#endif
}

/*
 * What to do when an unparsed entity declaration is parsed
 * TODO Create an Entity node.
 */
void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
			const CHAR *publicId, const CHAR *systemId,
			const CHAR *notationName) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
            name, publicId, systemId, notationName);
#endif
}

/*
 * Receive the document locator at startup, actually xmlDefaultSAXLocator
 * Everything is available on the context, so this is useless in our case.
 */
void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.setDocumentLocator()\n");
#endif
}

/*
 * called when the document start being processed.
 */
void startDocument(xmlParserCtxtPtr ctxt) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.startDocument()\n");
#endif
}

/*
 * called when the document end has been detected.
 */
void endDocument(xmlParserCtxtPtr ctxt) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.endDocument()\n");
#endif
}

/*
 * called when an opening tag has been processed.
 * TODO We currently have a small pblm with the arguments ...
 */
void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
    xmlNodePtr parent;

#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.startElement(%s)\n", name);
#endif
    if (ctxt->nodeNr < 2) return;
    parent = ctxt->nodeTab[ctxt->nodeNr - 2];
    if (parent != NULL)
	xmlAddChild(parent, ctxt->node);
    
}

/*
 * called when the end of an element has been detected.
 */
void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.endElement(%s)\n", name);
#endif
}

/*
 * receiving some chars from the parser.
 * Question: how much at a time ???
 */
void characters(xmlParserCtxtPtr ctxt, const CHAR *ch,
                       int start, int len) {
    xmlNodePtr lastChild;

#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
#endif
    /*
     * Handle the data if any. If there is no child
     * add it as content, otherwise if the last child is text,
     * concatenate it, else create a new node of type text.
     */

    lastChild = xmlGetLastChild(ctxt->node);
    if (lastChild == NULL)
	xmlNodeAddContentLen(ctxt->node, &ch[start], len);
    else {
	if (xmlNodeIsText(lastChild))
	    xmlTextConcat(lastChild, &ch[start], len);
	else {
	    lastChild = xmlNewTextLen(&ch[start], len);
	    xmlAddChild(ctxt->node, lastChild);
	}
    }
}

/*
 * receiving some ignorable whitespaces from the parser.
 * Question: how much at a time ???
 */
void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch,
                         int start, int len) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
#endif
}

/*
 * A processing instruction has beem parsed.
 */
void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
			   const CHAR *data) {
#ifdef DEBUG_SAX
    fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
#endif
}

xmlSAXHandler xmlDefaultSAXHandler = {
    resolveEntity,
    notationDecl,
    unparsedEntityDecl,
    setDocumentLocator,
    startDocument,
    endDocument,
    startElement,
    endElement,
    characters,
    ignorableWhitespace,
    processingInstruction,
    xmlParserWarning,
    xmlParserError,
    xmlParserError,
};

void xmlDefaultSAXHandlerInit(void) {
    xmlDefaultSAXHandler.resolveEntity = resolveEntity;
    xmlDefaultSAXHandler.notationDecl = notationDecl;
    xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
    xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
    xmlDefaultSAXHandler.startDocument = startDocument;
    xmlDefaultSAXHandler.endDocument = endDocument;
    xmlDefaultSAXHandler.startElement = startElement;
    xmlDefaultSAXHandler.endElement = endElement;
    xmlDefaultSAXHandler.characters = characters;
    xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
    xmlDefaultSAXHandler.processingInstruction = processingInstruction;
    xmlDefaultSAXHandler.warning = xmlParserWarning;
    xmlDefaultSAXHandler.error = xmlParserError;
    xmlDefaultSAXHandler.fatalError = xmlParserError;
}