pocxxeci 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pocxxeci might be problematic. Click here for more details.
- package/LICENSE +19 -0
- package/Makefile +18 -0
- package/README.md +52 -0
- package/binding.gyp +81 -0
- package/index.d.ts +273 -0
- package/index.js +45 -0
- package/lib/bindings.js +1 -0
- package/lib/document.js +122 -0
- package/lib/element.js +82 -0
- package/lib/sax_parser.js +38 -0
- package/package.json +70 -0
- package/src/html_document.cc +7 -0
- package/src/html_document.h +18 -0
- package/src/libxmljs.cc +252 -0
- package/src/libxmljs.h +53 -0
- package/src/xml_attribute.cc +173 -0
- package/src/xml_attribute.h +40 -0
- package/src/xml_comment.cc +117 -0
- package/src/xml_comment.h +30 -0
- package/src/xml_document.cc +810 -0
- package/src/xml_document.h +67 -0
- package/src/xml_element.cc +565 -0
- package/src/xml_element.h +61 -0
- package/src/xml_namespace.cc +158 -0
- package/src/xml_namespace.h +39 -0
- package/src/xml_node.cc +761 -0
- package/src/xml_node.h +73 -0
- package/src/xml_pi.cc +161 -0
- package/src/xml_pi.h +34 -0
- package/src/xml_sax_parser.cc +424 -0
- package/src/xml_sax_parser.h +73 -0
- package/src/xml_syntax_error.cc +66 -0
- package/src/xml_syntax_error.h +25 -0
- package/src/xml_text.cc +320 -0
- package/src/xml_text.h +48 -0
- package/src/xml_textwriter.cc +315 -0
- package/src/xml_textwriter.h +62 -0
- package/src/xml_xpath_context.cc +70 -0
- package/src/xml_xpath_context.h +23 -0
- package/vendor/libxml/Copyright +23 -0
- package/vendor/libxml/DOCBparser.c +305 -0
- package/vendor/libxml/HTMLparser.c +7287 -0
- package/vendor/libxml/HTMLtree.c +1200 -0
- package/vendor/libxml/Makefile +2983 -0
- package/vendor/libxml/SAX.c +180 -0
- package/vendor/libxml/SAX2.c +3036 -0
- package/vendor/libxml/buf.c +1351 -0
- package/vendor/libxml/buf.h +72 -0
- package/vendor/libxml/c14n.c +2234 -0
- package/vendor/libxml/catalog.c +3828 -0
- package/vendor/libxml/chvalid.c +336 -0
- package/vendor/libxml/config.h +294 -0
- package/vendor/libxml/config.h.gch +0 -0
- package/vendor/libxml/debugXML.c +3423 -0
- package/vendor/libxml/dict.c +1298 -0
- package/vendor/libxml/elfgcchack.h +17818 -0
- package/vendor/libxml/enc.h +32 -0
- package/vendor/libxml/encoding.c +3975 -0
- package/vendor/libxml/entities.c +1163 -0
- package/vendor/libxml/error.c +998 -0
- package/vendor/libxml/globals.c +1126 -0
- package/vendor/libxml/hash.c +1146 -0
- package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
- package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
- package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
- package/vendor/libxml/include/libxml/Makefile +725 -0
- package/vendor/libxml/include/libxml/Makefile.am +54 -0
- package/vendor/libxml/include/libxml/Makefile.in +725 -0
- package/vendor/libxml/include/libxml/SAX.h +173 -0
- package/vendor/libxml/include/libxml/SAX2.h +178 -0
- package/vendor/libxml/include/libxml/c14n.h +128 -0
- package/vendor/libxml/include/libxml/catalog.h +182 -0
- package/vendor/libxml/include/libxml/chvalid.h +230 -0
- package/vendor/libxml/include/libxml/debugXML.h +217 -0
- package/vendor/libxml/include/libxml/dict.h +79 -0
- package/vendor/libxml/include/libxml/encoding.h +245 -0
- package/vendor/libxml/include/libxml/entities.h +151 -0
- package/vendor/libxml/include/libxml/globals.h +508 -0
- package/vendor/libxml/include/libxml/hash.h +236 -0
- package/vendor/libxml/include/libxml/list.h +137 -0
- package/vendor/libxml/include/libxml/nanoftp.h +163 -0
- package/vendor/libxml/include/libxml/nanohttp.h +81 -0
- package/vendor/libxml/include/libxml/parser.h +1243 -0
- package/vendor/libxml/include/libxml/parserInternals.h +644 -0
- package/vendor/libxml/include/libxml/pattern.h +100 -0
- package/vendor/libxml/include/libxml/relaxng.h +217 -0
- package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
- package/vendor/libxml/include/libxml/schematron.h +142 -0
- package/vendor/libxml/include/libxml/threads.h +89 -0
- package/vendor/libxml/include/libxml/tree.h +1311 -0
- package/vendor/libxml/include/libxml/uri.h +94 -0
- package/vendor/libxml/include/libxml/valid.h +458 -0
- package/vendor/libxml/include/libxml/xinclude.h +129 -0
- package/vendor/libxml/include/libxml/xlink.h +189 -0
- package/vendor/libxml/include/libxml/xmlIO.h +368 -0
- package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
- package/vendor/libxml/include/libxml/xmlerror.h +945 -0
- package/vendor/libxml/include/libxml/xmlexports.h +77 -0
- package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
- package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
- package/vendor/libxml/include/libxml/xmlreader.h +428 -0
- package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
- package/vendor/libxml/include/libxml/xmlsave.h +88 -0
- package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
- package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
- package/vendor/libxml/include/libxml/xmlstring.h +140 -0
- package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
- package/vendor/libxml/include/libxml/xmlversion.h +484 -0
- package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
- package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
- package/vendor/libxml/include/libxml/xpath.h +564 -0
- package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
- package/vendor/libxml/include/libxml/xpointer.h +114 -0
- package/vendor/libxml/include/win32config.h +122 -0
- package/vendor/libxml/include/wsockcompat.h +54 -0
- package/vendor/libxml/legacy.c +1343 -0
- package/vendor/libxml/libxml.h +134 -0
- package/vendor/libxml/list.c +779 -0
- package/vendor/libxml/nanoftp.c +2118 -0
- package/vendor/libxml/nanohttp.c +1899 -0
- package/vendor/libxml/parser.c +15553 -0
- package/vendor/libxml/parserInternals.c +2164 -0
- package/vendor/libxml/pattern.c +2621 -0
- package/vendor/libxml/relaxng.c +11101 -0
- package/vendor/libxml/rngparser.c +1595 -0
- package/vendor/libxml/runsuite.c +1157 -0
- package/vendor/libxml/save.h +36 -0
- package/vendor/libxml/schematron.c +1787 -0
- package/vendor/libxml/threads.c +1049 -0
- package/vendor/libxml/timsort.h +601 -0
- package/vendor/libxml/tree.c +10183 -0
- package/vendor/libxml/trio.c +6895 -0
- package/vendor/libxml/trio.h +230 -0
- package/vendor/libxml/triodef.h +228 -0
- package/vendor/libxml/trionan.c +914 -0
- package/vendor/libxml/trionan.h +84 -0
- package/vendor/libxml/triop.h +150 -0
- package/vendor/libxml/triostr.c +2112 -0
- package/vendor/libxml/triostr.h +144 -0
- package/vendor/libxml/uri.c +2561 -0
- package/vendor/libxml/valid.c +7138 -0
- package/vendor/libxml/xinclude.c +2657 -0
- package/vendor/libxml/xlink.c +183 -0
- package/vendor/libxml/xmlIO.c +4135 -0
- package/vendor/libxml/xmlcatalog.c +624 -0
- package/vendor/libxml/xmllint.c +3796 -0
- package/vendor/libxml/xmlmemory.c +1163 -0
- package/vendor/libxml/xmlmodule.c +468 -0
- package/vendor/libxml/xmlreader.c +6033 -0
- package/vendor/libxml/xmlregexp.c +8271 -0
- package/vendor/libxml/xmlsave.c +2735 -0
- package/vendor/libxml/xmlschemas.c +29173 -0
- package/vendor/libxml/xmlschemastypes.c +6276 -0
- package/vendor/libxml/xmlstring.c +1050 -0
- package/vendor/libxml/xmlunicode.c +3179 -0
- package/vendor/libxml/xmlwriter.c +4738 -0
- package/vendor/libxml/xpath.c +14734 -0
- package/vendor/libxml/xpointer.c +2969 -0
- package/vendor/libxml/xzlib.c +815 -0
- package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,3036 @@
|
|
1
|
+
/*
|
2
|
+
* SAX2.c : Default SAX2 handler to build a tree.
|
3
|
+
*
|
4
|
+
* See Copyright for the status of this software.
|
5
|
+
*
|
6
|
+
* Daniel Veillard <daniel@veillard.com>
|
7
|
+
*/
|
8
|
+
|
9
|
+
|
10
|
+
#define IN_LIBXML
|
11
|
+
#include "libxml.h"
|
12
|
+
#include <stdlib.h>
|
13
|
+
#include <string.h>
|
14
|
+
#include <limits.h>
|
15
|
+
#include <stddef.h>
|
16
|
+
#include <libxml/xmlmemory.h>
|
17
|
+
#include <libxml/tree.h>
|
18
|
+
#include <libxml/parser.h>
|
19
|
+
#include <libxml/parserInternals.h>
|
20
|
+
#include <libxml/valid.h>
|
21
|
+
#include <libxml/entities.h>
|
22
|
+
#include <libxml/xmlerror.h>
|
23
|
+
#include <libxml/debugXML.h>
|
24
|
+
#include <libxml/xmlIO.h>
|
25
|
+
#include <libxml/SAX.h>
|
26
|
+
#include <libxml/uri.h>
|
27
|
+
#include <libxml/valid.h>
|
28
|
+
#include <libxml/HTMLtree.h>
|
29
|
+
#include <libxml/globals.h>
|
30
|
+
|
31
|
+
/* Define SIZE_T_MAX unless defined through <limits.h>. */
|
32
|
+
#ifndef SIZE_T_MAX
|
33
|
+
# define SIZE_T_MAX ((size_t)-1)
|
34
|
+
#endif /* !SIZE_T_MAX */
|
35
|
+
|
36
|
+
/* #define DEBUG_SAX2 */
|
37
|
+
/* #define DEBUG_SAX2_TREE */
|
38
|
+
|
39
|
+
/**
|
40
|
+
* TODO:
|
41
|
+
*
|
42
|
+
* macro to flag unimplemented blocks
|
43
|
+
* XML_CATALOG_PREFER user env to select between system/public preferred
|
44
|
+
* option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
|
45
|
+
*> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
|
46
|
+
*> values "system" and "public". I have made the default be "system" to
|
47
|
+
*> match yours.
|
48
|
+
*/
|
49
|
+
#define TODO \
|
50
|
+
xmlGenericError(xmlGenericErrorContext, \
|
51
|
+
"Unimplemented block at %s:%d\n", \
|
52
|
+
__FILE__, __LINE__);
|
53
|
+
|
54
|
+
/*
|
55
|
+
* xmlSAX2ErrMemory:
|
56
|
+
* @ctxt: an XML validation parser context
|
57
|
+
* @msg: a string to accompany the error message
|
58
|
+
*/
|
59
|
+
static void LIBXML_ATTR_FORMAT(2,0)
|
60
|
+
xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
|
61
|
+
xmlStructuredErrorFunc schannel = NULL;
|
62
|
+
const char *str1 = "out of memory\n";
|
63
|
+
|
64
|
+
if (ctxt != NULL) {
|
65
|
+
ctxt->errNo = XML_ERR_NO_MEMORY;
|
66
|
+
if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
|
67
|
+
schannel = ctxt->sax->serror;
|
68
|
+
__xmlRaiseError(schannel,
|
69
|
+
ctxt->vctxt.error, ctxt->vctxt.userData,
|
70
|
+
ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
|
71
|
+
XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
72
|
+
NULL, NULL, 0, 0,
|
73
|
+
msg, (const char *) str1, NULL);
|
74
|
+
ctxt->errNo = XML_ERR_NO_MEMORY;
|
75
|
+
ctxt->instate = XML_PARSER_EOF;
|
76
|
+
ctxt->disableSAX = 1;
|
77
|
+
} else {
|
78
|
+
__xmlRaiseError(schannel,
|
79
|
+
NULL, NULL,
|
80
|
+
ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
|
81
|
+
XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
82
|
+
NULL, NULL, 0, 0,
|
83
|
+
msg, (const char *) str1, NULL);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* xmlValidError:
|
89
|
+
* @ctxt: an XML validation parser context
|
90
|
+
* @error: the error number
|
91
|
+
* @msg: the error message
|
92
|
+
* @str1: extra data
|
93
|
+
* @str2: extra data
|
94
|
+
*
|
95
|
+
* Handle a validation error
|
96
|
+
*/
|
97
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
98
|
+
xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
99
|
+
const char *msg, const char *str1, const char *str2)
|
100
|
+
{
|
101
|
+
xmlStructuredErrorFunc schannel = NULL;
|
102
|
+
|
103
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
104
|
+
(ctxt->instate == XML_PARSER_EOF))
|
105
|
+
return;
|
106
|
+
if (ctxt != NULL) {
|
107
|
+
ctxt->errNo = error;
|
108
|
+
if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
|
109
|
+
schannel = ctxt->sax->serror;
|
110
|
+
__xmlRaiseError(schannel,
|
111
|
+
ctxt->vctxt.error, ctxt->vctxt.userData,
|
112
|
+
ctxt, NULL, XML_FROM_DTD, error,
|
113
|
+
XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
114
|
+
(const char *) str2, NULL, 0, 0,
|
115
|
+
msg, (const char *) str1, (const char *) str2);
|
116
|
+
ctxt->valid = 0;
|
117
|
+
} else {
|
118
|
+
__xmlRaiseError(schannel,
|
119
|
+
NULL, NULL,
|
120
|
+
ctxt, NULL, XML_FROM_DTD, error,
|
121
|
+
XML_ERR_ERROR, NULL, 0, (const char *) str1,
|
122
|
+
(const char *) str2, NULL, 0, 0,
|
123
|
+
msg, (const char *) str1, (const char *) str2);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* xmlFatalErrMsg:
|
129
|
+
* @ctxt: an XML parser context
|
130
|
+
* @error: the error number
|
131
|
+
* @msg: the error message
|
132
|
+
* @str1: an error string
|
133
|
+
* @str2: an error string
|
134
|
+
*
|
135
|
+
* Handle a fatal parser error, i.e. violating Well-Formedness constraints
|
136
|
+
*/
|
137
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
138
|
+
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
139
|
+
const char *msg, const xmlChar *str1, const xmlChar *str2)
|
140
|
+
{
|
141
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
142
|
+
(ctxt->instate == XML_PARSER_EOF))
|
143
|
+
return;
|
144
|
+
if (ctxt != NULL)
|
145
|
+
ctxt->errNo = error;
|
146
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
|
147
|
+
XML_ERR_FATAL, NULL, 0,
|
148
|
+
(const char *) str1, (const char *) str2,
|
149
|
+
NULL, 0, 0, msg, str1, str2);
|
150
|
+
if (ctxt != NULL) {
|
151
|
+
ctxt->wellFormed = 0;
|
152
|
+
ctxt->valid = 0;
|
153
|
+
if (ctxt->recovery == 0)
|
154
|
+
ctxt->disableSAX = 1;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* xmlWarnMsg:
|
160
|
+
* @ctxt: an XML parser context
|
161
|
+
* @error: the error number
|
162
|
+
* @msg: the error message
|
163
|
+
* @str1: an error string
|
164
|
+
* @str2: an error string
|
165
|
+
*
|
166
|
+
* Handle a parser warning
|
167
|
+
*/
|
168
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
169
|
+
xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
170
|
+
const char *msg, const xmlChar *str1)
|
171
|
+
{
|
172
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
173
|
+
(ctxt->instate == XML_PARSER_EOF))
|
174
|
+
return;
|
175
|
+
if (ctxt != NULL)
|
176
|
+
ctxt->errNo = error;
|
177
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
|
178
|
+
XML_ERR_WARNING, NULL, 0,
|
179
|
+
(const char *) str1, NULL,
|
180
|
+
NULL, 0, 0, msg, str1);
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* xmlNsErrMsg:
|
185
|
+
* @ctxt: an XML parser context
|
186
|
+
* @error: the error number
|
187
|
+
* @msg: the error message
|
188
|
+
* @str1: an error string
|
189
|
+
* @str2: an error string
|
190
|
+
*
|
191
|
+
* Handle a namespace error
|
192
|
+
*/
|
193
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
194
|
+
xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
195
|
+
const char *msg, const xmlChar *str1, const xmlChar *str2)
|
196
|
+
{
|
197
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
198
|
+
(ctxt->instate == XML_PARSER_EOF))
|
199
|
+
return;
|
200
|
+
if (ctxt != NULL)
|
201
|
+
ctxt->errNo = error;
|
202
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
203
|
+
XML_ERR_ERROR, NULL, 0,
|
204
|
+
(const char *) str1, (const char *) str2,
|
205
|
+
NULL, 0, 0, msg, str1, str2);
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
* xmlNsWarnMsg:
|
210
|
+
* @ctxt: an XML parser context
|
211
|
+
* @error: the error number
|
212
|
+
* @msg: the error message
|
213
|
+
* @str1: an error string
|
214
|
+
*
|
215
|
+
* Handle a namespace warning
|
216
|
+
*/
|
217
|
+
static void LIBXML_ATTR_FORMAT(3,0)
|
218
|
+
xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
219
|
+
const char *msg, const xmlChar *str1, const xmlChar *str2)
|
220
|
+
{
|
221
|
+
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
222
|
+
(ctxt->instate == XML_PARSER_EOF))
|
223
|
+
return;
|
224
|
+
if (ctxt != NULL)
|
225
|
+
ctxt->errNo = error;
|
226
|
+
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
227
|
+
XML_ERR_WARNING, NULL, 0,
|
228
|
+
(const char *) str1, (const char *) str2,
|
229
|
+
NULL, 0, 0, msg, str1, str2);
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* xmlSAX2GetPublicId:
|
234
|
+
* @ctx: the user data (XML parser context)
|
235
|
+
*
|
236
|
+
* Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
|
237
|
+
*
|
238
|
+
* Returns a xmlChar *
|
239
|
+
*/
|
240
|
+
const xmlChar *
|
241
|
+
xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
|
242
|
+
{
|
243
|
+
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
244
|
+
return(NULL);
|
245
|
+
}
|
246
|
+
|
247
|
+
/**
|
248
|
+
* xmlSAX2GetSystemId:
|
249
|
+
* @ctx: the user data (XML parser context)
|
250
|
+
*
|
251
|
+
* Provides the system ID, basically URL or filename e.g.
|
252
|
+
* http://www.sgmlsource.com/dtds/memo.dtd
|
253
|
+
*
|
254
|
+
* Returns a xmlChar *
|
255
|
+
*/
|
256
|
+
const xmlChar *
|
257
|
+
xmlSAX2GetSystemId(void *ctx)
|
258
|
+
{
|
259
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
260
|
+
if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
|
261
|
+
return((const xmlChar *) ctxt->input->filename);
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* xmlSAX2GetLineNumber:
|
266
|
+
* @ctx: the user data (XML parser context)
|
267
|
+
*
|
268
|
+
* Provide the line number of the current parsing point.
|
269
|
+
*
|
270
|
+
* Returns an int
|
271
|
+
*/
|
272
|
+
int
|
273
|
+
xmlSAX2GetLineNumber(void *ctx)
|
274
|
+
{
|
275
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
276
|
+
if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
|
277
|
+
return(ctxt->input->line);
|
278
|
+
}
|
279
|
+
|
280
|
+
/**
|
281
|
+
* xmlSAX2GetColumnNumber:
|
282
|
+
* @ctx: the user data (XML parser context)
|
283
|
+
*
|
284
|
+
* Provide the column number of the current parsing point.
|
285
|
+
*
|
286
|
+
* Returns an int
|
287
|
+
*/
|
288
|
+
int
|
289
|
+
xmlSAX2GetColumnNumber(void *ctx)
|
290
|
+
{
|
291
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
292
|
+
if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
|
293
|
+
return(ctxt->input->col);
|
294
|
+
}
|
295
|
+
|
296
|
+
/**
|
297
|
+
* xmlSAX2IsStandalone:
|
298
|
+
* @ctx: the user data (XML parser context)
|
299
|
+
*
|
300
|
+
* Is this document tagged standalone ?
|
301
|
+
*
|
302
|
+
* Returns 1 if true
|
303
|
+
*/
|
304
|
+
int
|
305
|
+
xmlSAX2IsStandalone(void *ctx)
|
306
|
+
{
|
307
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
308
|
+
if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
|
309
|
+
return(ctxt->myDoc->standalone == 1);
|
310
|
+
}
|
311
|
+
|
312
|
+
/**
|
313
|
+
* xmlSAX2HasInternalSubset:
|
314
|
+
* @ctx: the user data (XML parser context)
|
315
|
+
*
|
316
|
+
* Does this document has an internal subset
|
317
|
+
*
|
318
|
+
* Returns 1 if true
|
319
|
+
*/
|
320
|
+
int
|
321
|
+
xmlSAX2HasInternalSubset(void *ctx)
|
322
|
+
{
|
323
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
324
|
+
if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
|
325
|
+
return(ctxt->myDoc->intSubset != NULL);
|
326
|
+
}
|
327
|
+
|
328
|
+
/**
|
329
|
+
* xmlSAX2HasExternalSubset:
|
330
|
+
* @ctx: the user data (XML parser context)
|
331
|
+
*
|
332
|
+
* Does this document has an external subset
|
333
|
+
*
|
334
|
+
* Returns 1 if true
|
335
|
+
*/
|
336
|
+
int
|
337
|
+
xmlSAX2HasExternalSubset(void *ctx)
|
338
|
+
{
|
339
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
340
|
+
if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
|
341
|
+
return(ctxt->myDoc->extSubset != NULL);
|
342
|
+
}
|
343
|
+
|
344
|
+
/**
|
345
|
+
* xmlSAX2InternalSubset:
|
346
|
+
* @ctx: the user data (XML parser context)
|
347
|
+
* @name: the root element name
|
348
|
+
* @ExternalID: the external ID
|
349
|
+
* @SystemID: the SYSTEM ID (e.g. filename or URL)
|
350
|
+
*
|
351
|
+
* Callback on internal subset declaration.
|
352
|
+
*/
|
353
|
+
void
|
354
|
+
xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
|
355
|
+
const xmlChar *ExternalID, const xmlChar *SystemID)
|
356
|
+
{
|
357
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
358
|
+
xmlDtdPtr dtd;
|
359
|
+
if (ctx == NULL) return;
|
360
|
+
#ifdef DEBUG_SAX
|
361
|
+
xmlGenericError(xmlGenericErrorContext,
|
362
|
+
"SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
|
363
|
+
name, ExternalID, SystemID);
|
364
|
+
#endif
|
365
|
+
|
366
|
+
if (ctxt->myDoc == NULL)
|
367
|
+
return;
|
368
|
+
dtd = xmlGetIntSubset(ctxt->myDoc);
|
369
|
+
if (dtd != NULL) {
|
370
|
+
if (ctxt->html)
|
371
|
+
return;
|
372
|
+
xmlUnlinkNode((xmlNodePtr) dtd);
|
373
|
+
xmlFreeDtd(dtd);
|
374
|
+
ctxt->myDoc->intSubset = NULL;
|
375
|
+
}
|
376
|
+
ctxt->myDoc->intSubset =
|
377
|
+
xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
|
378
|
+
if (ctxt->myDoc->intSubset == NULL)
|
379
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
|
380
|
+
}
|
381
|
+
|
382
|
+
/**
|
383
|
+
* xmlSAX2ExternalSubset:
|
384
|
+
* @ctx: the user data (XML parser context)
|
385
|
+
* @name: the root element name
|
386
|
+
* @ExternalID: the external ID
|
387
|
+
* @SystemID: the SYSTEM ID (e.g. filename or URL)
|
388
|
+
*
|
389
|
+
* Callback on external subset declaration.
|
390
|
+
*/
|
391
|
+
void
|
392
|
+
xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
|
393
|
+
const xmlChar *ExternalID, const xmlChar *SystemID)
|
394
|
+
{
|
395
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
396
|
+
if (ctx == NULL) return;
|
397
|
+
#ifdef DEBUG_SAX
|
398
|
+
xmlGenericError(xmlGenericErrorContext,
|
399
|
+
"SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
|
400
|
+
name, ExternalID, SystemID);
|
401
|
+
#endif
|
402
|
+
if (((ExternalID != NULL) || (SystemID != NULL)) &&
|
403
|
+
(((ctxt->validate) || (ctxt->loadsubset != 0)) &&
|
404
|
+
(ctxt->wellFormed && ctxt->myDoc))) {
|
405
|
+
/*
|
406
|
+
* Try to fetch and parse the external subset.
|
407
|
+
*/
|
408
|
+
xmlParserInputPtr oldinput;
|
409
|
+
int oldinputNr;
|
410
|
+
int oldinputMax;
|
411
|
+
xmlParserInputPtr *oldinputTab;
|
412
|
+
xmlParserInputPtr input = NULL;
|
413
|
+
xmlCharEncoding enc;
|
414
|
+
int oldcharset;
|
415
|
+
const xmlChar *oldencoding;
|
416
|
+
|
417
|
+
/*
|
418
|
+
* Ask the Entity resolver to load the damn thing
|
419
|
+
*/
|
420
|
+
if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
|
421
|
+
input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
|
422
|
+
SystemID);
|
423
|
+
if (input == NULL) {
|
424
|
+
return;
|
425
|
+
}
|
426
|
+
|
427
|
+
xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
|
428
|
+
|
429
|
+
/*
|
430
|
+
* make sure we won't destroy the main document context
|
431
|
+
*/
|
432
|
+
oldinput = ctxt->input;
|
433
|
+
oldinputNr = ctxt->inputNr;
|
434
|
+
oldinputMax = ctxt->inputMax;
|
435
|
+
oldinputTab = ctxt->inputTab;
|
436
|
+
oldcharset = ctxt->charset;
|
437
|
+
oldencoding = ctxt->encoding;
|
438
|
+
ctxt->encoding = NULL;
|
439
|
+
|
440
|
+
ctxt->inputTab = (xmlParserInputPtr *)
|
441
|
+
xmlMalloc(5 * sizeof(xmlParserInputPtr));
|
442
|
+
if (ctxt->inputTab == NULL) {
|
443
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
|
444
|
+
ctxt->input = oldinput;
|
445
|
+
ctxt->inputNr = oldinputNr;
|
446
|
+
ctxt->inputMax = oldinputMax;
|
447
|
+
ctxt->inputTab = oldinputTab;
|
448
|
+
ctxt->charset = oldcharset;
|
449
|
+
ctxt->encoding = oldencoding;
|
450
|
+
return;
|
451
|
+
}
|
452
|
+
ctxt->inputNr = 0;
|
453
|
+
ctxt->inputMax = 5;
|
454
|
+
ctxt->input = NULL;
|
455
|
+
xmlPushInput(ctxt, input);
|
456
|
+
|
457
|
+
/*
|
458
|
+
* On the fly encoding conversion if needed
|
459
|
+
*/
|
460
|
+
if (ctxt->input->length >= 4) {
|
461
|
+
enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
|
462
|
+
xmlSwitchEncoding(ctxt, enc);
|
463
|
+
}
|
464
|
+
|
465
|
+
if (input->filename == NULL)
|
466
|
+
input->filename = (char *) xmlCanonicPath(SystemID);
|
467
|
+
input->line = 1;
|
468
|
+
input->col = 1;
|
469
|
+
input->base = ctxt->input->cur;
|
470
|
+
input->cur = ctxt->input->cur;
|
471
|
+
input->free = NULL;
|
472
|
+
|
473
|
+
/*
|
474
|
+
* let's parse that entity knowing it's an external subset.
|
475
|
+
*/
|
476
|
+
xmlParseExternalSubset(ctxt, ExternalID, SystemID);
|
477
|
+
|
478
|
+
/*
|
479
|
+
* Free up the external entities
|
480
|
+
*/
|
481
|
+
|
482
|
+
while (ctxt->inputNr > 1)
|
483
|
+
xmlPopInput(ctxt);
|
484
|
+
xmlFreeInputStream(ctxt->input);
|
485
|
+
xmlFree(ctxt->inputTab);
|
486
|
+
|
487
|
+
/*
|
488
|
+
* Restore the parsing context of the main entity
|
489
|
+
*/
|
490
|
+
ctxt->input = oldinput;
|
491
|
+
ctxt->inputNr = oldinputNr;
|
492
|
+
ctxt->inputMax = oldinputMax;
|
493
|
+
ctxt->inputTab = oldinputTab;
|
494
|
+
ctxt->charset = oldcharset;
|
495
|
+
if ((ctxt->encoding != NULL) &&
|
496
|
+
((ctxt->dict == NULL) ||
|
497
|
+
(!xmlDictOwns(ctxt->dict, ctxt->encoding))))
|
498
|
+
xmlFree((xmlChar *) ctxt->encoding);
|
499
|
+
ctxt->encoding = oldencoding;
|
500
|
+
/* ctxt->wellFormed = oldwellFormed; */
|
501
|
+
}
|
502
|
+
}
|
503
|
+
|
504
|
+
/**
|
505
|
+
* xmlSAX2ResolveEntity:
|
506
|
+
* @ctx: the user data (XML parser context)
|
507
|
+
* @publicId: The public ID of the entity
|
508
|
+
* @systemId: The system ID of the entity
|
509
|
+
*
|
510
|
+
* The entity loader, to control the loading of external entities,
|
511
|
+
* the application can either:
|
512
|
+
* - override this xmlSAX2ResolveEntity() callback in the SAX block
|
513
|
+
* - or better use the xmlSetExternalEntityLoader() function to
|
514
|
+
* set up it's own entity resolution routine
|
515
|
+
*
|
516
|
+
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
|
517
|
+
*/
|
518
|
+
xmlParserInputPtr
|
519
|
+
xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
|
520
|
+
{
|
521
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
522
|
+
xmlParserInputPtr ret;
|
523
|
+
xmlChar *URI;
|
524
|
+
const char *base = NULL;
|
525
|
+
|
526
|
+
if (ctx == NULL) return(NULL);
|
527
|
+
if (ctxt->input != NULL)
|
528
|
+
base = ctxt->input->filename;
|
529
|
+
if (base == NULL)
|
530
|
+
base = ctxt->directory;
|
531
|
+
|
532
|
+
URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
533
|
+
|
534
|
+
#ifdef DEBUG_SAX
|
535
|
+
xmlGenericError(xmlGenericErrorContext,
|
536
|
+
"SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
|
537
|
+
#endif
|
538
|
+
|
539
|
+
ret = xmlLoadExternalEntity((const char *) URI,
|
540
|
+
(const char *) publicId, ctxt);
|
541
|
+
if (URI != NULL)
|
542
|
+
xmlFree(URI);
|
543
|
+
return(ret);
|
544
|
+
}
|
545
|
+
|
546
|
+
/**
|
547
|
+
* xmlSAX2GetEntity:
|
548
|
+
* @ctx: the user data (XML parser context)
|
549
|
+
* @name: The entity name
|
550
|
+
*
|
551
|
+
* Get an entity by name
|
552
|
+
*
|
553
|
+
* Returns the xmlEntityPtr if found.
|
554
|
+
*/
|
555
|
+
xmlEntityPtr
|
556
|
+
xmlSAX2GetEntity(void *ctx, const xmlChar *name)
|
557
|
+
{
|
558
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
559
|
+
xmlEntityPtr ret = NULL;
|
560
|
+
|
561
|
+
if (ctx == NULL) return(NULL);
|
562
|
+
#ifdef DEBUG_SAX
|
563
|
+
xmlGenericError(xmlGenericErrorContext,
|
564
|
+
"SAX.xmlSAX2GetEntity(%s)\n", name);
|
565
|
+
#endif
|
566
|
+
|
567
|
+
if (ctxt->inSubset == 0) {
|
568
|
+
ret = xmlGetPredefinedEntity(name);
|
569
|
+
if (ret != NULL)
|
570
|
+
return(ret);
|
571
|
+
}
|
572
|
+
if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
|
573
|
+
if (ctxt->inSubset == 2) {
|
574
|
+
ctxt->myDoc->standalone = 0;
|
575
|
+
ret = xmlGetDocEntity(ctxt->myDoc, name);
|
576
|
+
ctxt->myDoc->standalone = 1;
|
577
|
+
} else {
|
578
|
+
ret = xmlGetDocEntity(ctxt->myDoc, name);
|
579
|
+
if (ret == NULL) {
|
580
|
+
ctxt->myDoc->standalone = 0;
|
581
|
+
ret = xmlGetDocEntity(ctxt->myDoc, name);
|
582
|
+
if (ret != NULL) {
|
583
|
+
xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
|
584
|
+
"Entity(%s) document marked standalone but requires external subset\n",
|
585
|
+
name, NULL);
|
586
|
+
}
|
587
|
+
ctxt->myDoc->standalone = 1;
|
588
|
+
}
|
589
|
+
}
|
590
|
+
} else {
|
591
|
+
ret = xmlGetDocEntity(ctxt->myDoc, name);
|
592
|
+
}
|
593
|
+
return(ret);
|
594
|
+
}
|
595
|
+
|
596
|
+
/**
|
597
|
+
* xmlSAX2GetParameterEntity:
|
598
|
+
* @ctx: the user data (XML parser context)
|
599
|
+
* @name: The entity name
|
600
|
+
*
|
601
|
+
* Get a parameter entity by name
|
602
|
+
*
|
603
|
+
* Returns the xmlEntityPtr if found.
|
604
|
+
*/
|
605
|
+
xmlEntityPtr
|
606
|
+
xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
|
607
|
+
{
|
608
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
609
|
+
xmlEntityPtr ret;
|
610
|
+
|
611
|
+
if (ctx == NULL) return(NULL);
|
612
|
+
#ifdef DEBUG_SAX
|
613
|
+
xmlGenericError(xmlGenericErrorContext,
|
614
|
+
"SAX.xmlSAX2GetParameterEntity(%s)\n", name);
|
615
|
+
#endif
|
616
|
+
|
617
|
+
ret = xmlGetParameterEntity(ctxt->myDoc, name);
|
618
|
+
return(ret);
|
619
|
+
}
|
620
|
+
|
621
|
+
|
622
|
+
/**
|
623
|
+
* xmlSAX2EntityDecl:
|
624
|
+
* @ctx: the user data (XML parser context)
|
625
|
+
* @name: the entity name
|
626
|
+
* @type: the entity type
|
627
|
+
* @publicId: The public ID of the entity
|
628
|
+
* @systemId: The system ID of the entity
|
629
|
+
* @content: the entity value (without processing).
|
630
|
+
*
|
631
|
+
* An entity definition has been parsed
|
632
|
+
*/
|
633
|
+
void
|
634
|
+
xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
|
635
|
+
const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
|
636
|
+
{
|
637
|
+
xmlEntityPtr ent;
|
638
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
639
|
+
|
640
|
+
if (ctx == NULL) return;
|
641
|
+
#ifdef DEBUG_SAX
|
642
|
+
xmlGenericError(xmlGenericErrorContext,
|
643
|
+
"SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
|
644
|
+
name, type, publicId, systemId, content);
|
645
|
+
#endif
|
646
|
+
if (ctxt->inSubset == 1) {
|
647
|
+
ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
|
648
|
+
systemId, content);
|
649
|
+
if ((ent == NULL) && (ctxt->pedantic))
|
650
|
+
xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
|
651
|
+
"Entity(%s) already defined in the internal subset\n",
|
652
|
+
name);
|
653
|
+
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
654
|
+
xmlChar *URI;
|
655
|
+
const char *base = NULL;
|
656
|
+
|
657
|
+
if (ctxt->input != NULL)
|
658
|
+
base = ctxt->input->filename;
|
659
|
+
if (base == NULL)
|
660
|
+
base = ctxt->directory;
|
661
|
+
|
662
|
+
URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
663
|
+
ent->URI = URI;
|
664
|
+
}
|
665
|
+
} else if (ctxt->inSubset == 2) {
|
666
|
+
ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
|
667
|
+
systemId, content);
|
668
|
+
if ((ent == NULL) && (ctxt->pedantic) &&
|
669
|
+
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
670
|
+
ctxt->sax->warning(ctxt->userData,
|
671
|
+
"Entity(%s) already defined in the external subset\n", name);
|
672
|
+
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
673
|
+
xmlChar *URI;
|
674
|
+
const char *base = NULL;
|
675
|
+
|
676
|
+
if (ctxt->input != NULL)
|
677
|
+
base = ctxt->input->filename;
|
678
|
+
if (base == NULL)
|
679
|
+
base = ctxt->directory;
|
680
|
+
|
681
|
+
URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
682
|
+
ent->URI = URI;
|
683
|
+
}
|
684
|
+
} else {
|
685
|
+
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
|
686
|
+
"SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
|
687
|
+
name, NULL);
|
688
|
+
}
|
689
|
+
}
|
690
|
+
|
691
|
+
/**
|
692
|
+
* xmlSAX2AttributeDecl:
|
693
|
+
* @ctx: the user data (XML parser context)
|
694
|
+
* @elem: the name of the element
|
695
|
+
* @fullname: the attribute name
|
696
|
+
* @type: the attribute type
|
697
|
+
* @def: the type of default value
|
698
|
+
* @defaultValue: the attribute default value
|
699
|
+
* @tree: the tree of enumerated value set
|
700
|
+
*
|
701
|
+
* An attribute definition has been parsed
|
702
|
+
*/
|
703
|
+
void
|
704
|
+
xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
|
705
|
+
int type, int def, const xmlChar *defaultValue,
|
706
|
+
xmlEnumerationPtr tree)
|
707
|
+
{
|
708
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
709
|
+
xmlAttributePtr attr;
|
710
|
+
xmlChar *name = NULL, *prefix = NULL;
|
711
|
+
|
712
|
+
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
713
|
+
return;
|
714
|
+
|
715
|
+
#ifdef DEBUG_SAX
|
716
|
+
xmlGenericError(xmlGenericErrorContext,
|
717
|
+
"SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
|
718
|
+
elem, fullname, type, def, defaultValue);
|
719
|
+
#endif
|
720
|
+
if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
|
721
|
+
(type != XML_ATTRIBUTE_ID)) {
|
722
|
+
/*
|
723
|
+
* Raise the error but keep the validity flag
|
724
|
+
*/
|
725
|
+
int tmp = ctxt->valid;
|
726
|
+
xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
|
727
|
+
"xml:id : attribute type should be ID\n", NULL, NULL);
|
728
|
+
ctxt->valid = tmp;
|
729
|
+
}
|
730
|
+
/* TODO: optimize name/prefix allocation */
|
731
|
+
name = xmlSplitQName(ctxt, fullname, &prefix);
|
732
|
+
ctxt->vctxt.valid = 1;
|
733
|
+
if (ctxt->inSubset == 1)
|
734
|
+
attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
|
735
|
+
name, prefix, (xmlAttributeType) type,
|
736
|
+
(xmlAttributeDefault) def, defaultValue, tree);
|
737
|
+
else if (ctxt->inSubset == 2)
|
738
|
+
attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
|
739
|
+
name, prefix, (xmlAttributeType) type,
|
740
|
+
(xmlAttributeDefault) def, defaultValue, tree);
|
741
|
+
else {
|
742
|
+
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
|
743
|
+
"SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
|
744
|
+
name, NULL);
|
745
|
+
xmlFreeEnumeration(tree);
|
746
|
+
return;
|
747
|
+
}
|
748
|
+
#ifdef LIBXML_VALID_ENABLED
|
749
|
+
if (ctxt->vctxt.valid == 0)
|
750
|
+
ctxt->valid = 0;
|
751
|
+
if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
|
752
|
+
(ctxt->myDoc->intSubset != NULL))
|
753
|
+
ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
|
754
|
+
attr);
|
755
|
+
#endif /* LIBXML_VALID_ENABLED */
|
756
|
+
if (prefix != NULL)
|
757
|
+
xmlFree(prefix);
|
758
|
+
if (name != NULL)
|
759
|
+
xmlFree(name);
|
760
|
+
}
|
761
|
+
|
762
|
+
/**
|
763
|
+
* xmlSAX2ElementDecl:
|
764
|
+
* @ctx: the user data (XML parser context)
|
765
|
+
* @name: the element name
|
766
|
+
* @type: the element type
|
767
|
+
* @content: the element value tree
|
768
|
+
*
|
769
|
+
* An element definition has been parsed
|
770
|
+
*/
|
771
|
+
void
|
772
|
+
xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
|
773
|
+
xmlElementContentPtr content)
|
774
|
+
{
|
775
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
776
|
+
xmlElementPtr elem = NULL;
|
777
|
+
|
778
|
+
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
779
|
+
return;
|
780
|
+
|
781
|
+
#ifdef DEBUG_SAX
|
782
|
+
xmlGenericError(xmlGenericErrorContext,
|
783
|
+
"SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
|
784
|
+
#endif
|
785
|
+
|
786
|
+
if (ctxt->inSubset == 1)
|
787
|
+
elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
|
788
|
+
name, (xmlElementTypeVal) type, content);
|
789
|
+
else if (ctxt->inSubset == 2)
|
790
|
+
elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
|
791
|
+
name, (xmlElementTypeVal) type, content);
|
792
|
+
else {
|
793
|
+
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
|
794
|
+
"SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
|
795
|
+
name, NULL);
|
796
|
+
return;
|
797
|
+
}
|
798
|
+
#ifdef LIBXML_VALID_ENABLED
|
799
|
+
if (elem == NULL)
|
800
|
+
ctxt->valid = 0;
|
801
|
+
if (ctxt->validate && ctxt->wellFormed &&
|
802
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
803
|
+
ctxt->valid &=
|
804
|
+
xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
|
805
|
+
#endif /* LIBXML_VALID_ENABLED */
|
806
|
+
}
|
807
|
+
|
808
|
+
/**
|
809
|
+
* xmlSAX2NotationDecl:
|
810
|
+
* @ctx: the user data (XML parser context)
|
811
|
+
* @name: The name of the notation
|
812
|
+
* @publicId: The public ID of the entity
|
813
|
+
* @systemId: The system ID of the entity
|
814
|
+
*
|
815
|
+
* What to do when a notation declaration has been parsed.
|
816
|
+
*/
|
817
|
+
void
|
818
|
+
xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
|
819
|
+
const xmlChar *publicId, const xmlChar *systemId)
|
820
|
+
{
|
821
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
822
|
+
xmlNotationPtr nota = NULL;
|
823
|
+
|
824
|
+
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
825
|
+
return;
|
826
|
+
|
827
|
+
#ifdef DEBUG_SAX
|
828
|
+
xmlGenericError(xmlGenericErrorContext,
|
829
|
+
"SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
|
830
|
+
#endif
|
831
|
+
|
832
|
+
if ((publicId == NULL) && (systemId == NULL)) {
|
833
|
+
xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
|
834
|
+
"SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
|
835
|
+
name, NULL);
|
836
|
+
return;
|
837
|
+
} else if (ctxt->inSubset == 1)
|
838
|
+
nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
|
839
|
+
publicId, systemId);
|
840
|
+
else if (ctxt->inSubset == 2)
|
841
|
+
nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
|
842
|
+
publicId, systemId);
|
843
|
+
else {
|
844
|
+
xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
|
845
|
+
"SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
|
846
|
+
name, NULL);
|
847
|
+
return;
|
848
|
+
}
|
849
|
+
#ifdef LIBXML_VALID_ENABLED
|
850
|
+
if (nota == NULL) ctxt->valid = 0;
|
851
|
+
if ((ctxt->validate) && (ctxt->wellFormed) &&
|
852
|
+
(ctxt->myDoc->intSubset != NULL))
|
853
|
+
ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
|
854
|
+
nota);
|
855
|
+
#endif /* LIBXML_VALID_ENABLED */
|
856
|
+
}
|
857
|
+
|
858
|
+
/**
|
859
|
+
* xmlSAX2UnparsedEntityDecl:
|
860
|
+
* @ctx: the user data (XML parser context)
|
861
|
+
* @name: The name of the entity
|
862
|
+
* @publicId: The public ID of the entity
|
863
|
+
* @systemId: The system ID of the entity
|
864
|
+
* @notationName: the name of the notation
|
865
|
+
*
|
866
|
+
* What to do when an unparsed entity declaration is parsed
|
867
|
+
*/
|
868
|
+
void
|
869
|
+
xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
|
870
|
+
const xmlChar *publicId, const xmlChar *systemId,
|
871
|
+
const xmlChar *notationName)
|
872
|
+
{
|
873
|
+
xmlEntityPtr ent;
|
874
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
875
|
+
if (ctx == NULL) return;
|
876
|
+
#ifdef DEBUG_SAX
|
877
|
+
xmlGenericError(xmlGenericErrorContext,
|
878
|
+
"SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
|
879
|
+
name, publicId, systemId, notationName);
|
880
|
+
#endif
|
881
|
+
if (ctxt->inSubset == 1) {
|
882
|
+
ent = xmlAddDocEntity(ctxt->myDoc, name,
|
883
|
+
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
|
884
|
+
publicId, systemId, notationName);
|
885
|
+
if ((ent == NULL) && (ctxt->pedantic) &&
|
886
|
+
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
887
|
+
ctxt->sax->warning(ctxt->userData,
|
888
|
+
"Entity(%s) already defined in the internal subset\n", name);
|
889
|
+
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
890
|
+
xmlChar *URI;
|
891
|
+
const char *base = NULL;
|
892
|
+
|
893
|
+
if (ctxt->input != NULL)
|
894
|
+
base = ctxt->input->filename;
|
895
|
+
if (base == NULL)
|
896
|
+
base = ctxt->directory;
|
897
|
+
|
898
|
+
URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
899
|
+
ent->URI = URI;
|
900
|
+
}
|
901
|
+
} else if (ctxt->inSubset == 2) {
|
902
|
+
ent = xmlAddDtdEntity(ctxt->myDoc, name,
|
903
|
+
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
|
904
|
+
publicId, systemId, notationName);
|
905
|
+
if ((ent == NULL) && (ctxt->pedantic) &&
|
906
|
+
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
907
|
+
ctxt->sax->warning(ctxt->userData,
|
908
|
+
"Entity(%s) already defined in the external subset\n", name);
|
909
|
+
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
|
910
|
+
xmlChar *URI;
|
911
|
+
const char *base = NULL;
|
912
|
+
|
913
|
+
if (ctxt->input != NULL)
|
914
|
+
base = ctxt->input->filename;
|
915
|
+
if (base == NULL)
|
916
|
+
base = ctxt->directory;
|
917
|
+
|
918
|
+
URI = xmlBuildURI(systemId, (const xmlChar *) base);
|
919
|
+
ent->URI = URI;
|
920
|
+
}
|
921
|
+
} else {
|
922
|
+
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
|
923
|
+
"SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
|
924
|
+
name, NULL);
|
925
|
+
}
|
926
|
+
}
|
927
|
+
|
928
|
+
/**
|
929
|
+
* xmlSAX2SetDocumentLocator:
|
930
|
+
* @ctx: the user data (XML parser context)
|
931
|
+
* @loc: A SAX Locator
|
932
|
+
*
|
933
|
+
* Receive the document locator at startup, actually xmlDefaultSAXLocator
|
934
|
+
* Everything is available on the context, so this is useless in our case.
|
935
|
+
*/
|
936
|
+
void
|
937
|
+
xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
|
938
|
+
{
|
939
|
+
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
940
|
+
#ifdef DEBUG_SAX
|
941
|
+
xmlGenericError(xmlGenericErrorContext,
|
942
|
+
"SAX.xmlSAX2SetDocumentLocator()\n");
|
943
|
+
#endif
|
944
|
+
}
|
945
|
+
|
946
|
+
/**
|
947
|
+
* xmlSAX2StartDocument:
|
948
|
+
* @ctx: the user data (XML parser context)
|
949
|
+
*
|
950
|
+
* called when the document start being processed.
|
951
|
+
*/
|
952
|
+
void
|
953
|
+
xmlSAX2StartDocument(void *ctx)
|
954
|
+
{
|
955
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
956
|
+
xmlDocPtr doc;
|
957
|
+
|
958
|
+
if (ctx == NULL) return;
|
959
|
+
|
960
|
+
#ifdef DEBUG_SAX
|
961
|
+
xmlGenericError(xmlGenericErrorContext,
|
962
|
+
"SAX.xmlSAX2StartDocument()\n");
|
963
|
+
#endif
|
964
|
+
if (ctxt->html) {
|
965
|
+
#ifdef LIBXML_HTML_ENABLED
|
966
|
+
if (ctxt->myDoc == NULL)
|
967
|
+
ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
|
968
|
+
if (ctxt->myDoc == NULL) {
|
969
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
|
970
|
+
return;
|
971
|
+
}
|
972
|
+
ctxt->myDoc->properties = XML_DOC_HTML;
|
973
|
+
ctxt->myDoc->parseFlags = ctxt->options;
|
974
|
+
#else
|
975
|
+
xmlGenericError(xmlGenericErrorContext,
|
976
|
+
"libxml2 built without HTML support\n");
|
977
|
+
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
|
978
|
+
ctxt->instate = XML_PARSER_EOF;
|
979
|
+
ctxt->disableSAX = 1;
|
980
|
+
return;
|
981
|
+
#endif
|
982
|
+
} else {
|
983
|
+
doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
|
984
|
+
if (doc != NULL) {
|
985
|
+
doc->properties = 0;
|
986
|
+
if (ctxt->options & XML_PARSE_OLD10)
|
987
|
+
doc->properties |= XML_DOC_OLD10;
|
988
|
+
doc->parseFlags = ctxt->options;
|
989
|
+
if (ctxt->encoding != NULL)
|
990
|
+
doc->encoding = xmlStrdup(ctxt->encoding);
|
991
|
+
else
|
992
|
+
doc->encoding = NULL;
|
993
|
+
doc->standalone = ctxt->standalone;
|
994
|
+
} else {
|
995
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
|
996
|
+
return;
|
997
|
+
}
|
998
|
+
if ((ctxt->dictNames) && (doc != NULL)) {
|
999
|
+
doc->dict = ctxt->dict;
|
1000
|
+
xmlDictReference(doc->dict);
|
1001
|
+
}
|
1002
|
+
}
|
1003
|
+
if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
|
1004
|
+
(ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
|
1005
|
+
ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
|
1006
|
+
if (ctxt->myDoc->URL == NULL)
|
1007
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
/**
|
1012
|
+
* xmlSAX2EndDocument:
|
1013
|
+
* @ctx: the user data (XML parser context)
|
1014
|
+
*
|
1015
|
+
* called when the document end has been detected.
|
1016
|
+
*/
|
1017
|
+
void
|
1018
|
+
xmlSAX2EndDocument(void *ctx)
|
1019
|
+
{
|
1020
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
1021
|
+
#ifdef DEBUG_SAX
|
1022
|
+
xmlGenericError(xmlGenericErrorContext,
|
1023
|
+
"SAX.xmlSAX2EndDocument()\n");
|
1024
|
+
#endif
|
1025
|
+
if (ctx == NULL) return;
|
1026
|
+
#ifdef LIBXML_VALID_ENABLED
|
1027
|
+
if (ctxt->validate && ctxt->wellFormed &&
|
1028
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
1029
|
+
ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
|
1030
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1031
|
+
|
1032
|
+
/*
|
1033
|
+
* Grab the encoding if it was added on-the-fly
|
1034
|
+
*/
|
1035
|
+
if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
|
1036
|
+
(ctxt->myDoc->encoding == NULL)) {
|
1037
|
+
ctxt->myDoc->encoding = ctxt->encoding;
|
1038
|
+
ctxt->encoding = NULL;
|
1039
|
+
}
|
1040
|
+
if ((ctxt->inputTab != NULL) &&
|
1041
|
+
(ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
|
1042
|
+
(ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
|
1043
|
+
(ctxt->myDoc->encoding == NULL)) {
|
1044
|
+
ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
|
1045
|
+
}
|
1046
|
+
if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
|
1047
|
+
(ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
|
1048
|
+
ctxt->myDoc->charset = ctxt->charset;
|
1049
|
+
}
|
1050
|
+
}
|
1051
|
+
|
1052
|
+
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
1053
|
+
/**
|
1054
|
+
* xmlSAX2AttributeInternal:
|
1055
|
+
* @ctx: the user data (XML parser context)
|
1056
|
+
* @fullname: The attribute name, including namespace prefix
|
1057
|
+
* @value: The attribute value
|
1058
|
+
* @prefix: the prefix on the element node
|
1059
|
+
*
|
1060
|
+
* Handle an attribute that has been read by the parser.
|
1061
|
+
* The default handling is to convert the attribute into an
|
1062
|
+
* DOM subtree and past it in a new xmlAttr element added to
|
1063
|
+
* the element.
|
1064
|
+
*/
|
1065
|
+
static void
|
1066
|
+
xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
1067
|
+
const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
|
1068
|
+
{
|
1069
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
1070
|
+
xmlAttrPtr ret;
|
1071
|
+
xmlChar *name;
|
1072
|
+
xmlChar *ns;
|
1073
|
+
xmlChar *nval;
|
1074
|
+
xmlNsPtr namespace;
|
1075
|
+
|
1076
|
+
if (ctxt->html) {
|
1077
|
+
name = xmlStrdup(fullname);
|
1078
|
+
ns = NULL;
|
1079
|
+
namespace = NULL;
|
1080
|
+
} else {
|
1081
|
+
/*
|
1082
|
+
* Split the full name into a namespace prefix and the tag name
|
1083
|
+
*/
|
1084
|
+
name = xmlSplitQName(ctxt, fullname, &ns);
|
1085
|
+
if ((name != NULL) && (name[0] == 0)) {
|
1086
|
+
if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
|
1087
|
+
xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
|
1088
|
+
"invalid namespace declaration '%s'\n",
|
1089
|
+
fullname, NULL);
|
1090
|
+
} else {
|
1091
|
+
xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
|
1092
|
+
"Avoid attribute ending with ':' like '%s'\n",
|
1093
|
+
fullname, NULL);
|
1094
|
+
}
|
1095
|
+
if (ns != NULL)
|
1096
|
+
xmlFree(ns);
|
1097
|
+
ns = NULL;
|
1098
|
+
xmlFree(name);
|
1099
|
+
name = xmlStrdup(fullname);
|
1100
|
+
}
|
1101
|
+
}
|
1102
|
+
if (name == NULL) {
|
1103
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1104
|
+
if (ns != NULL)
|
1105
|
+
xmlFree(ns);
|
1106
|
+
return;
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
#ifdef LIBXML_HTML_ENABLED
|
1110
|
+
if ((ctxt->html) &&
|
1111
|
+
(value == NULL) && (htmlIsBooleanAttr(fullname))) {
|
1112
|
+
nval = xmlStrdup(fullname);
|
1113
|
+
value = (const xmlChar *) nval;
|
1114
|
+
} else
|
1115
|
+
#endif
|
1116
|
+
{
|
1117
|
+
#ifdef LIBXML_VALID_ENABLED
|
1118
|
+
/*
|
1119
|
+
* Do the last stage of the attribute normalization
|
1120
|
+
* Needed for HTML too:
|
1121
|
+
* http://www.w3.org/TR/html4/types.html#h-6.2
|
1122
|
+
*/
|
1123
|
+
ctxt->vctxt.valid = 1;
|
1124
|
+
nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
|
1125
|
+
ctxt->myDoc, ctxt->node,
|
1126
|
+
fullname, value);
|
1127
|
+
if (ctxt->vctxt.valid != 1) {
|
1128
|
+
ctxt->valid = 0;
|
1129
|
+
}
|
1130
|
+
if (nval != NULL)
|
1131
|
+
value = nval;
|
1132
|
+
#else
|
1133
|
+
nval = NULL;
|
1134
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
/*
|
1138
|
+
* Check whether it's a namespace definition
|
1139
|
+
*/
|
1140
|
+
if ((!ctxt->html) && (ns == NULL) &&
|
1141
|
+
(name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
|
1142
|
+
(name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
|
1143
|
+
xmlNsPtr nsret;
|
1144
|
+
xmlChar *val;
|
1145
|
+
|
1146
|
+
if (!ctxt->replaceEntities) {
|
1147
|
+
ctxt->depth++;
|
1148
|
+
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
1149
|
+
0,0,0);
|
1150
|
+
ctxt->depth--;
|
1151
|
+
if (val == NULL) {
|
1152
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1153
|
+
if (name != NULL)
|
1154
|
+
xmlFree(name);
|
1155
|
+
if (nval != NULL)
|
1156
|
+
xmlFree(nval);
|
1157
|
+
return;
|
1158
|
+
}
|
1159
|
+
} else {
|
1160
|
+
val = (xmlChar *) value;
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
if (val[0] != 0) {
|
1164
|
+
xmlURIPtr uri;
|
1165
|
+
|
1166
|
+
uri = xmlParseURI((const char *)val);
|
1167
|
+
if (uri == NULL) {
|
1168
|
+
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
1169
|
+
ctxt->sax->warning(ctxt->userData,
|
1170
|
+
"xmlns: %s not a valid URI\n", val);
|
1171
|
+
} else {
|
1172
|
+
if (uri->scheme == NULL) {
|
1173
|
+
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
1174
|
+
ctxt->sax->warning(ctxt->userData,
|
1175
|
+
"xmlns: URI %s is not absolute\n", val);
|
1176
|
+
}
|
1177
|
+
xmlFreeURI(uri);
|
1178
|
+
}
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
/* a default namespace definition */
|
1182
|
+
nsret = xmlNewNs(ctxt->node, val, NULL);
|
1183
|
+
|
1184
|
+
#ifdef LIBXML_VALID_ENABLED
|
1185
|
+
/*
|
1186
|
+
* Validate also for namespace decls, they are attributes from
|
1187
|
+
* an XML-1.0 perspective
|
1188
|
+
*/
|
1189
|
+
if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
|
1190
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
1191
|
+
ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
|
1192
|
+
ctxt->node, prefix, nsret, val);
|
1193
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1194
|
+
if (name != NULL)
|
1195
|
+
xmlFree(name);
|
1196
|
+
if (nval != NULL)
|
1197
|
+
xmlFree(nval);
|
1198
|
+
if (val != value)
|
1199
|
+
xmlFree(val);
|
1200
|
+
return;
|
1201
|
+
}
|
1202
|
+
if ((!ctxt->html) &&
|
1203
|
+
(ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
|
1204
|
+
(ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
|
1205
|
+
xmlNsPtr nsret;
|
1206
|
+
xmlChar *val;
|
1207
|
+
|
1208
|
+
if (!ctxt->replaceEntities) {
|
1209
|
+
ctxt->depth++;
|
1210
|
+
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
1211
|
+
0,0,0);
|
1212
|
+
ctxt->depth--;
|
1213
|
+
if (val == NULL) {
|
1214
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1215
|
+
xmlFree(ns);
|
1216
|
+
if (name != NULL)
|
1217
|
+
xmlFree(name);
|
1218
|
+
if (nval != NULL)
|
1219
|
+
xmlFree(nval);
|
1220
|
+
return;
|
1221
|
+
}
|
1222
|
+
} else {
|
1223
|
+
val = (xmlChar *) value;
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
if (val[0] == 0) {
|
1227
|
+
xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
|
1228
|
+
"Empty namespace name for prefix %s\n", name, NULL);
|
1229
|
+
}
|
1230
|
+
if ((ctxt->pedantic != 0) && (val[0] != 0)) {
|
1231
|
+
xmlURIPtr uri;
|
1232
|
+
|
1233
|
+
uri = xmlParseURI((const char *)val);
|
1234
|
+
if (uri == NULL) {
|
1235
|
+
xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
|
1236
|
+
"xmlns:%s: %s not a valid URI\n", name, value);
|
1237
|
+
} else {
|
1238
|
+
if (uri->scheme == NULL) {
|
1239
|
+
xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
|
1240
|
+
"xmlns:%s: URI %s is not absolute\n", name, value);
|
1241
|
+
}
|
1242
|
+
xmlFreeURI(uri);
|
1243
|
+
}
|
1244
|
+
}
|
1245
|
+
|
1246
|
+
/* a standard namespace definition */
|
1247
|
+
nsret = xmlNewNs(ctxt->node, val, name);
|
1248
|
+
xmlFree(ns);
|
1249
|
+
#ifdef LIBXML_VALID_ENABLED
|
1250
|
+
/*
|
1251
|
+
* Validate also for namespace decls, they are attributes from
|
1252
|
+
* an XML-1.0 perspective
|
1253
|
+
*/
|
1254
|
+
if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
|
1255
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
1256
|
+
ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
|
1257
|
+
ctxt->node, prefix, nsret, value);
|
1258
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1259
|
+
if (name != NULL)
|
1260
|
+
xmlFree(name);
|
1261
|
+
if (nval != NULL)
|
1262
|
+
xmlFree(nval);
|
1263
|
+
if (val != value)
|
1264
|
+
xmlFree(val);
|
1265
|
+
return;
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
if (ns != NULL) {
|
1269
|
+
namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
|
1270
|
+
|
1271
|
+
if (namespace == NULL) {
|
1272
|
+
xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
|
1273
|
+
"Namespace prefix %s of attribute %s is not defined\n",
|
1274
|
+
ns, name);
|
1275
|
+
} else {
|
1276
|
+
xmlAttrPtr prop;
|
1277
|
+
|
1278
|
+
prop = ctxt->node->properties;
|
1279
|
+
while (prop != NULL) {
|
1280
|
+
if (prop->ns != NULL) {
|
1281
|
+
if ((xmlStrEqual(name, prop->name)) &&
|
1282
|
+
((namespace == prop->ns) ||
|
1283
|
+
(xmlStrEqual(namespace->href, prop->ns->href)))) {
|
1284
|
+
xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
|
1285
|
+
"Attribute %s in %s redefined\n",
|
1286
|
+
name, namespace->href);
|
1287
|
+
ctxt->wellFormed = 0;
|
1288
|
+
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
|
1289
|
+
if (name != NULL)
|
1290
|
+
xmlFree(name);
|
1291
|
+
goto error;
|
1292
|
+
}
|
1293
|
+
}
|
1294
|
+
prop = prop->next;
|
1295
|
+
}
|
1296
|
+
}
|
1297
|
+
} else {
|
1298
|
+
namespace = NULL;
|
1299
|
+
}
|
1300
|
+
|
1301
|
+
/* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
|
1302
|
+
ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
|
1303
|
+
|
1304
|
+
if (ret != NULL) {
|
1305
|
+
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
|
1306
|
+
xmlNodePtr tmp;
|
1307
|
+
|
1308
|
+
ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
|
1309
|
+
tmp = ret->children;
|
1310
|
+
while (tmp != NULL) {
|
1311
|
+
tmp->parent = (xmlNodePtr) ret;
|
1312
|
+
if (tmp->next == NULL)
|
1313
|
+
ret->last = tmp;
|
1314
|
+
tmp = tmp->next;
|
1315
|
+
}
|
1316
|
+
} else if (value != NULL) {
|
1317
|
+
ret->children = xmlNewDocText(ctxt->myDoc, value);
|
1318
|
+
ret->last = ret->children;
|
1319
|
+
if (ret->children != NULL)
|
1320
|
+
ret->children->parent = (xmlNodePtr) ret;
|
1321
|
+
}
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
#ifdef LIBXML_VALID_ENABLED
|
1325
|
+
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
1326
|
+
ctxt->myDoc && ctxt->myDoc->intSubset) {
|
1327
|
+
|
1328
|
+
/*
|
1329
|
+
* If we don't substitute entities, the validation should be
|
1330
|
+
* done on a value with replaced entities anyway.
|
1331
|
+
*/
|
1332
|
+
if (!ctxt->replaceEntities) {
|
1333
|
+
xmlChar *val;
|
1334
|
+
|
1335
|
+
ctxt->depth++;
|
1336
|
+
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
1337
|
+
0,0,0);
|
1338
|
+
ctxt->depth--;
|
1339
|
+
|
1340
|
+
if (val == NULL)
|
1341
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
1342
|
+
ctxt->myDoc, ctxt->node, ret, value);
|
1343
|
+
else {
|
1344
|
+
xmlChar *nvalnorm;
|
1345
|
+
|
1346
|
+
/*
|
1347
|
+
* Do the last stage of the attribute normalization
|
1348
|
+
* It need to be done twice ... it's an extra burden related
|
1349
|
+
* to the ability to keep xmlSAX2References in attributes
|
1350
|
+
*/
|
1351
|
+
nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
|
1352
|
+
ctxt->node, fullname, val);
|
1353
|
+
if (nvalnorm != NULL) {
|
1354
|
+
xmlFree(val);
|
1355
|
+
val = nvalnorm;
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
1359
|
+
ctxt->myDoc, ctxt->node, ret, val);
|
1360
|
+
xmlFree(val);
|
1361
|
+
}
|
1362
|
+
} else {
|
1363
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
|
1364
|
+
ctxt->node, ret, value);
|
1365
|
+
}
|
1366
|
+
} else
|
1367
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1368
|
+
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
|
1369
|
+
(((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
|
1370
|
+
((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
|
1371
|
+
/*
|
1372
|
+
* when validating, the ID registration is done at the attribute
|
1373
|
+
* validation level. Otherwise we have to do specific handling here.
|
1374
|
+
*/
|
1375
|
+
if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
|
1376
|
+
/*
|
1377
|
+
* Add the xml:id value
|
1378
|
+
*
|
1379
|
+
* Open issue: normalization of the value.
|
1380
|
+
*/
|
1381
|
+
if (xmlValidateNCName(value, 1) != 0) {
|
1382
|
+
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
|
1383
|
+
"xml:id : attribute value %s is not an NCName\n",
|
1384
|
+
(const char *) value, NULL);
|
1385
|
+
}
|
1386
|
+
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
1387
|
+
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
|
1388
|
+
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
1389
|
+
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
|
1390
|
+
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
1391
|
+
}
|
1392
|
+
|
1393
|
+
error:
|
1394
|
+
if (nval != NULL)
|
1395
|
+
xmlFree(nval);
|
1396
|
+
if (ns != NULL)
|
1397
|
+
xmlFree(ns);
|
1398
|
+
}
|
1399
|
+
|
1400
|
+
/*
|
1401
|
+
* xmlCheckDefaultedAttributes:
|
1402
|
+
*
|
1403
|
+
* Check defaulted attributes from the DTD
|
1404
|
+
*/
|
1405
|
+
static void
|
1406
|
+
xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
|
1407
|
+
const xmlChar *prefix, const xmlChar **atts) {
|
1408
|
+
xmlElementPtr elemDecl;
|
1409
|
+
const xmlChar *att;
|
1410
|
+
int internal = 1;
|
1411
|
+
int i;
|
1412
|
+
|
1413
|
+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
|
1414
|
+
if (elemDecl == NULL) {
|
1415
|
+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
|
1416
|
+
internal = 0;
|
1417
|
+
}
|
1418
|
+
|
1419
|
+
process_external_subset:
|
1420
|
+
|
1421
|
+
if (elemDecl != NULL) {
|
1422
|
+
xmlAttributePtr attr = elemDecl->attributes;
|
1423
|
+
/*
|
1424
|
+
* Check against defaulted attributes from the external subset
|
1425
|
+
* if the document is stamped as standalone
|
1426
|
+
*/
|
1427
|
+
if ((ctxt->myDoc->standalone == 1) &&
|
1428
|
+
(ctxt->myDoc->extSubset != NULL) &&
|
1429
|
+
(ctxt->validate)) {
|
1430
|
+
while (attr != NULL) {
|
1431
|
+
if ((attr->defaultValue != NULL) &&
|
1432
|
+
(xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
|
1433
|
+
attr->elem, attr->name,
|
1434
|
+
attr->prefix) == attr) &&
|
1435
|
+
(xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
|
1436
|
+
attr->elem, attr->name,
|
1437
|
+
attr->prefix) == NULL)) {
|
1438
|
+
xmlChar *fulln;
|
1439
|
+
|
1440
|
+
if (attr->prefix != NULL) {
|
1441
|
+
fulln = xmlStrdup(attr->prefix);
|
1442
|
+
fulln = xmlStrcat(fulln, BAD_CAST ":");
|
1443
|
+
fulln = xmlStrcat(fulln, attr->name);
|
1444
|
+
} else {
|
1445
|
+
fulln = xmlStrdup(attr->name);
|
1446
|
+
}
|
1447
|
+
if (fulln == NULL) {
|
1448
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1449
|
+
break;
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
/*
|
1453
|
+
* Check that the attribute is not declared in the
|
1454
|
+
* serialization
|
1455
|
+
*/
|
1456
|
+
att = NULL;
|
1457
|
+
if (atts != NULL) {
|
1458
|
+
i = 0;
|
1459
|
+
att = atts[i];
|
1460
|
+
while (att != NULL) {
|
1461
|
+
if (xmlStrEqual(att, fulln))
|
1462
|
+
break;
|
1463
|
+
i += 2;
|
1464
|
+
att = atts[i];
|
1465
|
+
}
|
1466
|
+
}
|
1467
|
+
if (att == NULL) {
|
1468
|
+
xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
|
1469
|
+
"standalone: attribute %s on %s defaulted from external subset\n",
|
1470
|
+
(const char *)fulln,
|
1471
|
+
(const char *)attr->elem);
|
1472
|
+
}
|
1473
|
+
xmlFree(fulln);
|
1474
|
+
}
|
1475
|
+
attr = attr->nexth;
|
1476
|
+
}
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
/*
|
1480
|
+
* Actually insert defaulted values when needed
|
1481
|
+
*/
|
1482
|
+
attr = elemDecl->attributes;
|
1483
|
+
while (attr != NULL) {
|
1484
|
+
/*
|
1485
|
+
* Make sure that attributes redefinition occurring in the
|
1486
|
+
* internal subset are not overridden by definitions in the
|
1487
|
+
* external subset.
|
1488
|
+
*/
|
1489
|
+
if (attr->defaultValue != NULL) {
|
1490
|
+
/*
|
1491
|
+
* the element should be instantiated in the tree if:
|
1492
|
+
* - this is a namespace prefix
|
1493
|
+
* - the user required for completion in the tree
|
1494
|
+
* like XSLT
|
1495
|
+
* - there isn't already an attribute definition
|
1496
|
+
* in the internal subset overriding it.
|
1497
|
+
*/
|
1498
|
+
if (((attr->prefix != NULL) &&
|
1499
|
+
(xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
|
1500
|
+
((attr->prefix == NULL) &&
|
1501
|
+
(xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
|
1502
|
+
(ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
|
1503
|
+
xmlAttributePtr tst;
|
1504
|
+
|
1505
|
+
tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
|
1506
|
+
attr->elem, attr->name,
|
1507
|
+
attr->prefix);
|
1508
|
+
if ((tst == attr) || (tst == NULL)) {
|
1509
|
+
xmlChar fn[50];
|
1510
|
+
xmlChar *fulln;
|
1511
|
+
|
1512
|
+
fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
|
1513
|
+
if (fulln == NULL) {
|
1514
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1515
|
+
return;
|
1516
|
+
}
|
1517
|
+
|
1518
|
+
/*
|
1519
|
+
* Check that the attribute is not declared in the
|
1520
|
+
* serialization
|
1521
|
+
*/
|
1522
|
+
att = NULL;
|
1523
|
+
if (atts != NULL) {
|
1524
|
+
i = 0;
|
1525
|
+
att = atts[i];
|
1526
|
+
while (att != NULL) {
|
1527
|
+
if (xmlStrEqual(att, fulln))
|
1528
|
+
break;
|
1529
|
+
i += 2;
|
1530
|
+
att = atts[i];
|
1531
|
+
}
|
1532
|
+
}
|
1533
|
+
if (att == NULL) {
|
1534
|
+
xmlSAX2AttributeInternal(ctxt, fulln,
|
1535
|
+
attr->defaultValue, prefix);
|
1536
|
+
}
|
1537
|
+
if ((fulln != fn) && (fulln != attr->name))
|
1538
|
+
xmlFree(fulln);
|
1539
|
+
}
|
1540
|
+
}
|
1541
|
+
}
|
1542
|
+
attr = attr->nexth;
|
1543
|
+
}
|
1544
|
+
if (internal == 1) {
|
1545
|
+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
|
1546
|
+
name, prefix);
|
1547
|
+
internal = 0;
|
1548
|
+
goto process_external_subset;
|
1549
|
+
}
|
1550
|
+
}
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
/**
|
1554
|
+
* xmlSAX2StartElement:
|
1555
|
+
* @ctx: the user data (XML parser context)
|
1556
|
+
* @fullname: The element name, including namespace prefix
|
1557
|
+
* @atts: An array of name/value attributes pairs, NULL terminated
|
1558
|
+
*
|
1559
|
+
* called when an opening tag has been processed.
|
1560
|
+
*/
|
1561
|
+
void
|
1562
|
+
xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
|
1563
|
+
{
|
1564
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
1565
|
+
xmlNodePtr ret;
|
1566
|
+
xmlNodePtr parent;
|
1567
|
+
xmlNsPtr ns;
|
1568
|
+
xmlChar *name;
|
1569
|
+
xmlChar *prefix;
|
1570
|
+
const xmlChar *att;
|
1571
|
+
const xmlChar *value;
|
1572
|
+
int i;
|
1573
|
+
|
1574
|
+
if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
|
1575
|
+
parent = ctxt->node;
|
1576
|
+
#ifdef DEBUG_SAX
|
1577
|
+
xmlGenericError(xmlGenericErrorContext,
|
1578
|
+
"SAX.xmlSAX2StartElement(%s)\n", fullname);
|
1579
|
+
#endif
|
1580
|
+
|
1581
|
+
/*
|
1582
|
+
* First check on validity:
|
1583
|
+
*/
|
1584
|
+
if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
1585
|
+
((ctxt->myDoc->intSubset == NULL) ||
|
1586
|
+
((ctxt->myDoc->intSubset->notations == NULL) &&
|
1587
|
+
(ctxt->myDoc->intSubset->elements == NULL) &&
|
1588
|
+
(ctxt->myDoc->intSubset->attributes == NULL) &&
|
1589
|
+
(ctxt->myDoc->intSubset->entities == NULL)))) {
|
1590
|
+
xmlErrValid(ctxt, XML_ERR_NO_DTD,
|
1591
|
+
"Validation failed: no DTD found !", NULL, NULL);
|
1592
|
+
ctxt->validate = 0;
|
1593
|
+
}
|
1594
|
+
|
1595
|
+
|
1596
|
+
/*
|
1597
|
+
* Split the full name into a namespace prefix and the tag name
|
1598
|
+
*/
|
1599
|
+
name = xmlSplitQName(ctxt, fullname, &prefix);
|
1600
|
+
|
1601
|
+
|
1602
|
+
/*
|
1603
|
+
* Note : the namespace resolution is deferred until the end of the
|
1604
|
+
* attributes parsing, since local namespace can be defined as
|
1605
|
+
* an attribute at this level.
|
1606
|
+
*/
|
1607
|
+
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
|
1608
|
+
if (ret == NULL) {
|
1609
|
+
if (prefix != NULL)
|
1610
|
+
xmlFree(prefix);
|
1611
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
|
1612
|
+
return;
|
1613
|
+
}
|
1614
|
+
if (ctxt->myDoc->children == NULL) {
|
1615
|
+
#ifdef DEBUG_SAX_TREE
|
1616
|
+
xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
|
1617
|
+
#endif
|
1618
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
|
1619
|
+
} else if (parent == NULL) {
|
1620
|
+
parent = ctxt->myDoc->children;
|
1621
|
+
}
|
1622
|
+
ctxt->nodemem = -1;
|
1623
|
+
if (ctxt->linenumbers) {
|
1624
|
+
if (ctxt->input != NULL) {
|
1625
|
+
if (ctxt->input->line < 65535)
|
1626
|
+
ret->line = (short) ctxt->input->line;
|
1627
|
+
else
|
1628
|
+
ret->line = 65535;
|
1629
|
+
}
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
/*
|
1633
|
+
* We are parsing a new node.
|
1634
|
+
*/
|
1635
|
+
#ifdef DEBUG_SAX_TREE
|
1636
|
+
xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
|
1637
|
+
#endif
|
1638
|
+
if (nodePush(ctxt, ret) < 0) {
|
1639
|
+
xmlUnlinkNode(ret);
|
1640
|
+
xmlFreeNode(ret);
|
1641
|
+
if (prefix != NULL)
|
1642
|
+
xmlFree(prefix);
|
1643
|
+
return;
|
1644
|
+
}
|
1645
|
+
|
1646
|
+
/*
|
1647
|
+
* Link the child element
|
1648
|
+
*/
|
1649
|
+
if (parent != NULL) {
|
1650
|
+
if (parent->type == XML_ELEMENT_NODE) {
|
1651
|
+
#ifdef DEBUG_SAX_TREE
|
1652
|
+
xmlGenericError(xmlGenericErrorContext,
|
1653
|
+
"adding child %s to %s\n", name, parent->name);
|
1654
|
+
#endif
|
1655
|
+
xmlAddChild(parent, ret);
|
1656
|
+
} else {
|
1657
|
+
#ifdef DEBUG_SAX_TREE
|
1658
|
+
xmlGenericError(xmlGenericErrorContext,
|
1659
|
+
"adding sibling %s to ", name);
|
1660
|
+
xmlDebugDumpOneNode(stderr, parent, 0);
|
1661
|
+
#endif
|
1662
|
+
xmlAddSibling(parent, ret);
|
1663
|
+
}
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
if (!ctxt->html) {
|
1667
|
+
/*
|
1668
|
+
* Insert all the defaulted attributes from the DTD especially
|
1669
|
+
* namespaces
|
1670
|
+
*/
|
1671
|
+
if ((ctxt->myDoc->intSubset != NULL) ||
|
1672
|
+
(ctxt->myDoc->extSubset != NULL)) {
|
1673
|
+
xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
|
1674
|
+
}
|
1675
|
+
|
1676
|
+
/*
|
1677
|
+
* process all the attributes whose name start with "xmlns"
|
1678
|
+
*/
|
1679
|
+
if (atts != NULL) {
|
1680
|
+
i = 0;
|
1681
|
+
att = atts[i++];
|
1682
|
+
value = atts[i++];
|
1683
|
+
while ((att != NULL) && (value != NULL)) {
|
1684
|
+
if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
|
1685
|
+
(att[3] == 'n') && (att[4] == 's'))
|
1686
|
+
xmlSAX2AttributeInternal(ctxt, att, value, prefix);
|
1687
|
+
|
1688
|
+
att = atts[i++];
|
1689
|
+
value = atts[i++];
|
1690
|
+
}
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
/*
|
1694
|
+
* Search the namespace, note that since the attributes have been
|
1695
|
+
* processed, the local namespaces are available.
|
1696
|
+
*/
|
1697
|
+
ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
|
1698
|
+
if ((ns == NULL) && (parent != NULL))
|
1699
|
+
ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
|
1700
|
+
if ((prefix != NULL) && (ns == NULL)) {
|
1701
|
+
ns = xmlNewNs(ret, NULL, prefix);
|
1702
|
+
xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
|
1703
|
+
"Namespace prefix %s is not defined\n",
|
1704
|
+
prefix, NULL);
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
/*
|
1708
|
+
* set the namespace node, making sure that if the default namespace
|
1709
|
+
* is unbound on a parent we simply keep it NULL
|
1710
|
+
*/
|
1711
|
+
if ((ns != NULL) && (ns->href != NULL) &&
|
1712
|
+
((ns->href[0] != 0) || (ns->prefix != NULL)))
|
1713
|
+
xmlSetNs(ret, ns);
|
1714
|
+
}
|
1715
|
+
|
1716
|
+
/*
|
1717
|
+
* process all the other attributes
|
1718
|
+
*/
|
1719
|
+
if (atts != NULL) {
|
1720
|
+
i = 0;
|
1721
|
+
att = atts[i++];
|
1722
|
+
value = atts[i++];
|
1723
|
+
if (ctxt->html) {
|
1724
|
+
while (att != NULL) {
|
1725
|
+
xmlSAX2AttributeInternal(ctxt, att, value, NULL);
|
1726
|
+
att = atts[i++];
|
1727
|
+
value = atts[i++];
|
1728
|
+
}
|
1729
|
+
} else {
|
1730
|
+
while ((att != NULL) && (value != NULL)) {
|
1731
|
+
if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
|
1732
|
+
(att[3] != 'n') || (att[4] != 's'))
|
1733
|
+
xmlSAX2AttributeInternal(ctxt, att, value, NULL);
|
1734
|
+
|
1735
|
+
/*
|
1736
|
+
* Next ones
|
1737
|
+
*/
|
1738
|
+
att = atts[i++];
|
1739
|
+
value = atts[i++];
|
1740
|
+
}
|
1741
|
+
}
|
1742
|
+
}
|
1743
|
+
|
1744
|
+
#ifdef LIBXML_VALID_ENABLED
|
1745
|
+
/*
|
1746
|
+
* If it's the Document root, finish the DTD validation and
|
1747
|
+
* check the document root element for validity
|
1748
|
+
*/
|
1749
|
+
if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
|
1750
|
+
int chk;
|
1751
|
+
|
1752
|
+
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
|
1753
|
+
if (chk <= 0)
|
1754
|
+
ctxt->valid = 0;
|
1755
|
+
if (chk < 0)
|
1756
|
+
ctxt->wellFormed = 0;
|
1757
|
+
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
|
1758
|
+
ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
|
1759
|
+
}
|
1760
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1761
|
+
|
1762
|
+
if (prefix != NULL)
|
1763
|
+
xmlFree(prefix);
|
1764
|
+
|
1765
|
+
}
|
1766
|
+
|
1767
|
+
/**
|
1768
|
+
* xmlSAX2EndElement:
|
1769
|
+
* @ctx: the user data (XML parser context)
|
1770
|
+
* @name: The element name
|
1771
|
+
*
|
1772
|
+
* called when the end of an element has been detected.
|
1773
|
+
*/
|
1774
|
+
void
|
1775
|
+
xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
1776
|
+
{
|
1777
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
1778
|
+
xmlNodePtr cur;
|
1779
|
+
|
1780
|
+
if (ctx == NULL) return;
|
1781
|
+
cur = ctxt->node;
|
1782
|
+
#ifdef DEBUG_SAX
|
1783
|
+
if (name == NULL)
|
1784
|
+
xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
|
1785
|
+
else
|
1786
|
+
xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
|
1787
|
+
#endif
|
1788
|
+
|
1789
|
+
/* Capture end position and add node */
|
1790
|
+
if (cur != NULL && ctxt->record_info) {
|
1791
|
+
ctxt->nodeInfo->end_pos = ctxt->input->cur - ctxt->input->base;
|
1792
|
+
ctxt->nodeInfo->end_line = ctxt->input->line;
|
1793
|
+
ctxt->nodeInfo->node = cur;
|
1794
|
+
xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
|
1795
|
+
}
|
1796
|
+
ctxt->nodemem = -1;
|
1797
|
+
|
1798
|
+
#ifdef LIBXML_VALID_ENABLED
|
1799
|
+
if (ctxt->validate && ctxt->wellFormed &&
|
1800
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
1801
|
+
ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
|
1802
|
+
cur);
|
1803
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1804
|
+
|
1805
|
+
|
1806
|
+
/*
|
1807
|
+
* end of parsing of this node.
|
1808
|
+
*/
|
1809
|
+
#ifdef DEBUG_SAX_TREE
|
1810
|
+
xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
|
1811
|
+
#endif
|
1812
|
+
nodePop(ctxt);
|
1813
|
+
}
|
1814
|
+
#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
|
1815
|
+
|
1816
|
+
/*
|
1817
|
+
* xmlSAX2TextNode:
|
1818
|
+
* @ctxt: the parser context
|
1819
|
+
* @str: the input string
|
1820
|
+
* @len: the string length
|
1821
|
+
*
|
1822
|
+
* Callback for a text node
|
1823
|
+
*
|
1824
|
+
* Returns the newly allocated string or NULL if not needed or error
|
1825
|
+
*/
|
1826
|
+
static xmlNodePtr
|
1827
|
+
xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
|
1828
|
+
xmlNodePtr ret;
|
1829
|
+
const xmlChar *intern = NULL;
|
1830
|
+
|
1831
|
+
/*
|
1832
|
+
* Allocate
|
1833
|
+
*/
|
1834
|
+
if (ctxt->freeElems != NULL) {
|
1835
|
+
ret = ctxt->freeElems;
|
1836
|
+
ctxt->freeElems = ret->next;
|
1837
|
+
ctxt->freeElemsNr--;
|
1838
|
+
} else {
|
1839
|
+
ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
|
1840
|
+
}
|
1841
|
+
if (ret == NULL) {
|
1842
|
+
xmlErrMemory(ctxt, "xmlSAX2Characters");
|
1843
|
+
return(NULL);
|
1844
|
+
}
|
1845
|
+
memset(ret, 0, sizeof(xmlNode));
|
1846
|
+
/*
|
1847
|
+
* intern the formatting blanks found between tags, or the
|
1848
|
+
* very short strings
|
1849
|
+
*/
|
1850
|
+
if (ctxt->dictNames) {
|
1851
|
+
xmlChar cur = str[len];
|
1852
|
+
|
1853
|
+
if ((len < (int) (2 * sizeof(void *))) &&
|
1854
|
+
(ctxt->options & XML_PARSE_COMPACT)) {
|
1855
|
+
/* store the string in the node overriding properties and nsDef */
|
1856
|
+
xmlChar *tmp = (xmlChar *) &(ret->properties);
|
1857
|
+
memcpy(tmp, str, len);
|
1858
|
+
tmp[len] = 0;
|
1859
|
+
intern = tmp;
|
1860
|
+
} else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
|
1861
|
+
((cur == '<') && (str[len + 1] != '!')))) {
|
1862
|
+
intern = xmlDictLookup(ctxt->dict, str, len);
|
1863
|
+
} else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
|
1864
|
+
(str[len + 1] != '!')) {
|
1865
|
+
int i;
|
1866
|
+
|
1867
|
+
for (i = 1;i < len;i++) {
|
1868
|
+
if (!IS_BLANK_CH(str[i])) goto skip;
|
1869
|
+
}
|
1870
|
+
intern = xmlDictLookup(ctxt->dict, str, len);
|
1871
|
+
}
|
1872
|
+
}
|
1873
|
+
skip:
|
1874
|
+
ret->type = XML_TEXT_NODE;
|
1875
|
+
|
1876
|
+
ret->name = xmlStringText;
|
1877
|
+
if (intern == NULL) {
|
1878
|
+
ret->content = xmlStrndup(str, len);
|
1879
|
+
if (ret->content == NULL) {
|
1880
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
|
1881
|
+
xmlFree(ret);
|
1882
|
+
return(NULL);
|
1883
|
+
}
|
1884
|
+
} else
|
1885
|
+
ret->content = (xmlChar *) intern;
|
1886
|
+
|
1887
|
+
if (ctxt->linenumbers) {
|
1888
|
+
if (ctxt->input != NULL) {
|
1889
|
+
if (ctxt->input->line < 65535)
|
1890
|
+
ret->line = (short) ctxt->input->line;
|
1891
|
+
else {
|
1892
|
+
ret->line = 65535;
|
1893
|
+
if (ctxt->options & XML_PARSE_BIG_LINES)
|
1894
|
+
ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
|
1895
|
+
}
|
1896
|
+
}
|
1897
|
+
}
|
1898
|
+
|
1899
|
+
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
|
1900
|
+
xmlRegisterNodeDefaultValue(ret);
|
1901
|
+
return(ret);
|
1902
|
+
}
|
1903
|
+
|
1904
|
+
#ifdef LIBXML_VALID_ENABLED
|
1905
|
+
/*
|
1906
|
+
* xmlSAX2DecodeAttrEntities:
|
1907
|
+
* @ctxt: the parser context
|
1908
|
+
* @str: the input string
|
1909
|
+
* @len: the string length
|
1910
|
+
*
|
1911
|
+
* Remove the entities from an attribute value
|
1912
|
+
*
|
1913
|
+
* Returns the newly allocated string or NULL if not needed or error
|
1914
|
+
*/
|
1915
|
+
static xmlChar *
|
1916
|
+
xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
|
1917
|
+
const xmlChar *end) {
|
1918
|
+
const xmlChar *in;
|
1919
|
+
xmlChar *ret;
|
1920
|
+
|
1921
|
+
in = str;
|
1922
|
+
while (in < end)
|
1923
|
+
if (*in++ == '&')
|
1924
|
+
goto decode;
|
1925
|
+
return(NULL);
|
1926
|
+
decode:
|
1927
|
+
ctxt->depth++;
|
1928
|
+
ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
|
1929
|
+
XML_SUBSTITUTE_REF, 0,0,0);
|
1930
|
+
ctxt->depth--;
|
1931
|
+
return(ret);
|
1932
|
+
}
|
1933
|
+
#endif /* LIBXML_VALID_ENABLED */
|
1934
|
+
|
1935
|
+
/**
|
1936
|
+
* xmlSAX2AttributeNs:
|
1937
|
+
* @ctx: the user data (XML parser context)
|
1938
|
+
* @localname: the local name of the attribute
|
1939
|
+
* @prefix: the attribute namespace prefix if available
|
1940
|
+
* @URI: the attribute namespace name if available
|
1941
|
+
* @value: Start of the attribute value
|
1942
|
+
* @valueend: end of the attribute value
|
1943
|
+
*
|
1944
|
+
* Handle an attribute that has been read by the parser.
|
1945
|
+
* The default handling is to convert the attribute into an
|
1946
|
+
* DOM subtree and past it in a new xmlAttr element added to
|
1947
|
+
* the element.
|
1948
|
+
*/
|
1949
|
+
static void
|
1950
|
+
xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
1951
|
+
const xmlChar * localname,
|
1952
|
+
const xmlChar * prefix,
|
1953
|
+
const xmlChar * value,
|
1954
|
+
const xmlChar * valueend)
|
1955
|
+
{
|
1956
|
+
xmlAttrPtr ret;
|
1957
|
+
xmlNsPtr namespace = NULL;
|
1958
|
+
xmlChar *dup = NULL;
|
1959
|
+
|
1960
|
+
/*
|
1961
|
+
* Note: if prefix == NULL, the attribute is not in the default namespace
|
1962
|
+
*/
|
1963
|
+
if (prefix != NULL)
|
1964
|
+
namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
|
1965
|
+
|
1966
|
+
/*
|
1967
|
+
* allocate the node
|
1968
|
+
*/
|
1969
|
+
if (ctxt->freeAttrs != NULL) {
|
1970
|
+
ret = ctxt->freeAttrs;
|
1971
|
+
ctxt->freeAttrs = ret->next;
|
1972
|
+
ctxt->freeAttrsNr--;
|
1973
|
+
memset(ret, 0, sizeof(xmlAttr));
|
1974
|
+
ret->type = XML_ATTRIBUTE_NODE;
|
1975
|
+
|
1976
|
+
ret->parent = ctxt->node;
|
1977
|
+
ret->doc = ctxt->myDoc;
|
1978
|
+
ret->ns = namespace;
|
1979
|
+
|
1980
|
+
if (ctxt->dictNames)
|
1981
|
+
ret->name = localname;
|
1982
|
+
else
|
1983
|
+
ret->name = xmlStrdup(localname);
|
1984
|
+
|
1985
|
+
/* link at the end to preserve order, TODO speed up with a last */
|
1986
|
+
if (ctxt->node->properties == NULL) {
|
1987
|
+
ctxt->node->properties = ret;
|
1988
|
+
} else {
|
1989
|
+
xmlAttrPtr prev = ctxt->node->properties;
|
1990
|
+
|
1991
|
+
while (prev->next != NULL) prev = prev->next;
|
1992
|
+
prev->next = ret;
|
1993
|
+
ret->prev = prev;
|
1994
|
+
}
|
1995
|
+
|
1996
|
+
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
|
1997
|
+
xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
|
1998
|
+
} else {
|
1999
|
+
if (ctxt->dictNames)
|
2000
|
+
ret = xmlNewNsPropEatName(ctxt->node, namespace,
|
2001
|
+
(xmlChar *) localname, NULL);
|
2002
|
+
else
|
2003
|
+
ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
|
2004
|
+
if (ret == NULL) {
|
2005
|
+
xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
|
2006
|
+
return;
|
2007
|
+
}
|
2008
|
+
}
|
2009
|
+
|
2010
|
+
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
|
2011
|
+
xmlNodePtr tmp;
|
2012
|
+
|
2013
|
+
/*
|
2014
|
+
* We know that if there is an entity reference, then
|
2015
|
+
* the string has been dup'ed and terminates with 0
|
2016
|
+
* otherwise with ' or "
|
2017
|
+
*/
|
2018
|
+
if (*valueend != 0) {
|
2019
|
+
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
|
2020
|
+
ret->children = tmp;
|
2021
|
+
ret->last = tmp;
|
2022
|
+
if (tmp != NULL) {
|
2023
|
+
tmp->doc = ret->doc;
|
2024
|
+
tmp->parent = (xmlNodePtr) ret;
|
2025
|
+
}
|
2026
|
+
} else {
|
2027
|
+
ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
|
2028
|
+
valueend - value);
|
2029
|
+
tmp = ret->children;
|
2030
|
+
while (tmp != NULL) {
|
2031
|
+
tmp->doc = ret->doc;
|
2032
|
+
tmp->parent = (xmlNodePtr) ret;
|
2033
|
+
if (tmp->next == NULL)
|
2034
|
+
ret->last = tmp;
|
2035
|
+
tmp = tmp->next;
|
2036
|
+
}
|
2037
|
+
}
|
2038
|
+
} else if (value != NULL) {
|
2039
|
+
xmlNodePtr tmp;
|
2040
|
+
|
2041
|
+
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
|
2042
|
+
ret->children = tmp;
|
2043
|
+
ret->last = tmp;
|
2044
|
+
if (tmp != NULL) {
|
2045
|
+
tmp->doc = ret->doc;
|
2046
|
+
tmp->parent = (xmlNodePtr) ret;
|
2047
|
+
}
|
2048
|
+
}
|
2049
|
+
|
2050
|
+
#ifdef LIBXML_VALID_ENABLED
|
2051
|
+
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
2052
|
+
ctxt->myDoc && ctxt->myDoc->intSubset) {
|
2053
|
+
/*
|
2054
|
+
* If we don't substitute entities, the validation should be
|
2055
|
+
* done on a value with replaced entities anyway.
|
2056
|
+
*/
|
2057
|
+
if (!ctxt->replaceEntities) {
|
2058
|
+
dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
|
2059
|
+
if (dup == NULL) {
|
2060
|
+
if (*valueend == 0) {
|
2061
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
2062
|
+
ctxt->myDoc, ctxt->node, ret, value);
|
2063
|
+
} else {
|
2064
|
+
/*
|
2065
|
+
* That should already be normalized.
|
2066
|
+
* cheaper to finally allocate here than duplicate
|
2067
|
+
* entry points in the full validation code
|
2068
|
+
*/
|
2069
|
+
dup = xmlStrndup(value, valueend - value);
|
2070
|
+
|
2071
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
2072
|
+
ctxt->myDoc, ctxt->node, ret, dup);
|
2073
|
+
}
|
2074
|
+
} else {
|
2075
|
+
/*
|
2076
|
+
* dup now contains a string of the flattened attribute
|
2077
|
+
* content with entities substituted. Check if we need to
|
2078
|
+
* apply an extra layer of normalization.
|
2079
|
+
* It need to be done twice ... it's an extra burden related
|
2080
|
+
* to the ability to keep references in attributes
|
2081
|
+
*/
|
2082
|
+
if (ctxt->attsSpecial != NULL) {
|
2083
|
+
xmlChar *nvalnorm;
|
2084
|
+
xmlChar fn[50];
|
2085
|
+
xmlChar *fullname;
|
2086
|
+
|
2087
|
+
fullname = xmlBuildQName(localname, prefix, fn, 50);
|
2088
|
+
if (fullname != NULL) {
|
2089
|
+
ctxt->vctxt.valid = 1;
|
2090
|
+
nvalnorm = xmlValidCtxtNormalizeAttributeValue(
|
2091
|
+
&ctxt->vctxt, ctxt->myDoc,
|
2092
|
+
ctxt->node, fullname, dup);
|
2093
|
+
if (ctxt->vctxt.valid != 1)
|
2094
|
+
ctxt->valid = 0;
|
2095
|
+
|
2096
|
+
if ((fullname != fn) && (fullname != localname))
|
2097
|
+
xmlFree(fullname);
|
2098
|
+
if (nvalnorm != NULL) {
|
2099
|
+
xmlFree(dup);
|
2100
|
+
dup = nvalnorm;
|
2101
|
+
}
|
2102
|
+
}
|
2103
|
+
}
|
2104
|
+
|
2105
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
2106
|
+
ctxt->myDoc, ctxt->node, ret, dup);
|
2107
|
+
}
|
2108
|
+
} else {
|
2109
|
+
/*
|
2110
|
+
* if entities already have been substituted, then
|
2111
|
+
* the attribute as passed is already normalized
|
2112
|
+
*/
|
2113
|
+
dup = xmlStrndup(value, valueend - value);
|
2114
|
+
|
2115
|
+
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
|
2116
|
+
ctxt->myDoc, ctxt->node, ret, dup);
|
2117
|
+
}
|
2118
|
+
} else
|
2119
|
+
#endif /* LIBXML_VALID_ENABLED */
|
2120
|
+
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
|
2121
|
+
(((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
|
2122
|
+
((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
|
2123
|
+
/*
|
2124
|
+
* when validating, the ID registration is done at the attribute
|
2125
|
+
* validation level. Otherwise we have to do specific handling here.
|
2126
|
+
*/
|
2127
|
+
if ((prefix == ctxt->str_xml) &&
|
2128
|
+
(localname[0] == 'i') && (localname[1] == 'd') &&
|
2129
|
+
(localname[2] == 0)) {
|
2130
|
+
/*
|
2131
|
+
* Add the xml:id value
|
2132
|
+
*
|
2133
|
+
* Open issue: normalization of the value.
|
2134
|
+
*/
|
2135
|
+
if (dup == NULL)
|
2136
|
+
dup = xmlStrndup(value, valueend - value);
|
2137
|
+
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
2138
|
+
#ifdef LIBXML_VALID_ENABLED
|
2139
|
+
if (xmlValidateNCName(dup, 1) != 0) {
|
2140
|
+
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
|
2141
|
+
"xml:id : attribute value %s is not an NCName\n",
|
2142
|
+
(const char *) dup, NULL);
|
2143
|
+
}
|
2144
|
+
#endif
|
2145
|
+
#endif
|
2146
|
+
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
2147
|
+
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
|
2148
|
+
/* might be worth duplicate entry points and not copy */
|
2149
|
+
if (dup == NULL)
|
2150
|
+
dup = xmlStrndup(value, valueend - value);
|
2151
|
+
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
2152
|
+
} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
|
2153
|
+
if (dup == NULL)
|
2154
|
+
dup = xmlStrndup(value, valueend - value);
|
2155
|
+
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
2156
|
+
}
|
2157
|
+
}
|
2158
|
+
if (dup != NULL)
|
2159
|
+
xmlFree(dup);
|
2160
|
+
}
|
2161
|
+
|
2162
|
+
/**
|
2163
|
+
* xmlSAX2StartElementNs:
|
2164
|
+
* @ctx: the user data (XML parser context)
|
2165
|
+
* @localname: the local name of the element
|
2166
|
+
* @prefix: the element namespace prefix if available
|
2167
|
+
* @URI: the element namespace name if available
|
2168
|
+
* @nb_namespaces: number of namespace definitions on that node
|
2169
|
+
* @namespaces: pointer to the array of prefix/URI pairs namespace definitions
|
2170
|
+
* @nb_attributes: the number of attributes on that node
|
2171
|
+
* @nb_defaulted: the number of defaulted attributes.
|
2172
|
+
* @attributes: pointer to the array of (localname/prefix/URI/value/end)
|
2173
|
+
* attribute values.
|
2174
|
+
*
|
2175
|
+
* SAX2 callback when an element start has been detected by the parser.
|
2176
|
+
* It provides the namespace information for the element, as well as
|
2177
|
+
* the new namespace declarations on the element.
|
2178
|
+
*/
|
2179
|
+
void
|
2180
|
+
xmlSAX2StartElementNs(void *ctx,
|
2181
|
+
const xmlChar *localname,
|
2182
|
+
const xmlChar *prefix,
|
2183
|
+
const xmlChar *URI,
|
2184
|
+
int nb_namespaces,
|
2185
|
+
const xmlChar **namespaces,
|
2186
|
+
int nb_attributes,
|
2187
|
+
int nb_defaulted,
|
2188
|
+
const xmlChar **attributes)
|
2189
|
+
{
|
2190
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
2191
|
+
xmlNodePtr ret;
|
2192
|
+
xmlNodePtr parent;
|
2193
|
+
xmlNsPtr last = NULL, ns;
|
2194
|
+
const xmlChar *uri, *pref;
|
2195
|
+
xmlChar *lname = NULL;
|
2196
|
+
int i, j;
|
2197
|
+
|
2198
|
+
if (ctx == NULL) return;
|
2199
|
+
parent = ctxt->node;
|
2200
|
+
/*
|
2201
|
+
* First check on validity:
|
2202
|
+
*/
|
2203
|
+
if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
|
2204
|
+
((ctxt->myDoc->intSubset == NULL) ||
|
2205
|
+
((ctxt->myDoc->intSubset->notations == NULL) &&
|
2206
|
+
(ctxt->myDoc->intSubset->elements == NULL) &&
|
2207
|
+
(ctxt->myDoc->intSubset->attributes == NULL) &&
|
2208
|
+
(ctxt->myDoc->intSubset->entities == NULL)))) {
|
2209
|
+
xmlErrValid(ctxt, XML_DTD_NO_DTD,
|
2210
|
+
"Validation failed: no DTD found !", NULL, NULL);
|
2211
|
+
ctxt->validate = 0;
|
2212
|
+
}
|
2213
|
+
|
2214
|
+
/*
|
2215
|
+
* Take care of the rare case of an undefined namespace prefix
|
2216
|
+
*/
|
2217
|
+
if ((prefix != NULL) && (URI == NULL)) {
|
2218
|
+
if (ctxt->dictNames) {
|
2219
|
+
const xmlChar *fullname;
|
2220
|
+
|
2221
|
+
fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
|
2222
|
+
if (fullname != NULL)
|
2223
|
+
localname = fullname;
|
2224
|
+
} else {
|
2225
|
+
lname = xmlBuildQName(localname, prefix, NULL, 0);
|
2226
|
+
}
|
2227
|
+
}
|
2228
|
+
/*
|
2229
|
+
* allocate the node
|
2230
|
+
*/
|
2231
|
+
if (ctxt->freeElems != NULL) {
|
2232
|
+
ret = ctxt->freeElems;
|
2233
|
+
ctxt->freeElems = ret->next;
|
2234
|
+
ctxt->freeElemsNr--;
|
2235
|
+
memset(ret, 0, sizeof(xmlNode));
|
2236
|
+
ret->doc = ctxt->myDoc;
|
2237
|
+
ret->type = XML_ELEMENT_NODE;
|
2238
|
+
|
2239
|
+
if (ctxt->dictNames)
|
2240
|
+
ret->name = localname;
|
2241
|
+
else {
|
2242
|
+
if (lname == NULL)
|
2243
|
+
ret->name = xmlStrdup(localname);
|
2244
|
+
else
|
2245
|
+
ret->name = lname;
|
2246
|
+
if (ret->name == NULL) {
|
2247
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
2248
|
+
return;
|
2249
|
+
}
|
2250
|
+
}
|
2251
|
+
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
|
2252
|
+
xmlRegisterNodeDefaultValue(ret);
|
2253
|
+
} else {
|
2254
|
+
if (ctxt->dictNames)
|
2255
|
+
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
|
2256
|
+
(xmlChar *) localname, NULL);
|
2257
|
+
else if (lname == NULL)
|
2258
|
+
ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
|
2259
|
+
else
|
2260
|
+
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
|
2261
|
+
(xmlChar *) lname, NULL);
|
2262
|
+
if (ret == NULL) {
|
2263
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
2264
|
+
return;
|
2265
|
+
}
|
2266
|
+
}
|
2267
|
+
if (ctxt->linenumbers) {
|
2268
|
+
if (ctxt->input != NULL) {
|
2269
|
+
if (ctxt->input->line < 65535)
|
2270
|
+
ret->line = (short) ctxt->input->line;
|
2271
|
+
else
|
2272
|
+
ret->line = 65535;
|
2273
|
+
}
|
2274
|
+
}
|
2275
|
+
|
2276
|
+
if (parent == NULL) {
|
2277
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
|
2278
|
+
}
|
2279
|
+
/*
|
2280
|
+
* Build the namespace list
|
2281
|
+
*/
|
2282
|
+
for (i = 0,j = 0;j < nb_namespaces;j++) {
|
2283
|
+
pref = namespaces[i++];
|
2284
|
+
uri = namespaces[i++];
|
2285
|
+
ns = xmlNewNs(NULL, uri, pref);
|
2286
|
+
if (ns != NULL) {
|
2287
|
+
if (last == NULL) {
|
2288
|
+
ret->nsDef = last = ns;
|
2289
|
+
} else {
|
2290
|
+
last->next = ns;
|
2291
|
+
last = ns;
|
2292
|
+
}
|
2293
|
+
if ((URI != NULL) && (prefix == pref))
|
2294
|
+
ret->ns = ns;
|
2295
|
+
} else {
|
2296
|
+
/*
|
2297
|
+
* any out of memory error would already have been raised
|
2298
|
+
* but we can't be guaranteed it's the actual error due to the
|
2299
|
+
* API, best is to skip in this case
|
2300
|
+
*/
|
2301
|
+
continue;
|
2302
|
+
}
|
2303
|
+
#ifdef LIBXML_VALID_ENABLED
|
2304
|
+
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
2305
|
+
ctxt->myDoc && ctxt->myDoc->intSubset) {
|
2306
|
+
ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
|
2307
|
+
ret, prefix, ns, uri);
|
2308
|
+
}
|
2309
|
+
#endif /* LIBXML_VALID_ENABLED */
|
2310
|
+
}
|
2311
|
+
ctxt->nodemem = -1;
|
2312
|
+
|
2313
|
+
/*
|
2314
|
+
* We are parsing a new node.
|
2315
|
+
*/
|
2316
|
+
if (nodePush(ctxt, ret) < 0) {
|
2317
|
+
xmlUnlinkNode(ret);
|
2318
|
+
xmlFreeNode(ret);
|
2319
|
+
return;
|
2320
|
+
}
|
2321
|
+
|
2322
|
+
/*
|
2323
|
+
* Link the child element
|
2324
|
+
*/
|
2325
|
+
if (parent != NULL) {
|
2326
|
+
if (parent->type == XML_ELEMENT_NODE) {
|
2327
|
+
xmlAddChild(parent, ret);
|
2328
|
+
} else {
|
2329
|
+
xmlAddSibling(parent, ret);
|
2330
|
+
}
|
2331
|
+
}
|
2332
|
+
|
2333
|
+
/*
|
2334
|
+
* Insert the defaulted attributes from the DTD only if requested:
|
2335
|
+
*/
|
2336
|
+
if ((nb_defaulted != 0) &&
|
2337
|
+
((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
|
2338
|
+
nb_attributes -= nb_defaulted;
|
2339
|
+
|
2340
|
+
/*
|
2341
|
+
* Search the namespace if it wasn't already found
|
2342
|
+
* Note that, if prefix is NULL, this searches for the default Ns
|
2343
|
+
*/
|
2344
|
+
if ((URI != NULL) && (ret->ns == NULL)) {
|
2345
|
+
ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
|
2346
|
+
if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
|
2347
|
+
ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
|
2348
|
+
}
|
2349
|
+
if (ret->ns == NULL) {
|
2350
|
+
ns = xmlNewNs(ret, NULL, prefix);
|
2351
|
+
if (ns == NULL) {
|
2352
|
+
|
2353
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
|
2354
|
+
return;
|
2355
|
+
}
|
2356
|
+
if (prefix != NULL)
|
2357
|
+
xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
|
2358
|
+
"Namespace prefix %s was not found\n",
|
2359
|
+
prefix, NULL);
|
2360
|
+
else
|
2361
|
+
xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
|
2362
|
+
"Namespace default prefix was not found\n",
|
2363
|
+
NULL, NULL);
|
2364
|
+
}
|
2365
|
+
}
|
2366
|
+
|
2367
|
+
/*
|
2368
|
+
* process all the other attributes
|
2369
|
+
*/
|
2370
|
+
if (nb_attributes > 0) {
|
2371
|
+
for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
|
2372
|
+
/*
|
2373
|
+
* Handle the rare case of an undefined attribute prefix
|
2374
|
+
*/
|
2375
|
+
if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
|
2376
|
+
if (ctxt->dictNames) {
|
2377
|
+
const xmlChar *fullname;
|
2378
|
+
|
2379
|
+
fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
|
2380
|
+
attributes[j]);
|
2381
|
+
if (fullname != NULL) {
|
2382
|
+
xmlSAX2AttributeNs(ctxt, fullname, NULL,
|
2383
|
+
attributes[j+3], attributes[j+4]);
|
2384
|
+
continue;
|
2385
|
+
}
|
2386
|
+
} else {
|
2387
|
+
lname = xmlBuildQName(attributes[j], attributes[j+1],
|
2388
|
+
NULL, 0);
|
2389
|
+
if (lname != NULL) {
|
2390
|
+
xmlSAX2AttributeNs(ctxt, lname, NULL,
|
2391
|
+
attributes[j+3], attributes[j+4]);
|
2392
|
+
xmlFree(lname);
|
2393
|
+
continue;
|
2394
|
+
}
|
2395
|
+
}
|
2396
|
+
}
|
2397
|
+
xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
|
2398
|
+
attributes[j+3], attributes[j+4]);
|
2399
|
+
}
|
2400
|
+
}
|
2401
|
+
|
2402
|
+
#ifdef LIBXML_VALID_ENABLED
|
2403
|
+
/*
|
2404
|
+
* If it's the Document root, finish the DTD validation and
|
2405
|
+
* check the document root element for validity
|
2406
|
+
*/
|
2407
|
+
if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
|
2408
|
+
int chk;
|
2409
|
+
|
2410
|
+
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
|
2411
|
+
if (chk <= 0)
|
2412
|
+
ctxt->valid = 0;
|
2413
|
+
if (chk < 0)
|
2414
|
+
ctxt->wellFormed = 0;
|
2415
|
+
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
|
2416
|
+
ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
|
2417
|
+
}
|
2418
|
+
#endif /* LIBXML_VALID_ENABLED */
|
2419
|
+
}
|
2420
|
+
|
2421
|
+
/**
|
2422
|
+
* xmlSAX2EndElementNs:
|
2423
|
+
* @ctx: the user data (XML parser context)
|
2424
|
+
* @localname: the local name of the element
|
2425
|
+
* @prefix: the element namespace prefix if available
|
2426
|
+
* @URI: the element namespace name if available
|
2427
|
+
*
|
2428
|
+
* SAX2 callback when an element end has been detected by the parser.
|
2429
|
+
* It provides the namespace information for the element.
|
2430
|
+
*/
|
2431
|
+
void
|
2432
|
+
xmlSAX2EndElementNs(void *ctx,
|
2433
|
+
const xmlChar * localname ATTRIBUTE_UNUSED,
|
2434
|
+
const xmlChar * prefix ATTRIBUTE_UNUSED,
|
2435
|
+
const xmlChar * URI ATTRIBUTE_UNUSED)
|
2436
|
+
{
|
2437
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
2438
|
+
xmlParserNodeInfo node_info;
|
2439
|
+
xmlNodePtr cur;
|
2440
|
+
|
2441
|
+
if (ctx == NULL) return;
|
2442
|
+
cur = ctxt->node;
|
2443
|
+
/* Capture end position and add node */
|
2444
|
+
if ((ctxt->record_info) && (cur != NULL)) {
|
2445
|
+
node_info.end_pos = ctxt->input->cur - ctxt->input->base;
|
2446
|
+
node_info.end_line = ctxt->input->line;
|
2447
|
+
node_info.node = cur;
|
2448
|
+
xmlParserAddNodeInfo(ctxt, &node_info);
|
2449
|
+
}
|
2450
|
+
ctxt->nodemem = -1;
|
2451
|
+
|
2452
|
+
#ifdef LIBXML_VALID_ENABLED
|
2453
|
+
if (ctxt->validate && ctxt->wellFormed &&
|
2454
|
+
ctxt->myDoc && ctxt->myDoc->intSubset)
|
2455
|
+
ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
|
2456
|
+
#endif /* LIBXML_VALID_ENABLED */
|
2457
|
+
|
2458
|
+
/*
|
2459
|
+
* end of parsing of this node.
|
2460
|
+
*/
|
2461
|
+
nodePop(ctxt);
|
2462
|
+
}
|
2463
|
+
|
2464
|
+
/**
|
2465
|
+
* xmlSAX2Reference:
|
2466
|
+
* @ctx: the user data (XML parser context)
|
2467
|
+
* @name: The entity name
|
2468
|
+
*
|
2469
|
+
* called when an entity xmlSAX2Reference is detected.
|
2470
|
+
*/
|
2471
|
+
void
|
2472
|
+
xmlSAX2Reference(void *ctx, const xmlChar *name)
|
2473
|
+
{
|
2474
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
2475
|
+
xmlNodePtr ret;
|
2476
|
+
|
2477
|
+
if (ctx == NULL) return;
|
2478
|
+
#ifdef DEBUG_SAX
|
2479
|
+
xmlGenericError(xmlGenericErrorContext,
|
2480
|
+
"SAX.xmlSAX2Reference(%s)\n", name);
|
2481
|
+
#endif
|
2482
|
+
if (name[0] == '#')
|
2483
|
+
ret = xmlNewCharRef(ctxt->myDoc, name);
|
2484
|
+
else
|
2485
|
+
ret = xmlNewReference(ctxt->myDoc, name);
|
2486
|
+
#ifdef DEBUG_SAX_TREE
|
2487
|
+
xmlGenericError(xmlGenericErrorContext,
|
2488
|
+
"add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
|
2489
|
+
#endif
|
2490
|
+
if (xmlAddChild(ctxt->node, ret) == NULL) {
|
2491
|
+
xmlFreeNode(ret);
|
2492
|
+
}
|
2493
|
+
}
|
2494
|
+
|
2495
|
+
/**
|
2496
|
+
* xmlSAX2Text:
|
2497
|
+
* @ctx: the user data (XML parser context)
|
2498
|
+
* @ch: a xmlChar string
|
2499
|
+
* @len: the number of xmlChar
|
2500
|
+
* @type: text or cdata
|
2501
|
+
*
|
2502
|
+
* Append characters.
|
2503
|
+
*/
|
2504
|
+
static void
|
2505
|
+
xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
|
2506
|
+
xmlElementType type)
|
2507
|
+
{
|
2508
|
+
xmlNodePtr lastChild;
|
2509
|
+
|
2510
|
+
if (ctxt == NULL) return;
|
2511
|
+
#ifdef DEBUG_SAX
|
2512
|
+
xmlGenericError(xmlGenericErrorContext,
|
2513
|
+
"SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
|
2514
|
+
#endif
|
2515
|
+
/*
|
2516
|
+
* Handle the data if any. If there is no child
|
2517
|
+
* add it as content, otherwise if the last child is text,
|
2518
|
+
* concatenate it, else create a new node of type text.
|
2519
|
+
*/
|
2520
|
+
|
2521
|
+
if (ctxt->node == NULL) {
|
2522
|
+
#ifdef DEBUG_SAX_TREE
|
2523
|
+
xmlGenericError(xmlGenericErrorContext,
|
2524
|
+
"add chars: ctxt->node == NULL !\n");
|
2525
|
+
#endif
|
2526
|
+
return;
|
2527
|
+
}
|
2528
|
+
lastChild = ctxt->node->last;
|
2529
|
+
#ifdef DEBUG_SAX_TREE
|
2530
|
+
xmlGenericError(xmlGenericErrorContext,
|
2531
|
+
"add chars to %s \n", ctxt->node->name);
|
2532
|
+
#endif
|
2533
|
+
|
2534
|
+
/*
|
2535
|
+
* Here we needed an accelerator mechanism in case of very large
|
2536
|
+
* elements. Use an attribute in the structure !!!
|
2537
|
+
*/
|
2538
|
+
if (lastChild == NULL) {
|
2539
|
+
if (type == XML_TEXT_NODE)
|
2540
|
+
lastChild = xmlSAX2TextNode(ctxt, ch, len);
|
2541
|
+
else
|
2542
|
+
lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
|
2543
|
+
if (lastChild != NULL) {
|
2544
|
+
ctxt->node->children = lastChild;
|
2545
|
+
ctxt->node->last = lastChild;
|
2546
|
+
lastChild->parent = ctxt->node;
|
2547
|
+
lastChild->doc = ctxt->node->doc;
|
2548
|
+
ctxt->nodelen = len;
|
2549
|
+
ctxt->nodemem = len + 1;
|
2550
|
+
} else {
|
2551
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
|
2552
|
+
return;
|
2553
|
+
}
|
2554
|
+
} else {
|
2555
|
+
int coalesceText = (lastChild != NULL) &&
|
2556
|
+
(lastChild->type == type) &&
|
2557
|
+
((type != XML_TEXT_NODE) ||
|
2558
|
+
(lastChild->name == xmlStringText));
|
2559
|
+
if ((coalesceText) && (ctxt->nodemem != 0)) {
|
2560
|
+
/*
|
2561
|
+
* The whole point of maintaining nodelen and nodemem,
|
2562
|
+
* xmlTextConcat is too costly, i.e. compute length,
|
2563
|
+
* reallocate a new buffer, move data, append ch. Here
|
2564
|
+
* We try to minimize realloc() uses and avoid copying
|
2565
|
+
* and recomputing length over and over.
|
2566
|
+
*/
|
2567
|
+
if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
|
2568
|
+
lastChild->content = xmlStrdup(lastChild->content);
|
2569
|
+
lastChild->properties = NULL;
|
2570
|
+
} else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
|
2571
|
+
(xmlDictOwns(ctxt->dict, lastChild->content))) {
|
2572
|
+
lastChild->content = xmlStrdup(lastChild->content);
|
2573
|
+
}
|
2574
|
+
if (lastChild->content == NULL) {
|
2575
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
|
2576
|
+
return;
|
2577
|
+
}
|
2578
|
+
if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
|
2579
|
+
((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
2580
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
|
2581
|
+
return;
|
2582
|
+
}
|
2583
|
+
if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
|
2584
|
+
(size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
|
2585
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
|
2586
|
+
return;
|
2587
|
+
}
|
2588
|
+
if (ctxt->nodelen + len >= ctxt->nodemem) {
|
2589
|
+
xmlChar *newbuf;
|
2590
|
+
size_t size;
|
2591
|
+
|
2592
|
+
size = ctxt->nodemem + len;
|
2593
|
+
size *= 2;
|
2594
|
+
newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
|
2595
|
+
if (newbuf == NULL) {
|
2596
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
|
2597
|
+
return;
|
2598
|
+
}
|
2599
|
+
ctxt->nodemem = size;
|
2600
|
+
lastChild->content = newbuf;
|
2601
|
+
}
|
2602
|
+
memcpy(&lastChild->content[ctxt->nodelen], ch, len);
|
2603
|
+
ctxt->nodelen += len;
|
2604
|
+
lastChild->content[ctxt->nodelen] = 0;
|
2605
|
+
} else if (coalesceText) {
|
2606
|
+
if (xmlTextConcat(lastChild, ch, len)) {
|
2607
|
+
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
|
2608
|
+
}
|
2609
|
+
if (ctxt->node->children != NULL) {
|
2610
|
+
ctxt->nodelen = xmlStrlen(lastChild->content);
|
2611
|
+
ctxt->nodemem = ctxt->nodelen + 1;
|
2612
|
+
}
|
2613
|
+
} else {
|
2614
|
+
/* Mixed content, first time */
|
2615
|
+
if (type == XML_TEXT_NODE)
|
2616
|
+
lastChild = xmlSAX2TextNode(ctxt, ch, len);
|
2617
|
+
else
|
2618
|
+
lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
|
2619
|
+
if (lastChild != NULL) {
|
2620
|
+
xmlAddChild(ctxt->node, lastChild);
|
2621
|
+
if (ctxt->node->children != NULL) {
|
2622
|
+
ctxt->nodelen = len;
|
2623
|
+
ctxt->nodemem = len + 1;
|
2624
|
+
}
|
2625
|
+
}
|
2626
|
+
}
|
2627
|
+
}
|
2628
|
+
}
|
2629
|
+
|
2630
|
+
/**
|
2631
|
+
* xmlSAX2Characters:
|
2632
|
+
* @ctx: the user data (XML parser context)
|
2633
|
+
* @ch: a xmlChar string
|
2634
|
+
* @len: the number of xmlChar
|
2635
|
+
*
|
2636
|
+
* receiving some chars from the parser.
|
2637
|
+
*/
|
2638
|
+
void
|
2639
|
+
xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
|
2640
|
+
{
|
2641
|
+
xmlSAX2Text((xmlParserCtxtPtr) ctx, ch, len, XML_TEXT_NODE);
|
2642
|
+
}
|
2643
|
+
|
2644
|
+
/**
|
2645
|
+
* xmlSAX2IgnorableWhitespace:
|
2646
|
+
* @ctx: the user data (XML parser context)
|
2647
|
+
* @ch: a xmlChar string
|
2648
|
+
* @len: the number of xmlChar
|
2649
|
+
*
|
2650
|
+
* receiving some ignorable whitespaces from the parser.
|
2651
|
+
* UNUSED: by default the DOM building will use xmlSAX2Characters
|
2652
|
+
*/
|
2653
|
+
void
|
2654
|
+
xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
|
2655
|
+
{
|
2656
|
+
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
2657
|
+
#ifdef DEBUG_SAX
|
2658
|
+
xmlGenericError(xmlGenericErrorContext,
|
2659
|
+
"SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
|
2660
|
+
#endif
|
2661
|
+
}
|
2662
|
+
|
2663
|
+
/**
|
2664
|
+
* xmlSAX2ProcessingInstruction:
|
2665
|
+
* @ctx: the user data (XML parser context)
|
2666
|
+
* @target: the target name
|
2667
|
+
* @data: the PI data's
|
2668
|
+
*
|
2669
|
+
* A processing instruction has been parsed.
|
2670
|
+
*/
|
2671
|
+
void
|
2672
|
+
xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
|
2673
|
+
const xmlChar *data)
|
2674
|
+
{
|
2675
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
2676
|
+
xmlNodePtr ret;
|
2677
|
+
xmlNodePtr parent;
|
2678
|
+
|
2679
|
+
if (ctx == NULL) return;
|
2680
|
+
parent = ctxt->node;
|
2681
|
+
#ifdef DEBUG_SAX
|
2682
|
+
xmlGenericError(xmlGenericErrorContext,
|
2683
|
+
"SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
|
2684
|
+
#endif
|
2685
|
+
|
2686
|
+
ret = xmlNewDocPI(ctxt->myDoc, target, data);
|
2687
|
+
if (ret == NULL) return;
|
2688
|
+
|
2689
|
+
if (ctxt->linenumbers) {
|
2690
|
+
if (ctxt->input != NULL) {
|
2691
|
+
if (ctxt->input->line < 65535)
|
2692
|
+
ret->line = (short) ctxt->input->line;
|
2693
|
+
else
|
2694
|
+
ret->line = 65535;
|
2695
|
+
}
|
2696
|
+
}
|
2697
|
+
if (ctxt->inSubset == 1) {
|
2698
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
|
2699
|
+
return;
|
2700
|
+
} else if (ctxt->inSubset == 2) {
|
2701
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
|
2702
|
+
return;
|
2703
|
+
}
|
2704
|
+
if (parent == NULL) {
|
2705
|
+
#ifdef DEBUG_SAX_TREE
|
2706
|
+
xmlGenericError(xmlGenericErrorContext,
|
2707
|
+
"Setting PI %s as root\n", target);
|
2708
|
+
#endif
|
2709
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
|
2710
|
+
return;
|
2711
|
+
}
|
2712
|
+
if (parent->type == XML_ELEMENT_NODE) {
|
2713
|
+
#ifdef DEBUG_SAX_TREE
|
2714
|
+
xmlGenericError(xmlGenericErrorContext,
|
2715
|
+
"adding PI %s child to %s\n", target, parent->name);
|
2716
|
+
#endif
|
2717
|
+
xmlAddChild(parent, ret);
|
2718
|
+
} else {
|
2719
|
+
#ifdef DEBUG_SAX_TREE
|
2720
|
+
xmlGenericError(xmlGenericErrorContext,
|
2721
|
+
"adding PI %s sibling to ", target);
|
2722
|
+
xmlDebugDumpOneNode(stderr, parent, 0);
|
2723
|
+
#endif
|
2724
|
+
xmlAddSibling(parent, ret);
|
2725
|
+
}
|
2726
|
+
}
|
2727
|
+
|
2728
|
+
/**
|
2729
|
+
* xmlSAX2Comment:
|
2730
|
+
* @ctx: the user data (XML parser context)
|
2731
|
+
* @value: the xmlSAX2Comment content
|
2732
|
+
*
|
2733
|
+
* A xmlSAX2Comment has been parsed.
|
2734
|
+
*/
|
2735
|
+
void
|
2736
|
+
xmlSAX2Comment(void *ctx, const xmlChar *value)
|
2737
|
+
{
|
2738
|
+
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
2739
|
+
xmlNodePtr ret;
|
2740
|
+
xmlNodePtr parent;
|
2741
|
+
|
2742
|
+
if (ctx == NULL) return;
|
2743
|
+
parent = ctxt->node;
|
2744
|
+
#ifdef DEBUG_SAX
|
2745
|
+
xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
|
2746
|
+
#endif
|
2747
|
+
ret = xmlNewDocComment(ctxt->myDoc, value);
|
2748
|
+
if (ret == NULL) return;
|
2749
|
+
if (ctxt->linenumbers) {
|
2750
|
+
if (ctxt->input != NULL) {
|
2751
|
+
if (ctxt->input->line < 65535)
|
2752
|
+
ret->line = (short) ctxt->input->line;
|
2753
|
+
else
|
2754
|
+
ret->line = 65535;
|
2755
|
+
}
|
2756
|
+
}
|
2757
|
+
|
2758
|
+
if (ctxt->inSubset == 1) {
|
2759
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
|
2760
|
+
return;
|
2761
|
+
} else if (ctxt->inSubset == 2) {
|
2762
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
|
2763
|
+
return;
|
2764
|
+
}
|
2765
|
+
if (parent == NULL) {
|
2766
|
+
#ifdef DEBUG_SAX_TREE
|
2767
|
+
xmlGenericError(xmlGenericErrorContext,
|
2768
|
+
"Setting xmlSAX2Comment as root\n");
|
2769
|
+
#endif
|
2770
|
+
xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
|
2771
|
+
return;
|
2772
|
+
}
|
2773
|
+
if (parent->type == XML_ELEMENT_NODE) {
|
2774
|
+
#ifdef DEBUG_SAX_TREE
|
2775
|
+
xmlGenericError(xmlGenericErrorContext,
|
2776
|
+
"adding xmlSAX2Comment child to %s\n", parent->name);
|
2777
|
+
#endif
|
2778
|
+
xmlAddChild(parent, ret);
|
2779
|
+
} else {
|
2780
|
+
#ifdef DEBUG_SAX_TREE
|
2781
|
+
xmlGenericError(xmlGenericErrorContext,
|
2782
|
+
"adding xmlSAX2Comment sibling to ");
|
2783
|
+
xmlDebugDumpOneNode(stderr, parent, 0);
|
2784
|
+
#endif
|
2785
|
+
xmlAddSibling(parent, ret);
|
2786
|
+
}
|
2787
|
+
}
|
2788
|
+
|
2789
|
+
/**
|
2790
|
+
* xmlSAX2CDataBlock:
|
2791
|
+
* @ctx: the user data (XML parser context)
|
2792
|
+
* @value: The pcdata content
|
2793
|
+
* @len: the block length
|
2794
|
+
*
|
2795
|
+
* called when a pcdata block has been parsed
|
2796
|
+
*/
|
2797
|
+
void
|
2798
|
+
xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
|
2799
|
+
{
|
2800
|
+
xmlSAX2Text((xmlParserCtxtPtr) ctx, value, len, XML_CDATA_SECTION_NODE);
|
2801
|
+
}
|
2802
|
+
|
2803
|
+
static int xmlSAX2DefaultVersionValue = 2;
|
2804
|
+
|
2805
|
+
#ifdef LIBXML_SAX1_ENABLED
|
2806
|
+
/**
|
2807
|
+
* xmlSAXDefaultVersion:
|
2808
|
+
* @version: the version, 1 or 2
|
2809
|
+
*
|
2810
|
+
* Set the default version of SAX used globally by the library.
|
2811
|
+
* By default, during initialization the default is set to 2.
|
2812
|
+
* Note that it is generally a better coding style to use
|
2813
|
+
* xmlSAXVersion() to set up the version explicitly for a given
|
2814
|
+
* parsing context.
|
2815
|
+
*
|
2816
|
+
* Returns the previous value in case of success and -1 in case of error.
|
2817
|
+
*/
|
2818
|
+
int
|
2819
|
+
xmlSAXDefaultVersion(int version)
|
2820
|
+
{
|
2821
|
+
int ret = xmlSAX2DefaultVersionValue;
|
2822
|
+
|
2823
|
+
if ((version != 1) && (version != 2))
|
2824
|
+
return(-1);
|
2825
|
+
xmlSAX2DefaultVersionValue = version;
|
2826
|
+
return(ret);
|
2827
|
+
}
|
2828
|
+
#endif /* LIBXML_SAX1_ENABLED */
|
2829
|
+
|
2830
|
+
/**
|
2831
|
+
* xmlSAXVersion:
|
2832
|
+
* @hdlr: the SAX handler
|
2833
|
+
* @version: the version, 1 or 2
|
2834
|
+
*
|
2835
|
+
* Initialize the default XML SAX handler according to the version
|
2836
|
+
*
|
2837
|
+
* Returns 0 in case of success and -1 in case of error.
|
2838
|
+
*/
|
2839
|
+
int
|
2840
|
+
xmlSAXVersion(xmlSAXHandler *hdlr, int version)
|
2841
|
+
{
|
2842
|
+
if (hdlr == NULL) return(-1);
|
2843
|
+
if (version == 2) {
|
2844
|
+
hdlr->startElement = NULL;
|
2845
|
+
hdlr->endElement = NULL;
|
2846
|
+
hdlr->startElementNs = xmlSAX2StartElementNs;
|
2847
|
+
hdlr->endElementNs = xmlSAX2EndElementNs;
|
2848
|
+
hdlr->serror = NULL;
|
2849
|
+
hdlr->initialized = XML_SAX2_MAGIC;
|
2850
|
+
#ifdef LIBXML_SAX1_ENABLED
|
2851
|
+
} else if (version == 1) {
|
2852
|
+
hdlr->startElement = xmlSAX2StartElement;
|
2853
|
+
hdlr->endElement = xmlSAX2EndElement;
|
2854
|
+
hdlr->initialized = 1;
|
2855
|
+
#endif /* LIBXML_SAX1_ENABLED */
|
2856
|
+
} else
|
2857
|
+
return(-1);
|
2858
|
+
hdlr->internalSubset = xmlSAX2InternalSubset;
|
2859
|
+
hdlr->externalSubset = xmlSAX2ExternalSubset;
|
2860
|
+
hdlr->isStandalone = xmlSAX2IsStandalone;
|
2861
|
+
hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
|
2862
|
+
hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
|
2863
|
+
hdlr->resolveEntity = xmlSAX2ResolveEntity;
|
2864
|
+
hdlr->getEntity = xmlSAX2GetEntity;
|
2865
|
+
hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
|
2866
|
+
hdlr->entityDecl = xmlSAX2EntityDecl;
|
2867
|
+
hdlr->attributeDecl = xmlSAX2AttributeDecl;
|
2868
|
+
hdlr->elementDecl = xmlSAX2ElementDecl;
|
2869
|
+
hdlr->notationDecl = xmlSAX2NotationDecl;
|
2870
|
+
hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
|
2871
|
+
hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
|
2872
|
+
hdlr->startDocument = xmlSAX2StartDocument;
|
2873
|
+
hdlr->endDocument = xmlSAX2EndDocument;
|
2874
|
+
hdlr->reference = xmlSAX2Reference;
|
2875
|
+
hdlr->characters = xmlSAX2Characters;
|
2876
|
+
hdlr->cdataBlock = xmlSAX2CDataBlock;
|
2877
|
+
hdlr->ignorableWhitespace = xmlSAX2Characters;
|
2878
|
+
hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
|
2879
|
+
hdlr->comment = xmlSAX2Comment;
|
2880
|
+
hdlr->warning = xmlParserWarning;
|
2881
|
+
hdlr->error = xmlParserError;
|
2882
|
+
hdlr->fatalError = xmlParserError;
|
2883
|
+
|
2884
|
+
return(0);
|
2885
|
+
}
|
2886
|
+
|
2887
|
+
/**
|
2888
|
+
* xmlSAX2InitDefaultSAXHandler:
|
2889
|
+
* @hdlr: the SAX handler
|
2890
|
+
* @warning: flag if non-zero sets the handler warning procedure
|
2891
|
+
*
|
2892
|
+
* Initialize the default XML SAX2 handler
|
2893
|
+
*/
|
2894
|
+
void
|
2895
|
+
xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
|
2896
|
+
{
|
2897
|
+
if ((hdlr == NULL) || (hdlr->initialized != 0))
|
2898
|
+
return;
|
2899
|
+
|
2900
|
+
xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
|
2901
|
+
if (warning == 0)
|
2902
|
+
hdlr->warning = NULL;
|
2903
|
+
else
|
2904
|
+
hdlr->warning = xmlParserWarning;
|
2905
|
+
}
|
2906
|
+
|
2907
|
+
/**
|
2908
|
+
* xmlDefaultSAXHandlerInit:
|
2909
|
+
*
|
2910
|
+
* Initialize the default SAX2 handler
|
2911
|
+
*/
|
2912
|
+
void
|
2913
|
+
xmlDefaultSAXHandlerInit(void)
|
2914
|
+
{
|
2915
|
+
#ifdef LIBXML_SAX1_ENABLED
|
2916
|
+
xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
|
2917
|
+
#endif /* LIBXML_SAX1_ENABLED */
|
2918
|
+
}
|
2919
|
+
|
2920
|
+
#ifdef LIBXML_HTML_ENABLED
|
2921
|
+
|
2922
|
+
/**
|
2923
|
+
* xmlSAX2InitHtmlDefaultSAXHandler:
|
2924
|
+
* @hdlr: the SAX handler
|
2925
|
+
*
|
2926
|
+
* Initialize the default HTML SAX2 handler
|
2927
|
+
*/
|
2928
|
+
void
|
2929
|
+
xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
|
2930
|
+
{
|
2931
|
+
if ((hdlr == NULL) || (hdlr->initialized != 0))
|
2932
|
+
return;
|
2933
|
+
|
2934
|
+
hdlr->internalSubset = xmlSAX2InternalSubset;
|
2935
|
+
hdlr->externalSubset = NULL;
|
2936
|
+
hdlr->isStandalone = NULL;
|
2937
|
+
hdlr->hasInternalSubset = NULL;
|
2938
|
+
hdlr->hasExternalSubset = NULL;
|
2939
|
+
hdlr->resolveEntity = NULL;
|
2940
|
+
hdlr->getEntity = xmlSAX2GetEntity;
|
2941
|
+
hdlr->getParameterEntity = NULL;
|
2942
|
+
hdlr->entityDecl = NULL;
|
2943
|
+
hdlr->attributeDecl = NULL;
|
2944
|
+
hdlr->elementDecl = NULL;
|
2945
|
+
hdlr->notationDecl = NULL;
|
2946
|
+
hdlr->unparsedEntityDecl = NULL;
|
2947
|
+
hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
|
2948
|
+
hdlr->startDocument = xmlSAX2StartDocument;
|
2949
|
+
hdlr->endDocument = xmlSAX2EndDocument;
|
2950
|
+
hdlr->startElement = xmlSAX2StartElement;
|
2951
|
+
hdlr->endElement = xmlSAX2EndElement;
|
2952
|
+
hdlr->reference = NULL;
|
2953
|
+
hdlr->characters = xmlSAX2Characters;
|
2954
|
+
hdlr->cdataBlock = xmlSAX2CDataBlock;
|
2955
|
+
hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
|
2956
|
+
hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
|
2957
|
+
hdlr->comment = xmlSAX2Comment;
|
2958
|
+
hdlr->warning = xmlParserWarning;
|
2959
|
+
hdlr->error = xmlParserError;
|
2960
|
+
hdlr->fatalError = xmlParserError;
|
2961
|
+
|
2962
|
+
hdlr->initialized = 1;
|
2963
|
+
}
|
2964
|
+
|
2965
|
+
/**
|
2966
|
+
* htmlDefaultSAXHandlerInit:
|
2967
|
+
*
|
2968
|
+
* Initialize the default SAX handler
|
2969
|
+
*/
|
2970
|
+
void
|
2971
|
+
htmlDefaultSAXHandlerInit(void)
|
2972
|
+
{
|
2973
|
+
xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
|
2974
|
+
}
|
2975
|
+
|
2976
|
+
#endif /* LIBXML_HTML_ENABLED */
|
2977
|
+
|
2978
|
+
#ifdef LIBXML_DOCB_ENABLED
|
2979
|
+
|
2980
|
+
/**
|
2981
|
+
* xmlSAX2InitDocbDefaultSAXHandler:
|
2982
|
+
* @hdlr: the SAX handler
|
2983
|
+
*
|
2984
|
+
* Initialize the default DocBook SAX2 handler
|
2985
|
+
*/
|
2986
|
+
void
|
2987
|
+
xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
|
2988
|
+
{
|
2989
|
+
if ((hdlr == NULL) || (hdlr->initialized != 0))
|
2990
|
+
return;
|
2991
|
+
|
2992
|
+
hdlr->internalSubset = xmlSAX2InternalSubset;
|
2993
|
+
hdlr->externalSubset = NULL;
|
2994
|
+
hdlr->isStandalone = xmlSAX2IsStandalone;
|
2995
|
+
hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
|
2996
|
+
hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
|
2997
|
+
hdlr->resolveEntity = xmlSAX2ResolveEntity;
|
2998
|
+
hdlr->getEntity = xmlSAX2GetEntity;
|
2999
|
+
hdlr->getParameterEntity = NULL;
|
3000
|
+
hdlr->entityDecl = xmlSAX2EntityDecl;
|
3001
|
+
hdlr->attributeDecl = NULL;
|
3002
|
+
hdlr->elementDecl = NULL;
|
3003
|
+
hdlr->notationDecl = NULL;
|
3004
|
+
hdlr->unparsedEntityDecl = NULL;
|
3005
|
+
hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
|
3006
|
+
hdlr->startDocument = xmlSAX2StartDocument;
|
3007
|
+
hdlr->endDocument = xmlSAX2EndDocument;
|
3008
|
+
hdlr->startElement = xmlSAX2StartElement;
|
3009
|
+
hdlr->endElement = xmlSAX2EndElement;
|
3010
|
+
hdlr->reference = xmlSAX2Reference;
|
3011
|
+
hdlr->characters = xmlSAX2Characters;
|
3012
|
+
hdlr->cdataBlock = NULL;
|
3013
|
+
hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
|
3014
|
+
hdlr->processingInstruction = NULL;
|
3015
|
+
hdlr->comment = xmlSAX2Comment;
|
3016
|
+
hdlr->warning = xmlParserWarning;
|
3017
|
+
hdlr->error = xmlParserError;
|
3018
|
+
hdlr->fatalError = xmlParserError;
|
3019
|
+
|
3020
|
+
hdlr->initialized = 1;
|
3021
|
+
}
|
3022
|
+
|
3023
|
+
/**
|
3024
|
+
* docbDefaultSAXHandlerInit:
|
3025
|
+
*
|
3026
|
+
* Initialize the default SAX handler
|
3027
|
+
*/
|
3028
|
+
void
|
3029
|
+
docbDefaultSAXHandlerInit(void)
|
3030
|
+
{
|
3031
|
+
xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
|
3032
|
+
}
|
3033
|
+
|
3034
|
+
#endif /* LIBXML_DOCB_ENABLED */
|
3035
|
+
#define bottom_SAX2
|
3036
|
+
#include "elfgcchack.h"
|