2
* xmlreader.c: implements the xmlTextReader streaming node API
5
* XmlTextReader.Normalization Property won't be supported, since
6
* it makes the parser non compliant to the XML recommendation
8
* See Copyright for the status of this software.
15
* - XML Schemas validation
20
#ifdef LIBXML_READER_ENABLED
21
#include <string.h> /* for memset() only ! */
31
#include <libxml/xmlmemory.h>
32
#include <libxml/xmlIO.h>
33
#include <libxml/xmlreader.h>
34
#include <libxml/parserInternals.h>
35
#ifdef LIBXML_SCHEMAS_ENABLED
36
#include <libxml/relaxng.h>
37
#include <libxml/xmlschemas.h>
39
#include <libxml/uri.h>
40
#ifdef LIBXML_XINCLUDE_ENABLED
41
#include <libxml/xinclude.h>
43
#ifdef LIBXML_PATTERN_ENABLED
44
#include <libxml/pattern.h>
47
/* #define DEBUG_CALLBACKS */
48
/* #define DEBUG_READER */
53
* macro to flag unimplemented blocks
56
xmlGenericError(xmlGenericErrorContext, \
57
"Unimplemented block at %s:%d\n", \
61
#define DUMP_READER xmlTextReaderDebug(reader);
66
#define CHUNK_SIZE 512
67
/************************************************************************
69
* The parser: maps the Text Reader API on top of the existing *
70
* parsing routines building a tree *
72
************************************************************************/
74
#define XML_TEXTREADER_INPUT 1
75
#define XML_TEXTREADER_CTXT 2
78
XML_TEXTREADER_NONE = -1,
79
XML_TEXTREADER_START= 0,
80
XML_TEXTREADER_ELEMENT= 1,
81
XML_TEXTREADER_END= 2,
82
XML_TEXTREADER_EMPTY= 3,
83
XML_TEXTREADER_BACKTRACK= 4,
84
XML_TEXTREADER_DONE= 5,
85
XML_TEXTREADER_ERROR= 6
89
XML_TEXTREADER_NOT_VALIDATE = 0,
90
XML_TEXTREADER_VALIDATE_DTD = 1,
91
XML_TEXTREADER_VALIDATE_RNG = 2,
92
XML_TEXTREADER_VALIDATE_XSD = 4
93
} xmlTextReaderValidate;
95
struct _xmlTextReader {
96
int mode; /* the parsing mode */
97
xmlDocPtr doc; /* when walking an existing doc */
98
xmlTextReaderValidate validate;/* is there any validation */
99
int allocs; /* what structure were deallocated */
100
xmlTextReaderState state;
101
xmlParserCtxtPtr ctxt; /* the parser context */
102
xmlSAXHandlerPtr sax; /* the parser SAX callbacks */
103
xmlParserInputBufferPtr input; /* the input */
104
startElementSAXFunc startElement;/* initial SAX callbacks */
105
endElementSAXFunc endElement; /* idem */
106
startElementNsSAX2Func startElementNs;/* idem */
107
endElementNsSAX2Func endElementNs; /* idem */
108
charactersSAXFunc characters;
109
cdataBlockSAXFunc cdataBlock;
110
unsigned int base; /* base of the segment in the input */
111
unsigned int cur; /* current position in the input */
112
xmlNodePtr node; /* current node */
113
xmlNodePtr curnode;/* current attribute node */
114
int depth; /* depth of the current node */
115
xmlNodePtr faketext;/* fake xmlNs chld */
116
int preserve;/* preserve the resulting document */
117
xmlBufferPtr buffer; /* used to return const xmlChar * */
118
xmlDictPtr dict; /* the context dictionnary */
120
/* entity stack when traversing entities content */
121
xmlNodePtr ent; /* Current Entity Ref Node */
122
int entNr; /* Depth of the entities stack */
123
int entMax; /* Max depth of the entities stack */
124
xmlNodePtr *entTab; /* array of entities */
127
xmlTextReaderErrorFunc errorFunc; /* callback function */
128
void *errorFuncArg; /* callback function user argument */
130
#ifdef LIBXML_SCHEMAS_ENABLED
131
/* Handling of RelaxNG validation */
132
xmlRelaxNGPtr rngSchemas; /* The Relax NG schemas */
133
xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
134
int rngValidErrors;/* The number of errors detected */
135
xmlNodePtr rngFullNode; /* the node if RNG not progressive */
136
/* Handling of Schemas validation */
137
xmlSchemaPtr xsdSchemas; /* The Schemas schemas */
138
xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */
139
int xsdPreserveCtxt; /* 1 if the context was provided by the user */
140
int xsdValidErrors;/* The number of errors detected */
141
xmlSchemaSAXPlugPtr xsdPlug; /* the schemas plug in SAX pipeline */
143
#ifdef LIBXML_XINCLUDE_ENABLED
144
/* Handling of XInclude processing */
145
int xinclude; /* is xinclude asked for */
146
const xmlChar * xinclude_name; /* the xinclude name from dict */
147
xmlXIncludeCtxtPtr xincctxt; /* the xinclude context */
148
int in_xinclude; /* counts for xinclude */
150
#ifdef LIBXML_PATTERN_ENABLED
151
int patternNr; /* number of preserve patterns */
152
int patternMax; /* max preserve patterns */
153
xmlPatternPtr *patternTab; /* array of preserve patterns */
155
int preserves; /* level of preserves */
156
int parserFlags; /* the set of options set */
157
/* Structured error handling */
158
xmlStructuredErrorFunc sErrorFunc; /* callback function */
161
#define NODE_IS_EMPTY 0x1
162
#define NODE_IS_PRESERVED 0x2
163
#define NODE_IS_SPRESERVED 0x4
168
* Macro used to return an interned string
170
#define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
171
#define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
173
static int xmlTextReaderReadTree(xmlTextReaderPtr reader);
174
static int xmlTextReaderNextTree(xmlTextReaderPtr reader);
176
/************************************************************************
178
* Our own version of the freeing routines as we recycle nodes *
180
************************************************************************/
185
* Free a string if it is not owned by the "dict" dictionnary in the
188
#define DICT_FREE(str) \
189
if ((str) && ((!dict) || \
190
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
191
xmlFree((char *)(str));
193
static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
194
static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);
200
* Deallocate the memory used by an id definition
203
xmlFreeID(xmlIDPtr id) {
204
xmlDictPtr dict = NULL;
206
if (id == NULL) return;
209
dict = id->doc->dict;
211
if (id->value != NULL)
217
* xmlTextReaderRemoveID:
219
* @attr: the attribute
221
* Remove the given attribute from the ID table maintained internally.
223
* Returns -1 if the lookup failed and 0 otherwise
226
xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
231
if (doc == NULL) return(-1);
232
if (attr == NULL) return(-1);
233
table = (xmlIDTablePtr) doc->ids;
237
ID = xmlNodeListGetString(doc, attr->children, 1);
240
id = xmlHashLookup(table, ID);
242
if (id == NULL || id->attr != attr) {
245
id->name = attr->name;
251
* xmlTextReaderFreeProp:
252
* @reader: the xmlTextReaderPtr used
258
xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
261
dict = reader->ctxt->dict;
262
if (cur == NULL) return;
264
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
265
xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
267
/* Check for ID removal -> leading to invalid references ! */
268
if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
269
((cur->parent->doc->intSubset != NULL) ||
270
(cur->parent->doc->extSubset != NULL))) {
271
if (xmlIsID(cur->parent->doc, cur->parent, cur))
272
xmlTextReaderRemoveID(cur->parent->doc, cur);
274
if (cur->children != NULL)
275
xmlTextReaderFreeNodeList(reader, cur->children);
277
DICT_FREE(cur->name);
278
if ((reader != NULL) && (reader->ctxt != NULL) &&
279
(reader->ctxt->freeAttrsNr < 100)) {
280
cur->next = reader->ctxt->freeAttrs;
281
reader->ctxt->freeAttrs = cur;
282
reader->ctxt->freeAttrsNr++;
289
* xmlTextReaderFreePropList:
290
* @reader: the xmlTextReaderPtr used
291
* @cur: the first property in the list
293
* Free a property and all its siblings, all the children are freed too.
296
xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
298
if (cur == NULL) return;
299
while (cur != NULL) {
301
xmlTextReaderFreeProp(reader, cur);
307
* xmlTextReaderFreeNodeList:
308
* @reader: the xmlTextReaderPtr used
309
* @cur: the first node in the list
311
* Free a node and all its siblings, this is a recursive behaviour, all
312
* the children are freed too.
315
xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
319
dict = reader->ctxt->dict;
320
if (cur == NULL) return;
321
if (cur->type == XML_NAMESPACE_DECL) {
322
xmlFreeNsList((xmlNsPtr) cur);
325
if ((cur->type == XML_DOCUMENT_NODE) ||
326
(cur->type == XML_HTML_DOCUMENT_NODE)) {
327
xmlFreeDoc((xmlDocPtr) cur);
330
while (cur != NULL) {
332
/* unroll to speed up freeing the document */
333
if (cur->type != XML_DTD_NODE) {
335
if ((cur->children != NULL) &&
336
(cur->type != XML_ENTITY_REF_NODE)) {
337
if (cur->children->parent == cur)
338
xmlTextReaderFreeNodeList(reader, cur->children);
339
cur->children = NULL;
342
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
343
xmlDeregisterNodeDefaultValue(cur);
345
if (((cur->type == XML_ELEMENT_NODE) ||
346
(cur->type == XML_XINCLUDE_START) ||
347
(cur->type == XML_XINCLUDE_END)) &&
348
(cur->properties != NULL))
349
xmlTextReaderFreePropList(reader, cur->properties);
350
if ((cur->content != (xmlChar *) &(cur->properties)) &&
351
(cur->type != XML_ELEMENT_NODE) &&
352
(cur->type != XML_XINCLUDE_START) &&
353
(cur->type != XML_XINCLUDE_END) &&
354
(cur->type != XML_ENTITY_REF_NODE)) {
355
DICT_FREE(cur->content);
357
if (((cur->type == XML_ELEMENT_NODE) ||
358
(cur->type == XML_XINCLUDE_START) ||
359
(cur->type == XML_XINCLUDE_END)) &&
360
(cur->nsDef != NULL))
361
xmlFreeNsList(cur->nsDef);
364
* we don't free element names here they are interned now
366
if ((cur->type != XML_TEXT_NODE) &&
367
(cur->type != XML_COMMENT_NODE))
368
DICT_FREE(cur->name);
369
if (((cur->type == XML_ELEMENT_NODE) ||
370
(cur->type == XML_TEXT_NODE)) &&
371
(reader != NULL) && (reader->ctxt != NULL) &&
372
(reader->ctxt->freeElemsNr < 100)) {
373
cur->next = reader->ctxt->freeElems;
374
reader->ctxt->freeElems = cur;
375
reader->ctxt->freeElemsNr++;
385
* xmlTextReaderFreeNode:
386
* @reader: the xmlTextReaderPtr used
389
* Free a node, this is a recursive behaviour, all the children are freed too.
390
* This doesn't unlink the child from the list, use xmlUnlinkNode() first.
393
xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
396
dict = reader->ctxt->dict;
397
if (cur->type == XML_DTD_NODE) {
398
xmlFreeDtd((xmlDtdPtr) cur);
401
if (cur->type == XML_NAMESPACE_DECL) {
402
xmlFreeNs((xmlNsPtr) cur);
405
if (cur->type == XML_ATTRIBUTE_NODE) {
406
xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);
410
if ((cur->children != NULL) &&
411
(cur->type != XML_ENTITY_REF_NODE)) {
412
if (cur->children->parent == cur)
413
xmlTextReaderFreeNodeList(reader, cur->children);
414
cur->children = NULL;
417
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
418
xmlDeregisterNodeDefaultValue(cur);
420
if (((cur->type == XML_ELEMENT_NODE) ||
421
(cur->type == XML_XINCLUDE_START) ||
422
(cur->type == XML_XINCLUDE_END)) &&
423
(cur->properties != NULL))
424
xmlTextReaderFreePropList(reader, cur->properties);
425
if ((cur->content != (xmlChar *) &(cur->properties)) &&
426
(cur->type != XML_ELEMENT_NODE) &&
427
(cur->type != XML_XINCLUDE_START) &&
428
(cur->type != XML_XINCLUDE_END) &&
429
(cur->type != XML_ENTITY_REF_NODE)) {
430
DICT_FREE(cur->content);
432
if (((cur->type == XML_ELEMENT_NODE) ||
433
(cur->type == XML_XINCLUDE_START) ||
434
(cur->type == XML_XINCLUDE_END)) &&
435
(cur->nsDef != NULL))
436
xmlFreeNsList(cur->nsDef);
439
* we don't free names here they are interned now
441
if ((cur->type != XML_TEXT_NODE) &&
442
(cur->type != XML_COMMENT_NODE))
443
DICT_FREE(cur->name);
445
if (((cur->type == XML_ELEMENT_NODE) ||
446
(cur->type == XML_TEXT_NODE)) &&
447
(reader != NULL) && (reader->ctxt != NULL) &&
448
(reader->ctxt->freeElemsNr < 100)) {
449
cur->next = reader->ctxt->freeElems;
450
reader->ctxt->freeElems = cur;
451
reader->ctxt->freeElemsNr++;
458
* xmlTextReaderFreeIDTable:
459
* @table: An id table
461
* Deallocate the memory used by an ID hash table.
464
xmlTextReaderFreeIDTable(xmlIDTablePtr table) {
465
xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
469
* xmlTextReaderFreeDoc:
470
* @reader: the xmlTextReaderPtr used
471
* @cur: pointer to the document
473
* Free up all the structures used by a document, tree included.
476
xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
477
xmlDtdPtr extSubset, intSubset;
479
if (cur == NULL) return;
481
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
482
xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
485
* Do this before freeing the children list to avoid ID lookups
487
if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids);
489
if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
491
extSubset = cur->extSubset;
492
intSubset = cur->intSubset;
493
if (intSubset == extSubset)
495
if (extSubset != NULL) {
496
xmlUnlinkNode((xmlNodePtr) cur->extSubset);
497
cur->extSubset = NULL;
498
xmlFreeDtd(extSubset);
500
if (intSubset != NULL) {
501
xmlUnlinkNode((xmlNodePtr) cur->intSubset);
502
cur->intSubset = NULL;
503
xmlFreeDtd(intSubset);
506
if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);
508
if (cur->version != NULL) xmlFree((char *) cur->version);
509
if (cur->name != NULL) xmlFree((char *) cur->name);
510
if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
511
if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
512
if (cur->URL != NULL) xmlFree((char *) cur->URL);
513
if (cur->dict != NULL) xmlDictFree(cur->dict);
518
/************************************************************************
520
* The reader core parser *
522
************************************************************************/
525
xmlTextReaderDebug(xmlTextReaderPtr reader) {
526
if ((reader == NULL) || (reader->ctxt == NULL)) {
527
fprintf(stderr, "xmlTextReader NULL\n");
530
fprintf(stderr, "xmlTextReader: state %d depth %d ",
531
reader->state, reader->depth);
532
if (reader->node == NULL) {
533
fprintf(stderr, "node = NULL\n");
535
fprintf(stderr, "node %s\n", reader->node->name);
537
fprintf(stderr, " input: base %d, cur %d, depth %d: ",
538
reader->base, reader->cur, reader->ctxt->nodeNr);
539
if (reader->input->buffer == NULL) {
540
fprintf(stderr, "buffer is NULL\n");
542
#ifdef LIBXML_DEBUG_ENABLED
543
xmlDebugDumpString(stderr,
544
&reader->input->buffer->content[reader->cur]);
546
fprintf(stderr, "\n");
552
* xmlTextReaderEntPush:
553
* @reader: the xmlTextReaderPtr used
554
* @value: the entity reference node
556
* Pushes a new entity reference node on top of the entities stack
558
* Returns 0 in case of error, the index in the stack otherwise
561
xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)
563
if (reader->entMax <= 0) {
565
reader->entTab = (xmlNodePtr *) xmlMalloc(reader->entMax *
566
sizeof(reader->entTab[0]));
567
if (reader->entTab == NULL) {
568
xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
572
if (reader->entNr >= reader->entMax) {
575
(xmlNodePtr *) xmlRealloc(reader->entTab,
577
sizeof(reader->entTab[0]));
578
if (reader->entTab == NULL) {
579
xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
583
reader->entTab[reader->entNr] = value;
585
return (reader->entNr++);
589
* xmlTextReaderEntPop:
590
* @reader: the xmlTextReaderPtr used
592
* Pops the top element entity from the entities stack
594
* Returns the entity just removed
597
xmlTextReaderEntPop(xmlTextReaderPtr reader)
601
if (reader->entNr <= 0)
604
if (reader->entNr > 0)
605
reader->ent = reader->entTab[reader->entNr - 1];
608
ret = reader->entTab[reader->entNr];
609
reader->entTab[reader->entNr] = NULL;
614
* xmlTextReaderStartElement:
615
* @ctx: the user data (XML parser context)
616
* @fullname: The element name, including namespace prefix
617
* @atts: An array of name/value attributes pairs, NULL terminated
619
* called when an opening tag has been processed.
622
xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
623
const xmlChar **atts) {
624
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
625
xmlTextReaderPtr reader = ctxt->_private;
627
#ifdef DEBUG_CALLBACKS
628
printf("xmlTextReaderStartElement(%s)\n", fullname);
630
if ((reader != NULL) && (reader->startElement != NULL)) {
631
reader->startElement(ctx, fullname, atts);
632
if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
633
(ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
634
(ctxt->input->cur[1] == '>'))
635
ctxt->node->extra = NODE_IS_EMPTY;
638
reader->state = XML_TEXTREADER_ELEMENT;
642
* xmlTextReaderEndElement:
643
* @ctx: the user data (XML parser context)
644
* @fullname: The element name, including namespace prefix
646
* called when an ending tag has been processed.
649
xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
650
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
651
xmlTextReaderPtr reader = ctxt->_private;
653
#ifdef DEBUG_CALLBACKS
654
printf("xmlTextReaderEndElement(%s)\n", fullname);
656
if ((reader != NULL) && (reader->endElement != NULL)) {
657
reader->endElement(ctx, fullname);
662
* xmlTextReaderStartElementNs:
663
* @ctx: the user data (XML parser context)
664
* @localname: the local name of the element
665
* @prefix: the element namespace prefix if available
666
* @URI: the element namespace name if available
667
* @nb_namespaces: number of namespace definitions on that node
668
* @namespaces: pointer to the array of prefix/URI pairs namespace definitions
669
* @nb_attributes: the number of attributes on that node
670
* nb_defaulted: the number of defaulted attributes.
671
* @attributes: pointer to the array of (localname/prefix/URI/value/end)
674
* called when an opening tag has been processed.
677
xmlTextReaderStartElementNs(void *ctx,
678
const xmlChar *localname,
679
const xmlChar *prefix,
682
const xmlChar **namespaces,
685
const xmlChar **attributes)
687
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
688
xmlTextReaderPtr reader = ctxt->_private;
690
#ifdef DEBUG_CALLBACKS
691
printf("xmlTextReaderStartElementNs(%s)\n", localname);
693
if ((reader != NULL) && (reader->startElementNs != NULL)) {
694
reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
695
namespaces, nb_attributes, nb_defaulted,
697
if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
698
(ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
699
(ctxt->input->cur[1] == '>'))
700
ctxt->node->extra = NODE_IS_EMPTY;
703
reader->state = XML_TEXTREADER_ELEMENT;
707
* xmlTextReaderEndElementNs:
708
* @ctx: the user data (XML parser context)
709
* @localname: the local name of the element
710
* @prefix: the element namespace prefix if available
711
* @URI: the element namespace name if available
713
* called when an ending tag has been processed.
716
xmlTextReaderEndElementNs(void *ctx,
717
const xmlChar * localname,
718
const xmlChar * prefix,
721
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
722
xmlTextReaderPtr reader = ctxt->_private;
724
#ifdef DEBUG_CALLBACKS
725
printf("xmlTextReaderEndElementNs(%s)\n", localname);
727
if ((reader != NULL) && (reader->endElementNs != NULL)) {
728
reader->endElementNs(ctx, localname, prefix, URI);
734
* xmlTextReaderCharacters:
735
* @ctx: the user data (XML parser context)
736
* @ch: a xmlChar string
737
* @len: the number of xmlChar
739
* receiving some chars from the parser.
742
xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
744
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
745
xmlTextReaderPtr reader = ctxt->_private;
747
#ifdef DEBUG_CALLBACKS
748
printf("xmlTextReaderCharacters()\n");
750
if ((reader != NULL) && (reader->characters != NULL)) {
751
reader->characters(ctx, ch, len);
756
* xmlTextReaderCDataBlock:
757
* @ctx: the user data (XML parser context)
758
* @value: The pcdata content
759
* @len: the block length
761
* called when a pcdata block has been parsed
764
xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
766
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
767
xmlTextReaderPtr reader = ctxt->_private;
769
#ifdef DEBUG_CALLBACKS
770
printf("xmlTextReaderCDataBlock()\n");
772
if ((reader != NULL) && (reader->cdataBlock != NULL)) {
773
reader->cdataBlock(ctx, ch, len);
778
* xmlTextReaderPushData:
779
* @reader: the xmlTextReaderPtr used
781
* Push data down the progressive parser until a significant callback
784
* Returns -1 in case of failure, 0 otherwise
787
xmlTextReaderPushData(xmlTextReaderPtr reader) {
790
xmlTextReaderState oldstate;
792
if ((reader->input == NULL) || (reader->input->buffer == NULL))
795
oldstate = reader->state;
796
reader->state = XML_TEXTREADER_NONE;
797
inbuf = reader->input->buffer;
799
while (reader->state == XML_TEXTREADER_NONE) {
800
if (inbuf->use < reader->cur + CHUNK_SIZE) {
802
* Refill the buffer unless we are at the end of the stream
804
if (reader->mode != XML_TEXTREADER_MODE_EOF) {
805
val = xmlParserInputBufferRead(reader->input, 4096);
807
(inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
808
if (inbuf->use == reader->cur) {
809
reader->mode = XML_TEXTREADER_MODE_EOF;
810
reader->state = oldstate;
812
} else if (val < 0) {
813
reader->mode = XML_TEXTREADER_MODE_EOF;
814
reader->state = oldstate;
815
if ((oldstate != XML_TEXTREADER_START) ||
816
(reader->ctxt->myDoc != NULL))
818
} else if (val == 0) {
819
/* mark the end of the stream and process the remains */
820
reader->mode = XML_TEXTREADER_MODE_EOF;
828
* parse by block of CHUNK_SIZE bytes, various tests show that
829
* it's the best tradeoff at least on a 1.2GH Duron
831
if (inbuf->use >= reader->cur + CHUNK_SIZE) {
832
val = xmlParseChunk(reader->ctxt,
833
(const char *) &inbuf->content[reader->cur],
835
reader->cur += CHUNK_SIZE;
836
if ((val != 0) || (reader->ctxt->wellFormed == 0))
839
s = inbuf->use - reader->cur;
840
val = xmlParseChunk(reader->ctxt,
841
(const char *) &inbuf->content[reader->cur],
844
if ((val != 0) || (reader->ctxt->wellFormed == 0))
851
* Discard the consumed input when needed and possible
853
if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
854
if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
855
if ((reader->cur >= 4096) &&
856
(inbuf->use - reader->cur <= CHUNK_SIZE)) {
857
val = xmlBufferShrink(inbuf, reader->cur);
866
* At the end of the stream signal that the work is done to the Push
869
else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
870
if (reader->state != XML_TEXTREADER_DONE) {
871
s = inbuf->use - reader->cur;
872
val = xmlParseChunk(reader->ctxt,
873
(const char *) &inbuf->content[reader->cur],
875
reader->cur = inbuf->use;
876
reader->state = XML_TEXTREADER_DONE;
877
if ((val != 0) || (reader->ctxt->wellFormed == 0))
881
reader->state = oldstate;
885
#ifdef LIBXML_REGEXP_ENABLED
887
* xmlTextReaderValidatePush:
888
* @reader: the xmlTextReaderPtr used
890
* Push the current node for validation
893
xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
894
xmlNodePtr node = reader->node;
896
#ifdef LIBXML_VALID_ENABLED
897
if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
898
(reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
899
if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
900
reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
901
reader->ctxt->myDoc, node, node->name);
903
/* TODO use the BuildQName interface */
906
qname = xmlStrdup(node->ns->prefix);
907
qname = xmlStrcat(qname, BAD_CAST ":");
908
qname = xmlStrcat(qname, node->name);
909
reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
910
reader->ctxt->myDoc, node, qname);
915
#endif /* LIBXML_VALID_ENABLED */
916
#ifdef LIBXML_SCHEMAS_ENABLED
917
if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
918
(reader->rngValidCtxt != NULL)) {
921
if (reader->rngFullNode != NULL) return;
922
ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
927
* this element requires a full tree
929
node = xmlTextReaderExpand(reader);
931
printf("Expand failed !\n");
934
ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
937
reader->rngFullNode = node;
941
reader->rngValidErrors++;
947
* xmlTextReaderValidateCData:
948
* @reader: the xmlTextReaderPtr used
949
* @data: pointer to the CData
950
* @len: lenght of the CData block in bytes.
952
* Push some CData for validation
955
xmlTextReaderValidateCData(xmlTextReaderPtr reader,
956
const xmlChar *data, int len) {
957
#ifdef LIBXML_VALID_ENABLED
958
if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
959
(reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
960
reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
963
#endif /* LIBXML_VALID_ENABLED */
964
#ifdef LIBXML_SCHEMAS_ENABLED
965
if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
966
(reader->rngValidCtxt != NULL)) {
969
if (reader->rngFullNode != NULL) return;
970
ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
972
reader->rngValidErrors++;
978
* xmlTextReaderValidatePop:
979
* @reader: the xmlTextReaderPtr used
981
* Pop the current node from validation
984
xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
985
xmlNodePtr node = reader->node;
987
#ifdef LIBXML_VALID_ENABLED
988
if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
989
(reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
990
if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
991
reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
992
reader->ctxt->myDoc, node, node->name);
994
/* TODO use the BuildQName interface */
997
qname = xmlStrdup(node->ns->prefix);
998
qname = xmlStrcat(qname, BAD_CAST ":");
999
qname = xmlStrcat(qname, node->name);
1000
reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
1001
reader->ctxt->myDoc, node, qname);
1006
#endif /* LIBXML_VALID_ENABLED */
1007
#ifdef LIBXML_SCHEMAS_ENABLED
1008
if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
1009
(reader->rngValidCtxt != NULL)) {
1012
if (reader->rngFullNode != NULL) {
1013
if (node == reader->rngFullNode)
1014
reader->rngFullNode = NULL;
1017
ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
1018
reader->ctxt->myDoc,
1021
reader->rngValidErrors++;
1027
* xmlTextReaderValidateEntity:
1028
* @reader: the xmlTextReaderPtr used
1030
* Handle the validation when an entity reference is encountered and
1031
* entity substitution is not activated. As a result the parser interface
1032
* must walk through the entity and do the validation calls
1035
xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
1036
xmlNodePtr oldnode = reader->node;
1037
xmlNodePtr node = reader->node;
1038
xmlParserCtxtPtr ctxt = reader->ctxt;
1041
if (node->type == XML_ENTITY_REF_NODE) {
1043
* Case where the underlying tree is not availble, lookup the entity
1046
if ((node->children == NULL) && (ctxt->sax != NULL) &&
1047
(ctxt->sax->getEntity != NULL)) {
1048
node->children = (xmlNodePtr)
1049
ctxt->sax->getEntity(ctxt, node->name);
1052
if ((node->children != NULL) &&
1053
(node->children->type == XML_ENTITY_DECL) &&
1054
(node->children->children != NULL)) {
1055
xmlTextReaderEntPush(reader, node);
1056
node = node->children->children;
1060
* The error has probably be raised already.
1062
if (node == oldnode)
1066
#ifdef LIBXML_REGEXP_ENABLED
1067
} else if (node->type == XML_ELEMENT_NODE) {
1068
reader->node = node;
1069
xmlTextReaderValidatePush(reader);
1070
} else if ((node->type == XML_TEXT_NODE) ||
1071
(node->type == XML_CDATA_SECTION_NODE)) {
1072
xmlTextReaderValidateCData(reader, node->content,
1073
xmlStrlen(node->content));
1080
if (node->children != NULL) {
1081
node = node->children;
1083
} else if (node->type == XML_ELEMENT_NODE) {
1084
xmlTextReaderValidatePop(reader);
1086
if (node->next != NULL) {
1091
node = node->parent;
1092
if (node->type == XML_ELEMENT_NODE) {
1094
if (reader->entNr == 0) {
1095
while ((tmp = node->last) != NULL) {
1096
if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
1098
xmlTextReaderFreeNode(reader, tmp);
1103
reader->node = node;
1104
xmlTextReaderValidatePop(reader);
1106
if ((node->type == XML_ENTITY_DECL) &&
1107
(reader->ent != NULL) && (reader->ent->children == node)) {
1108
node = xmlTextReaderEntPop(reader);
1110
if (node == oldnode)
1112
if (node->next != NULL) {
1116
} while ((node != NULL) && (node != oldnode));
1117
} while ((node != NULL) && (node != oldnode));
1118
reader->node = oldnode;
1120
#endif /* LIBXML_REGEXP_ENABLED */
1124
* xmlTextReaderGetSuccessor:
1125
* @cur: the current node
1127
* Get the successor of a node if available.
1129
* Returns the successor node or NULL
1132
xmlTextReaderGetSuccessor(xmlNodePtr cur) {
1133
if (cur == NULL) return(NULL) ; /* ERROR */
1134
if (cur->next != NULL) return(cur->next) ;
1137
if (cur == NULL) break;
1138
if (cur->next != NULL) return(cur->next);
1139
} while (cur != NULL);
1144
* xmlTextReaderDoExpand:
1145
* @reader: the xmlTextReaderPtr used
1147
* Makes sure that the current node is fully read as well as all its
1148
* descendant. It means the full DOM subtree must be available at the
1151
* Returns 1 if the node was expanded successfully, 0 if there is no more
1152
* nodes to read, or -1 in case of error
1155
xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
1158
if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
1161
if (reader->ctxt->instate == XML_PARSER_EOF) return(1);
1163
if (xmlTextReaderGetSuccessor(reader->node) != NULL)
1165
if (reader->ctxt->nodeNr < reader->depth)
1167
if (reader->mode == XML_TEXTREADER_MODE_EOF)
1169
val = xmlTextReaderPushData(reader);
1171
reader->mode = XML_TEXTREADER_MODE_ERROR;
1174
} while(reader->mode != XML_TEXTREADER_MODE_EOF);
1179
* xmlTextReaderCollectSiblings:
1180
* @node: the first child
1182
* Traverse depth-first through all sibling nodes and their children
1183
* nodes and concatenate their content. This is an auxiliary function
1184
* to xmlTextReaderReadString.
1186
* Returns a string containing the content, or NULL in case of error.
1189
xmlTextReaderCollectSiblings(xmlNodePtr node)
1191
xmlBufferPtr buffer;
1194
buffer = xmlBufferCreate();
1198
for ( ; node != NULL; node = node->next) {
1199
switch (node->type) {
1201
case XML_CDATA_SECTION_NODE:
1202
xmlBufferCat(buffer, node->content);
1204
case XML_ELEMENT_NODE: {
1207
tmp = xmlTextReaderCollectSiblings(node->children);
1208
xmlBufferCat(buffer, tmp);
1216
ret = buffer->content;
1217
buffer->content = NULL;
1218
xmlBufferFree(buffer);
1223
* xmlTextReaderRead:
1224
* @reader: the xmlTextReaderPtr used
1226
* Moves the position of the current instance to the next node in
1227
* the stream, exposing its properties.
1229
* Returns 1 if the node was read successfully, 0 if there is no more
1230
* nodes to read, or -1 in case of error
1233
xmlTextReaderRead(xmlTextReaderPtr reader) {
1234
int val, olddepth = 0;
1235
xmlTextReaderState oldstate = XML_TEXTREADER_START;
1236
xmlNodePtr oldnode = NULL;
1241
reader->curnode = NULL;
1242
if (reader->doc != NULL)
1243
return(xmlTextReaderReadTree(reader));
1244
if (reader->ctxt == NULL)
1246
if (reader->ctxt->wellFormed != 1)
1250
fprintf(stderr, "\nREAD ");
1253
if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
1254
reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
1259
val = xmlTextReaderPushData(reader);
1261
reader->mode = XML_TEXTREADER_MODE_ERROR;
1262
reader->state = XML_TEXTREADER_ERROR;
1265
} while ((reader->ctxt->node == NULL) &&
1266
((reader->mode != XML_TEXTREADER_MODE_EOF) &&
1267
(reader->state != XML_TEXTREADER_DONE)));
1268
if (reader->ctxt->node == NULL) {
1269
if (reader->ctxt->myDoc != NULL) {
1270
reader->node = reader->ctxt->myDoc->children;
1272
if (reader->node == NULL){
1273
reader->mode = XML_TEXTREADER_MODE_ERROR;
1274
reader->state = XML_TEXTREADER_ERROR;
1277
reader->state = XML_TEXTREADER_ELEMENT;
1279
if (reader->ctxt->myDoc != NULL) {
1280
reader->node = reader->ctxt->myDoc->children;
1282
if (reader->node == NULL)
1283
reader->node = reader->ctxt->nodeTab[0];
1284
reader->state = XML_TEXTREADER_ELEMENT;
1287
reader->ctxt->parseMode = XML_PARSE_READER;
1290
oldstate = reader->state;
1291
olddepth = reader->ctxt->nodeNr;
1292
oldnode = reader->node;
1295
if (reader->node == NULL) {
1296
if (reader->mode == XML_TEXTREADER_MODE_EOF)
1303
* If we are not backtracking on ancestors or examined nodes,
1304
* that the parser didn't finished or that we arent at the end
1305
* of stream, continue processing.
1307
while ((reader->node != NULL) && (reader->node->next == NULL) &&
1308
(reader->ctxt->nodeNr == olddepth) &&
1309
((oldstate == XML_TEXTREADER_BACKTRACK) ||
1310
(reader->node->children == NULL) ||
1311
(reader->node->type == XML_ENTITY_REF_NODE) ||
1312
((reader->node->children != NULL) &&
1313
(reader->node->children->type == XML_TEXT_NODE) &&
1314
(reader->node->children->next == NULL)) ||
1315
(reader->node->type == XML_DTD_NODE) ||
1316
(reader->node->type == XML_DOCUMENT_NODE) ||
1317
(reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
1318
((reader->ctxt->node == NULL) ||
1319
(reader->ctxt->node == reader->node) ||
1320
(reader->ctxt->node == reader->node->parent)) &&
1321
(reader->ctxt->instate != XML_PARSER_EOF)) {
1322
val = xmlTextReaderPushData(reader);
1324
reader->mode = XML_TEXTREADER_MODE_ERROR;
1325
reader->state = XML_TEXTREADER_ERROR;
1328
if (reader->node == NULL)
1331
if (oldstate != XML_TEXTREADER_BACKTRACK) {
1332
if ((reader->node->children != NULL) &&
1333
(reader->node->type != XML_ENTITY_REF_NODE) &&
1334
(reader->node->type != XML_XINCLUDE_START) &&
1335
(reader->node->type != XML_DTD_NODE)) {
1336
reader->node = reader->node->children;
1338
reader->state = XML_TEXTREADER_ELEMENT;
1342
if (reader->node->next != NULL) {
1343
if ((oldstate == XML_TEXTREADER_ELEMENT) &&
1344
(reader->node->type == XML_ELEMENT_NODE) &&
1345
(reader->node->children == NULL) &&
1346
((reader->node->extra & NODE_IS_EMPTY) == 0)
1347
#ifdef LIBXML_XINCLUDE_ENABLED
1348
&& (reader->in_xinclude <= 0)
1351
reader->state = XML_TEXTREADER_END;
1354
#ifdef LIBXML_REGEXP_ENABLED
1355
if ((reader->validate) &&
1356
(reader->node->type == XML_ELEMENT_NODE))
1357
xmlTextReaderValidatePop(reader);
1358
#endif /* LIBXML_REGEXP_ENABLED */
1359
if ((reader->preserves > 0) &&
1360
(reader->node->extra & NODE_IS_SPRESERVED))
1361
reader->preserves--;
1362
reader->node = reader->node->next;
1363
reader->state = XML_TEXTREADER_ELEMENT;
1366
* Cleanup of the old node
1368
if ((reader->preserves == 0) &&
1369
#ifdef LIBXML_XINCLUDE_ENABLED
1370
(reader->in_xinclude == 0) &&
1372
(reader->entNr == 0) &&
1373
(reader->node->prev != NULL) &&
1374
(reader->node->prev->type != XML_DTD_NODE) &&
1375
(reader->entNr == 0)) {
1376
xmlNodePtr tmp = reader->node->prev;
1377
if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
1379
xmlTextReaderFreeNode(reader, tmp);
1385
if ((oldstate == XML_TEXTREADER_ELEMENT) &&
1386
(reader->node->type == XML_ELEMENT_NODE) &&
1387
(reader->node->children == NULL) &&
1388
((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
1389
reader->state = XML_TEXTREADER_END;
1392
#ifdef LIBXML_REGEXP_ENABLED
1393
if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
1394
xmlTextReaderValidatePop(reader);
1395
#endif /* LIBXML_REGEXP_ENABLED */
1396
if ((reader->preserves > 0) &&
1397
(reader->node->extra & NODE_IS_SPRESERVED))
1398
reader->preserves--;
1399
reader->node = reader->node->parent;
1400
if ((reader->node == NULL) ||
1401
(reader->node->type == XML_DOCUMENT_NODE) ||
1402
#ifdef LIBXML_DOCB_ENABLED
1403
(reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
1405
(reader->node->type == XML_HTML_DOCUMENT_NODE)) {
1406
if (reader->mode != XML_TEXTREADER_MODE_EOF) {
1407
val = xmlParseChunk(reader->ctxt, "", 0, 1);
1408
reader->state = XML_TEXTREADER_DONE;
1412
reader->node = NULL;
1416
* Cleanup of the old node
1418
if ((reader->preserves == 0) &&
1419
#ifdef LIBXML_XINCLUDE_ENABLED
1420
(reader->in_xinclude == 0) &&
1422
(reader->entNr == 0) &&
1423
(oldnode->type != XML_DTD_NODE) &&
1424
((oldnode->extra & NODE_IS_PRESERVED) == 0) &&
1425
(reader->entNr == 0)) {
1426
xmlUnlinkNode(oldnode);
1427
xmlTextReaderFreeNode(reader, oldnode);
1432
if ((reader->preserves == 0) &&
1433
#ifdef LIBXML_XINCLUDE_ENABLED
1434
(reader->in_xinclude == 0) &&
1436
(reader->entNr == 0) &&
1437
(reader->node->last != NULL) &&
1438
((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
1439
xmlNodePtr tmp = reader->node->last;
1441
xmlTextReaderFreeNode(reader, tmp);
1444
reader->state = XML_TEXTREADER_BACKTRACK;
1450
* If we are in the middle of a piece of CDATA make sure it's finished
1452
if ((reader->node != NULL) &&
1453
(reader->node->next == NULL) &&
1454
((reader->node->type == XML_TEXT_NODE) ||
1455
(reader->node->type == XML_CDATA_SECTION_NODE))) {
1456
if (xmlTextReaderExpand(reader) == NULL)
1460
#ifdef LIBXML_XINCLUDE_ENABLED
1462
* Handle XInclude if asked for
1464
if ((reader->xinclude) && (reader->node != NULL) &&
1465
(reader->node->type == XML_ELEMENT_NODE) &&
1466
(reader->node->ns != NULL) &&
1467
((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
1468
(xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
1469
if (reader->xincctxt == NULL) {
1470
reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
1471
xmlXIncludeSetFlags(reader->xincctxt,
1472
reader->parserFlags & (~XML_PARSE_NOXINCNODE));
1475
* expand that node and process it
1477
if (xmlTextReaderExpand(reader) == NULL)
1479
xmlXIncludeProcessNode(reader->xincctxt, reader->node);
1481
if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
1482
reader->in_xinclude++;
1485
if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
1486
reader->in_xinclude--;
1491
* Handle entities enter and exit when in entity replacement mode
1493
if ((reader->node != NULL) &&
1494
(reader->node->type == XML_ENTITY_REF_NODE) &&
1495
(reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
1497
* Case where the underlying tree is not availble, lookup the entity
1500
if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
1501
(reader->ctxt->sax->getEntity != NULL)) {
1502
reader->node->children = (xmlNodePtr)
1503
reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
1506
if ((reader->node->children != NULL) &&
1507
(reader->node->children->type == XML_ENTITY_DECL) &&
1508
(reader->node->children->children != NULL)) {
1509
xmlTextReaderEntPush(reader, reader->node);
1510
reader->node = reader->node->children->children;
1512
#ifdef LIBXML_REGEXP_ENABLED
1513
} else if ((reader->node != NULL) &&
1514
(reader->node->type == XML_ENTITY_REF_NODE) &&
1515
(reader->ctxt != NULL) && (reader->validate)) {
1516
xmlTextReaderValidateEntity(reader);
1517
#endif /* LIBXML_REGEXP_ENABLED */
1519
if ((reader->node != NULL) &&
1520
(reader->node->type == XML_ENTITY_DECL) &&
1521
(reader->ent != NULL) && (reader->ent->children == reader->node)) {
1522
reader->node = xmlTextReaderEntPop(reader);
1526
#ifdef LIBXML_REGEXP_ENABLED
1527
if ((reader->validate) && (reader->node != NULL)) {
1528
xmlNodePtr node = reader->node;
1530
if ((node->type == XML_ELEMENT_NODE) &&
1531
((reader->state != XML_TEXTREADER_END) &&
1532
(reader->state != XML_TEXTREADER_BACKTRACK))) {
1533
xmlTextReaderValidatePush(reader);
1534
} else if ((node->type == XML_TEXT_NODE) ||
1535
(node->type == XML_CDATA_SECTION_NODE)) {
1536
xmlTextReaderValidateCData(reader, node->content,
1537
xmlStrlen(node->content));
1540
#endif /* LIBXML_REGEXP_ENABLED */
1541
#ifdef LIBXML_PATTERN_ENABLED
1542
if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
1543
(reader->state != XML_TEXTREADER_BACKTRACK)) {
1545
for (i = 0;i < reader->patternNr;i++) {
1546
if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
1547
xmlTextReaderPreserve(reader);
1552
#endif /* LIBXML_PATTERN_ENABLED */
1553
#ifdef LIBXML_SCHEMAS_ENABLED
1554
if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
1555
(reader->xsdValidErrors == 0) &&
1556
(reader->xsdValidCtxt != NULL)) {
1557
reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
1559
#endif /* LIBXML_PATTERN_ENABLED */
1562
reader->state = XML_TEXTREADER_DONE;
1567
* xmlTextReaderReadState:
1568
* @reader: the xmlTextReaderPtr used
1570
* Gets the read state of the reader.
1572
* Returns the state value, or -1 in case of error
1575
xmlTextReaderReadState(xmlTextReaderPtr reader) {
1578
return(reader->mode);
1582
* xmlTextReaderExpand:
1583
* @reader: the xmlTextReaderPtr used
1585
* Reads the contents of the current node and the full subtree. It then makes
1586
* the subtree available until the next xmlTextReaderRead() call
1588
* Returns a node pointer valid until the next xmlTextReaderRead() call
1589
* or NULL in case of error.
1592
xmlTextReaderExpand(xmlTextReaderPtr reader) {
1593
if ((reader == NULL) || (reader->node == NULL))
1595
if (reader->doc != NULL)
1596
return(reader->node);
1597
if (reader->ctxt == NULL)
1599
if (xmlTextReaderDoExpand(reader) < 0)
1601
return(reader->node);
1605
* xmlTextReaderNext:
1606
* @reader: the xmlTextReaderPtr used
1608
* Skip to the node following the current one in document order while
1609
* avoiding the subtree if any.
1611
* Returns 1 if the node was read successfully, 0 if there is no more
1612
* nodes to read, or -1 in case of error
1615
xmlTextReaderNext(xmlTextReaderPtr reader) {
1621
if (reader->doc != NULL)
1622
return(xmlTextReaderNextTree(reader));
1624
if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
1625
return(xmlTextReaderRead(reader));
1626
if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
1627
return(xmlTextReaderRead(reader));
1628
if (cur->extra & NODE_IS_EMPTY)
1629
return(xmlTextReaderRead(reader));
1631
ret = xmlTextReaderRead(reader);
1634
} while (reader->node != cur);
1635
return(xmlTextReaderRead(reader));
1638
#ifdef LIBXML_WRITER_ENABLED
1640
* xmlTextReaderReadInnerXml:
1641
* @reader: the xmlTextReaderPtr used
1643
* Reads the contents of the current node, including child nodes and markup.
1645
* Returns a string containing the XML content, or NULL if the current node
1646
* is neither an element nor attribute, or has no child nodes. The
1647
* string must be deallocated by the caller.
1650
xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
1653
xmlNodePtr node, cur_node;
1654
xmlBufferPtr buff, buff2;
1657
if (xmlTextReaderExpand(reader) == NULL) {
1661
buff = xmlBufferCreate();
1662
for (cur_node = reader->node->children; cur_node != NULL;
1663
cur_node = cur_node->next) {
1664
node = xmlDocCopyNode(cur_node, doc, 1);
1665
buff2 = xmlBufferCreate();
1666
if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
1668
xmlBufferFree(buff2);
1669
xmlBufferFree(buff);
1672
xmlBufferCat(buff, buff2->content);
1674
xmlBufferFree(buff2);
1676
resbuf = buff->content;
1677
buff->content = NULL;
1679
xmlBufferFree(buff);
1684
#ifdef LIBXML_WRITER_ENABLED
1686
* xmlTextReaderReadOuterXml:
1687
* @reader: the xmlTextReaderPtr used
1689
* Reads the contents of the current node, including child nodes and markup.
1691
* Returns a string containing the XML content, or NULL if the current node
1692
* is neither an element nor attribute, or has no child nodes. The
1693
* string must be deallocated by the caller.
1696
xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
1703
node = reader->node;
1705
if (xmlTextReaderExpand(reader) == NULL) {
1708
node = xmlDocCopyNode(node, doc, 1);
1709
buff = xmlBufferCreate();
1710
if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
1712
xmlBufferFree(buff);
1716
resbuf = buff->content;
1717
buff->content = NULL;
1720
xmlBufferFree(buff);
1726
* xmlTextReaderReadString:
1727
* @reader: the xmlTextReaderPtr used
1729
* Reads the contents of an element or a text node as a string.
1731
* Returns a string containing the contents of the Element or Text node,
1732
* or NULL if the reader is positioned on any other type of node.
1733
* The string must be deallocated by the caller.
1736
xmlTextReaderReadString(xmlTextReaderPtr reader)
1740
if ((reader == NULL) || (reader->node == NULL))
1743
node = (reader->curnode != NULL) ? reader->curnode : reader->node;
1744
switch (node->type) {
1746
if (node->content != NULL)
1747
return(xmlStrdup(node->content));
1749
case XML_ELEMENT_NODE:
1750
if (xmlTextReaderDoExpand(reader) != -1) {
1751
return xmlTextReaderCollectSiblings(node->children);
1753
case XML_ATTRIBUTE_NODE:
1764
* xmlTextReaderReadBase64:
1765
* @reader: the xmlTextReaderPtr used
1766
* @array: a byte array to store the content.
1767
* @offset: the zero-based index into array where the method should
1769
* @len: the number of bytes to write.
1771
* Reads and decodes the Base64 encoded contents of an element and
1772
* stores the result in a byte buffer.
1774
* Returns the number of bytes written to array, or zero if the current
1775
* instance is not positioned on an element or -1 in case of error.
1778
xmlTextReaderReadBase64(xmlTextReaderPtr reader,
1779
unsigned char *array ATTRIBUTE_UNUSED,
1780
int offset ATTRIBUTE_UNUSED,
1781
int len ATTRIBUTE_UNUSED) {
1782
if ((reader == NULL) || (reader->ctxt == NULL))
1784
if (reader->ctxt->wellFormed != 1)
1787
if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
1794
* xmlTextReaderReadBinHex:
1795
* @reader: the xmlTextReaderPtr used
1796
* @array: a byte array to store the content.
1797
* @offset: the zero-based index into array where the method should
1799
* @len: the number of bytes to write.
1801
* Reads and decodes the BinHex encoded contents of an element and
1802
* stores the result in a byte buffer.
1804
* Returns the number of bytes written to array, or zero if the current
1805
* instance is not positioned on an element or -1 in case of error.
1808
xmlTextReaderReadBinHex(xmlTextReaderPtr reader,
1809
unsigned char *array ATTRIBUTE_UNUSED,
1810
int offset ATTRIBUTE_UNUSED,
1811
int len ATTRIBUTE_UNUSED) {
1812
if ((reader == NULL) || (reader->ctxt == NULL))
1814
if (reader->ctxt->wellFormed != 1)
1817
if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
1824
/************************************************************************
1826
* Operating on a preparsed tree *
1828
************************************************************************/
1830
xmlTextReaderNextTree(xmlTextReaderPtr reader)
1835
if (reader->state == XML_TEXTREADER_END)
1838
if (reader->node == NULL) {
1839
if (reader->doc->children == NULL) {
1840
reader->state = XML_TEXTREADER_END;
1844
reader->node = reader->doc->children;
1845
reader->state = XML_TEXTREADER_START;
1849
if (reader->state != XML_TEXTREADER_BACKTRACK) {
1850
if (reader->node->children != 0) {
1851
reader->node = reader->node->children;
1853
reader->state = XML_TEXTREADER_START;
1857
if ((reader->node->type == XML_ELEMENT_NODE) ||
1858
(reader->node->type == XML_ATTRIBUTE_NODE)) {
1859
reader->state = XML_TEXTREADER_BACKTRACK;
1864
if (reader->node->next != 0) {
1865
reader->node = reader->node->next;
1866
reader->state = XML_TEXTREADER_START;
1870
if (reader->node->parent != 0) {
1871
if (reader->node->parent->type == XML_DOCUMENT_NODE) {
1872
reader->state = XML_TEXTREADER_END;
1876
reader->node = reader->node->parent;
1878
reader->state = XML_TEXTREADER_BACKTRACK;
1882
reader->state = XML_TEXTREADER_END;
1888
* xmlTextReaderReadTree:
1889
* @reader: the xmlTextReaderPtr used
1891
* Moves the position of the current instance to the next node in
1892
* the stream, exposing its properties.
1894
* Returns 1 if the node was read successfully, 0 if there is no more
1895
* nodes to read, or -1 in case of error
1898
xmlTextReaderReadTree(xmlTextReaderPtr reader) {
1899
if (reader->state == XML_TEXTREADER_END)
1903
if (reader->node == NULL) {
1904
if (reader->doc->children == NULL) {
1905
reader->state = XML_TEXTREADER_END;
1909
reader->node = reader->doc->children;
1910
reader->state = XML_TEXTREADER_START;
1914
if ((reader->state != XML_TEXTREADER_BACKTRACK) &&
1915
(reader->node->type != XML_DTD_NODE) &&
1916
(reader->node->type != XML_XINCLUDE_START) &&
1917
(reader->node->type != XML_ENTITY_REF_NODE)) {
1918
if (reader->node->children != NULL) {
1919
reader->node = reader->node->children;
1921
reader->state = XML_TEXTREADER_START;
1925
if (reader->node->type == XML_ATTRIBUTE_NODE) {
1926
reader->state = XML_TEXTREADER_BACKTRACK;
1931
if (reader->node->next != NULL) {
1932
reader->node = reader->node->next;
1933
reader->state = XML_TEXTREADER_START;
1937
if (reader->node->parent != NULL) {
1938
if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||
1939
(reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) {
1940
reader->state = XML_TEXTREADER_END;
1944
reader->node = reader->node->parent;
1946
reader->state = XML_TEXTREADER_BACKTRACK;
1950
reader->state = XML_TEXTREADER_END;
1953
if ((reader->node->type == XML_XINCLUDE_START) ||
1954
(reader->node->type == XML_XINCLUDE_END))
1961
* xmlTextReaderNextSibling:
1962
* @reader: the xmlTextReaderPtr used
1964
* Skip to the node following the current one in document order while
1965
* avoiding the subtree if any.
1966
* Currently implemented only for Readers built on a document
1968
* Returns 1 if the node was read successfully, 0 if there is no more
1969
* nodes to read, or -1 in case of error
1972
xmlTextReaderNextSibling(xmlTextReaderPtr reader) {
1975
if (reader->doc == NULL) {
1980
if (reader->state == XML_TEXTREADER_END)
1983
if (reader->node == NULL)
1984
return(xmlTextReaderNextTree(reader));
1986
if (reader->node->next != NULL) {
1987
reader->node = reader->node->next;
1988
reader->state = XML_TEXTREADER_START;
1995
/************************************************************************
1997
* Constructor and destructors *
1999
************************************************************************/
2002
* @input: the xmlParserInputBufferPtr used to read data
2003
* @URI: the URI information for the source if available
2005
* Create an xmlTextReader structure fed with @input
2007
* Returns the new xmlTextReaderPtr or NULL in case of error
2010
xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
2011
xmlTextReaderPtr ret;
2015
ret = xmlMalloc(sizeof(xmlTextReader));
2017
xmlGenericError(xmlGenericErrorContext,
2018
"xmlNewTextReader : malloc failed\n");
2021
memset(ret, 0, sizeof(xmlTextReader));
2027
ret->buffer = xmlBufferCreateSize(100);
2028
if (ret->buffer == NULL) {
2030
xmlGenericError(xmlGenericErrorContext,
2031
"xmlNewTextReader : malloc failed\n");
2034
ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
2035
if (ret->sax == NULL) {
2036
xmlBufferFree(ret->buffer);
2038
xmlGenericError(xmlGenericErrorContext,
2039
"xmlNewTextReader : malloc failed\n");
2042
xmlSAXVersion(ret->sax, 2);
2043
ret->startElement = ret->sax->startElement;
2044
ret->sax->startElement = xmlTextReaderStartElement;
2045
ret->endElement = ret->sax->endElement;
2046
ret->sax->endElement = xmlTextReaderEndElement;
2047
#ifdef LIBXML_SAX1_ENABLED
2048
if (ret->sax->initialized == XML_SAX2_MAGIC) {
2049
#endif /* LIBXML_SAX1_ENABLED */
2050
ret->startElementNs = ret->sax->startElementNs;
2051
ret->sax->startElementNs = xmlTextReaderStartElementNs;
2052
ret->endElementNs = ret->sax->endElementNs;
2053
ret->sax->endElementNs = xmlTextReaderEndElementNs;
2054
#ifdef LIBXML_SAX1_ENABLED
2056
ret->startElementNs = NULL;
2057
ret->endElementNs = NULL;
2059
#endif /* LIBXML_SAX1_ENABLED */
2060
ret->characters = ret->sax->characters;
2061
ret->sax->characters = xmlTextReaderCharacters;
2062
ret->sax->ignorableWhitespace = xmlTextReaderCharacters;
2063
ret->cdataBlock = ret->sax->cdataBlock;
2064
ret->sax->cdataBlock = xmlTextReaderCDataBlock;
2066
ret->mode = XML_TEXTREADER_MODE_INITIAL;
2068
ret->curnode = NULL;
2069
if (ret->input->buffer->use < 4) {
2070
xmlParserInputBufferRead(input, 4);
2072
if (ret->input->buffer->use >= 4) {
2073
ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
2074
(const char *) ret->input->buffer->content, 4, URI);
2078
ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);
2083
if (ret->ctxt == NULL) {
2084
xmlGenericError(xmlGenericErrorContext,
2085
"xmlNewTextReader : malloc failed\n");
2086
xmlBufferFree(ret->buffer);
2091
ret->ctxt->parseMode = XML_PARSE_READER;
2092
ret->ctxt->_private = ret;
2093
ret->ctxt->linenumbers = 1;
2094
ret->ctxt->dictNames = 1;
2095
ret->allocs = XML_TEXTREADER_CTXT;
2097
* use the parser dictionnary to allocate all elements and attributes names
2099
ret->ctxt->docdict = 1;
2100
ret->dict = ret->ctxt->dict;
2101
#ifdef LIBXML_XINCLUDE_ENABLED
2104
#ifdef LIBXML_PATTERN_ENABLED
2105
ret->patternMax = 0;
2106
ret->patternTab = NULL;
2112
* xmlNewTextReaderFilename:
2113
* @URI: the URI of the resource to process
2115
* Create an xmlTextReader structure fed with the resource at @URI
2117
* Returns the new xmlTextReaderPtr or NULL in case of error
2120
xmlNewTextReaderFilename(const char *URI) {
2121
xmlParserInputBufferPtr input;
2122
xmlTextReaderPtr ret;
2123
char *directory = NULL;
2125
input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
2128
ret = xmlNewTextReader(input, URI);
2130
xmlFreeParserInputBuffer(input);
2133
ret->allocs |= XML_TEXTREADER_INPUT;
2134
if (ret->ctxt->directory == NULL)
2135
directory = xmlParserGetDirectory(URI);
2136
if ((ret->ctxt->directory == NULL) && (directory != NULL))
2137
ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
2138
if (directory != NULL)
2144
* xmlFreeTextReader:
2145
* @reader: the xmlTextReaderPtr
2147
* Deallocate all the resources associated to the reader
2150
xmlFreeTextReader(xmlTextReaderPtr reader) {
2153
#ifdef LIBXML_SCHEMAS_ENABLED
2154
if (reader->rngSchemas != NULL) {
2155
xmlRelaxNGFree(reader->rngSchemas);
2156
reader->rngSchemas = NULL;
2158
if (reader->rngValidCtxt != NULL) {
2159
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
2160
reader->rngValidCtxt = NULL;
2162
if (reader->xsdPlug != NULL) {
2163
xmlSchemaSAXUnplug(reader->xsdPlug);
2164
reader->xsdPlug = NULL;
2166
if (reader->xsdValidCtxt != NULL) {
2167
if (! reader->xsdPreserveCtxt)
2168
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
2169
reader->xsdValidCtxt = NULL;
2171
if (reader->xsdSchemas != NULL) {
2172
xmlSchemaFree(reader->xsdSchemas);
2173
reader->xsdSchemas = NULL;
2176
#ifdef LIBXML_XINCLUDE_ENABLED
2177
if (reader->xincctxt != NULL)
2178
xmlXIncludeFreeContext(reader->xincctxt);
2180
#ifdef LIBXML_PATTERN_ENABLED
2181
if (reader->patternTab != NULL) {
2183
for (i = 0;i < reader->patternNr;i++) {
2184
if (reader->patternTab[i] != NULL)
2185
xmlFreePattern(reader->patternTab[i]);
2187
xmlFree(reader->patternTab);
2190
if (reader->ctxt != NULL) {
2191
if (reader->dict == reader->ctxt->dict)
2192
reader->dict = NULL;
2193
if (reader->ctxt->myDoc != NULL) {
2194
if (reader->preserve == 0)
2195
xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
2196
reader->ctxt->myDoc = NULL;
2198
if ((reader->ctxt->vctxt.vstateTab != NULL) &&
2199
(reader->ctxt->vctxt.vstateMax > 0)){
2200
xmlFree(reader->ctxt->vctxt.vstateTab);
2201
reader->ctxt->vctxt.vstateTab = NULL;
2202
reader->ctxt->vctxt.vstateMax = 0;
2204
if (reader->allocs & XML_TEXTREADER_CTXT)
2205
xmlFreeParserCtxt(reader->ctxt);
2207
if (reader->sax != NULL)
2208
xmlFree(reader->sax);
2209
if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT))
2210
xmlFreeParserInputBuffer(reader->input);
2211
if (reader->faketext != NULL) {
2212
xmlFreeNode(reader->faketext);
2214
if (reader->buffer != NULL)
2215
xmlBufferFree(reader->buffer);
2216
if (reader->entTab != NULL)
2217
xmlFree(reader->entTab);
2218
if (reader->dict != NULL)
2219
xmlDictFree(reader->dict);
2223
/************************************************************************
2225
* Methods for XmlTextReader *
2227
************************************************************************/
2229
* xmlTextReaderClose:
2230
* @reader: the xmlTextReaderPtr used
2232
* This method releases any resources allocated by the current instance
2233
* changes the state to Closed and close any underlying input.
2235
* Returns 0 or -1 in case of error
2238
xmlTextReaderClose(xmlTextReaderPtr reader) {
2241
reader->node = NULL;
2242
reader->curnode = NULL;
2243
reader->mode = XML_TEXTREADER_MODE_CLOSED;
2244
if (reader->ctxt != NULL) {
2245
xmlStopParser(reader->ctxt);
2246
if (reader->ctxt->myDoc != NULL) {
2247
if (reader->preserve == 0)
2248
xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
2249
reader->ctxt->myDoc = NULL;
2252
if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT)) {
2253
xmlFreeParserInputBuffer(reader->input);
2254
reader->allocs -= XML_TEXTREADER_INPUT;
2260
* xmlTextReaderGetAttributeNo:
2261
* @reader: the xmlTextReaderPtr used
2262
* @no: the zero-based index of the attribute relative to the containing element
2264
* Provides the value of the attribute with the specified index relative
2265
* to the containing element.
2267
* Returns a string containing the value of the specified attribute, or NULL
2268
* in case of error. The string must be deallocated by the caller.
2271
xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
2279
if (reader->node == NULL)
2281
if (reader->curnode != NULL)
2283
/* TODO: handle the xmlDecl */
2284
if (reader->node->type != XML_ELEMENT_NODE)
2287
ns = reader->node->nsDef;
2288
for (i = 0;(i < no) && (ns != NULL);i++) {
2292
return(xmlStrdup(ns->href));
2294
cur = reader->node->properties;
2302
/* TODO walk the DTD if present */
2304
ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
2305
if (ret == NULL) return(xmlStrdup((xmlChar *)""));
2310
* xmlTextReaderGetAttribute:
2311
* @reader: the xmlTextReaderPtr used
2312
* @name: the qualified name of the attribute.
2314
* Provides the value of the attribute with the specified qualified name.
2316
* Returns a string containing the value of the specified attribute, or NULL
2317
* in case of error. The string must be deallocated by the caller.
2320
xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
2321
xmlChar *prefix = NULL;
2324
xmlChar *ret = NULL;
2326
if ((reader == NULL) || (name == NULL))
2328
if (reader->node == NULL)
2330
if (reader->curnode != NULL)
2333
/* TODO: handle the xmlDecl */
2334
if (reader->node->type != XML_ELEMENT_NODE)
2337
localname = xmlSplitQName2(name, &prefix);
2338
if (localname == NULL) {
2340
* Namespace default decl
2342
if (xmlStrEqual(name, BAD_CAST "xmlns")) {
2343
ns = reader->node->nsDef;
2344
while (ns != NULL) {
2345
if (ns->prefix == NULL) {
2346
return(xmlStrdup(ns->href));
2352
return(xmlGetNoNsProp(reader->node, name));
2356
* Namespace default decl
2358
if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
2359
ns = reader->node->nsDef;
2360
while (ns != NULL) {
2361
if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
2362
ret = xmlStrdup(ns->href);
2368
ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
2370
ret = xmlGetNsProp(reader->node, localname, ns->href);
2381
* xmlTextReaderGetAttributeNs:
2382
* @reader: the xmlTextReaderPtr used
2383
* @localName: the local name of the attribute.
2384
* @namespaceURI: the namespace URI of the attribute.
2386
* Provides the value of the specified attribute
2388
* Returns a string containing the value of the specified attribute, or NULL
2389
* in case of error. The string must be deallocated by the caller.
2392
xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,
2393
const xmlChar *namespaceURI) {
2394
xmlChar *prefix = NULL;
2397
if ((reader == NULL) || (localName == NULL))
2399
if (reader->node == NULL)
2401
if (reader->curnode != NULL)
2404
/* TODO: handle the xmlDecl */
2405
if (reader->node->type != XML_ELEMENT_NODE)
2408
if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
2409
if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
2410
prefix = BAD_CAST localName;
2412
ns = reader->node->nsDef;
2413
while (ns != NULL) {
2414
if ((prefix == NULL && ns->prefix == NULL) ||
2415
((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
2416
return xmlStrdup(ns->href);
2423
return(xmlGetNsProp(reader->node, localName, namespaceURI));
2427
* xmlTextReaderGetRemainder:
2428
* @reader: the xmlTextReaderPtr used
2430
* Method to get the remainder of the buffered XML. this method stops the
2431
* parser, set its state to End Of File and return the input stream with
2432
* what is left that the parser did not use.
2434
* The implementation is not good, the parser certainly procgressed past
2435
* what's left in reader->input, and there is an allocation problem. Best
2436
* would be to rewrite it differently.
2438
* Returns the xmlParserInputBufferPtr attached to the XML or NULL
2441
xmlParserInputBufferPtr
2442
xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
2443
xmlParserInputBufferPtr ret = NULL;
2447
if (reader->node == NULL)
2450
reader->node = NULL;
2451
reader->curnode = NULL;
2452
reader->mode = XML_TEXTREADER_MODE_EOF;
2453
if (reader->ctxt != NULL) {
2454
xmlStopParser(reader->ctxt);
2455
if (reader->ctxt->myDoc != NULL) {
2456
if (reader->preserve == 0)
2457
xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
2458
reader->ctxt->myDoc = NULL;
2461
if (reader->allocs & XML_TEXTREADER_INPUT) {
2462
ret = reader->input;
2463
reader->input = NULL;
2464
reader->allocs -= XML_TEXTREADER_INPUT;
2467
* Hum, one may need to duplicate the data structure because
2468
* without reference counting the input may be freed twice:
2469
* - by the layer which allocated it.
2470
* - by the layer to which would have been returned to.
2479
* xmlTextReaderLookupNamespace:
2480
* @reader: the xmlTextReaderPtr used
2481
* @prefix: the prefix whose namespace URI is to be resolved. To return
2482
* the default namespace, specify NULL
2484
* Resolves a namespace prefix in the scope of the current element.
2486
* Returns a string containing the namespace URI to which the prefix maps
2487
* or NULL in case of error. The string must be deallocated by the caller.
2490
xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
2495
if (reader->node == NULL)
2498
ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
2501
return(xmlStrdup(ns->href));
2505
* xmlTextReaderMoveToAttributeNo:
2506
* @reader: the xmlTextReaderPtr used
2507
* @no: the zero-based index of the attribute relative to the containing
2510
* Moves the position of the current instance to the attribute with
2511
* the specified index relative to the containing element.
2513
* Returns 1 in case of success, -1 in case of error, 0 if not found
2516
xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
2523
if (reader->node == NULL)
2525
/* TODO: handle the xmlDecl */
2526
if (reader->node->type != XML_ELEMENT_NODE)
2529
reader->curnode = NULL;
2531
ns = reader->node->nsDef;
2532
for (i = 0;(i < no) && (ns != NULL);i++) {
2536
reader->curnode = (xmlNodePtr) ns;
2540
cur = reader->node->properties;
2548
/* TODO walk the DTD if present */
2550
reader->curnode = (xmlNodePtr) cur;
2555
* xmlTextReaderMoveToAttribute:
2556
* @reader: the xmlTextReaderPtr used
2557
* @name: the qualified name of the attribute.
2559
* Moves the position of the current instance to the attribute with
2560
* the specified qualified name.
2562
* Returns 1 in case of success, -1 in case of error, 0 if not found
2565
xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
2566
xmlChar *prefix = NULL;
2571
if ((reader == NULL) || (name == NULL))
2573
if (reader->node == NULL)
2576
/* TODO: handle the xmlDecl */
2577
if (reader->node->type != XML_ELEMENT_NODE)
2580
localname = xmlSplitQName2(name, &prefix);
2581
if (localname == NULL) {
2583
* Namespace default decl
2585
if (xmlStrEqual(name, BAD_CAST "xmlns")) {
2586
ns = reader->node->nsDef;
2587
while (ns != NULL) {
2588
if (ns->prefix == NULL) {
2589
reader->curnode = (xmlNodePtr) ns;
2597
prop = reader->node->properties;
2598
while (prop != NULL) {
2601
* - same attribute names
2602
* - and the attribute carrying that namespace
2604
if ((xmlStrEqual(prop->name, name)) &&
2605
((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
2606
reader->curnode = (xmlNodePtr) prop;
2615
* Namespace default decl
2617
if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
2618
ns = reader->node->nsDef;
2619
while (ns != NULL) {
2620
if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
2621
reader->curnode = (xmlNodePtr) ns;
2628
prop = reader->node->properties;
2629
while (prop != NULL) {
2632
* - same attribute names
2633
* - and the attribute carrying that namespace
2635
if ((xmlStrEqual(prop->name, localname)) &&
2636
(prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
2637
reader->curnode = (xmlNodePtr) prop;
2643
if (localname != NULL)
2650
if (localname != NULL)
2658
* xmlTextReaderMoveToAttributeNs:
2659
* @reader: the xmlTextReaderPtr used
2660
* @localName: the local name of the attribute.
2661
* @namespaceURI: the namespace URI of the attribute.
2663
* Moves the position of the current instance to the attribute with the
2664
* specified local name and namespace URI.
2666
* Returns 1 in case of success, -1 in case of error, 0 if not found
2669
xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
2670
const xmlChar *localName, const xmlChar *namespaceURI) {
2674
xmlChar *prefix = NULL;
2676
if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
2678
if (reader->node == NULL)
2680
if (reader->node->type != XML_ELEMENT_NODE)
2682
node = reader->node;
2684
if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
2685
if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
2686
prefix = BAD_CAST localName;
2688
ns = reader->node->nsDef;
2689
while (ns != NULL) {
2690
if ((prefix == NULL && ns->prefix == NULL) ||
2691
((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
2692
reader->curnode = (xmlNodePtr) ns;
2700
prop = node->properties;
2701
while (prop != NULL) {
2704
* - same attribute names
2705
* - and the attribute carrying that namespace
2707
if (xmlStrEqual(prop->name, localName) &&
2708
((prop->ns != NULL) &&
2709
(xmlStrEqual(prop->ns->href, namespaceURI)))) {
2710
reader->curnode = (xmlNodePtr) prop;
2719
* xmlTextReaderMoveToFirstAttribute:
2720
* @reader: the xmlTextReaderPtr used
2722
* Moves the position of the current instance to the first attribute
2723
* associated with the current node.
2725
* Returns 1 in case of success, -1 in case of error, 0 if not found
2728
xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
2731
if (reader->node == NULL)
2733
if (reader->node->type != XML_ELEMENT_NODE)
2736
if (reader->node->nsDef != NULL) {
2737
reader->curnode = (xmlNodePtr) reader->node->nsDef;
2740
if (reader->node->properties != NULL) {
2741
reader->curnode = (xmlNodePtr) reader->node->properties;
2748
* xmlTextReaderMoveToNextAttribute:
2749
* @reader: the xmlTextReaderPtr used
2751
* Moves the position of the current instance to the next attribute
2752
* associated with the current node.
2754
* Returns 1 in case of success, -1 in case of error, 0 if not found
2757
xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
2760
if (reader->node == NULL)
2762
if (reader->node->type != XML_ELEMENT_NODE)
2764
if (reader->curnode == NULL)
2765
return(xmlTextReaderMoveToFirstAttribute(reader));
2767
if (reader->curnode->type == XML_NAMESPACE_DECL) {
2768
xmlNsPtr ns = (xmlNsPtr) reader->curnode;
2769
if (ns->next != NULL) {
2770
reader->curnode = (xmlNodePtr) ns->next;
2773
if (reader->node->properties != NULL) {
2774
reader->curnode = (xmlNodePtr) reader->node->properties;
2778
} else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
2779
(reader->curnode->next != NULL)) {
2780
reader->curnode = reader->curnode->next;
2787
* xmlTextReaderMoveToElement:
2788
* @reader: the xmlTextReaderPtr used
2790
* Moves the position of the current instance to the node that
2791
* contains the current Attribute node.
2793
* Returns 1 in case of success, -1 in case of error, 0 if not moved
2796
xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
2799
if (reader->node == NULL)
2801
if (reader->node->type != XML_ELEMENT_NODE)
2803
if (reader->curnode != NULL) {
2804
reader->curnode = NULL;
2811
* xmlTextReaderReadAttributeValue:
2812
* @reader: the xmlTextReaderPtr used
2814
* Parses an attribute value into one or more Text and EntityReference nodes.
2816
* Returns 1 in case of success, 0 if the reader was not positionned on an
2817
* ttribute node or all the attribute values have been read, or -1
2821
xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) {
2824
if (reader->node == NULL)
2826
if (reader->curnode == NULL)
2828
if (reader->curnode->type == XML_ATTRIBUTE_NODE) {
2829
if (reader->curnode->children == NULL)
2831
reader->curnode = reader->curnode->children;
2832
} else if (reader->curnode->type == XML_NAMESPACE_DECL) {
2833
xmlNsPtr ns = (xmlNsPtr) reader->curnode;
2835
if (reader->faketext == NULL) {
2836
reader->faketext = xmlNewDocText(reader->node->doc,
2839
if ((reader->faketext->content != NULL) &&
2840
(reader->faketext->content !=
2841
(xmlChar *) &(reader->faketext->properties)))
2842
xmlFree(reader->faketext->content);
2843
reader->faketext->content = xmlStrdup(ns->href);
2845
reader->curnode = reader->faketext;
2847
if (reader->curnode->next == NULL)
2849
reader->curnode = reader->curnode->next;
2855
* xmlTextReaderConstEncoding:
2856
* @reader: the xmlTextReaderPtr used
2858
* Determine the encoding of the document being read.
2860
* Returns a string containing the encoding of the document or NULL in
2861
* case of error. The string is deallocated with the reader.
2864
xmlTextReaderConstEncoding(xmlTextReaderPtr reader) {
2865
xmlDocPtr doc = NULL;
2868
if (reader->doc != NULL)
2870
else if (reader->ctxt != NULL)
2871
doc = reader->ctxt->myDoc;
2875
if (doc->encoding == NULL)
2878
return(CONSTSTR(doc->encoding));
2882
/************************************************************************
2884
* Acces API to the current node *
2886
************************************************************************/
2888
* xmlTextReaderAttributeCount:
2889
* @reader: the xmlTextReaderPtr used
2891
* Provides the number of attributes of the current node
2893
* Returns 0 i no attributes, -1 in case of error or the attribute count
2896
xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
2904
if (reader->node == NULL)
2907
if (reader->curnode != NULL)
2908
node = reader->curnode;
2910
node = reader->node;
2912
if (node->type != XML_ELEMENT_NODE)
2914
if ((reader->state == XML_TEXTREADER_END) ||
2915
(reader->state == XML_TEXTREADER_BACKTRACK))
2918
attr = node->properties;
2919
while (attr != NULL) {
2924
while (ns != NULL) {
2932
* xmlTextReaderNodeType:
2933
* @reader: the xmlTextReaderPtr used
2935
* Get the node type of the current node
2937
* http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2939
* Returns the xmlNodeType of the current node or -1 in case of error
2942
xmlTextReaderNodeType(xmlTextReaderPtr reader) {
2947
if (reader->node == NULL)
2948
return(XML_READER_TYPE_NONE);
2949
if (reader->curnode != NULL)
2950
node = reader->curnode;
2952
node = reader->node;
2953
switch (node->type) {
2954
case XML_ELEMENT_NODE:
2955
if ((reader->state == XML_TEXTREADER_END) ||
2956
(reader->state == XML_TEXTREADER_BACKTRACK))
2957
return(XML_READER_TYPE_END_ELEMENT);
2958
return(XML_READER_TYPE_ELEMENT);
2959
case XML_NAMESPACE_DECL:
2960
case XML_ATTRIBUTE_NODE:
2961
return(XML_READER_TYPE_ATTRIBUTE);
2963
if (xmlIsBlankNode(reader->node)) {
2964
if (xmlNodeGetSpacePreserve(reader->node))
2965
return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
2967
return(XML_READER_TYPE_WHITESPACE);
2969
return(XML_READER_TYPE_TEXT);
2971
case XML_CDATA_SECTION_NODE:
2972
return(XML_READER_TYPE_CDATA);
2973
case XML_ENTITY_REF_NODE:
2974
return(XML_READER_TYPE_ENTITY_REFERENCE);
2975
case XML_ENTITY_NODE:
2976
return(XML_READER_TYPE_ENTITY);
2978
return(XML_READER_TYPE_PROCESSING_INSTRUCTION);
2979
case XML_COMMENT_NODE:
2980
return(XML_READER_TYPE_COMMENT);
2981
case XML_DOCUMENT_NODE:
2982
case XML_HTML_DOCUMENT_NODE:
2983
#ifdef LIBXML_DOCB_ENABLED
2984
case XML_DOCB_DOCUMENT_NODE:
2986
return(XML_READER_TYPE_DOCUMENT);
2987
case XML_DOCUMENT_FRAG_NODE:
2988
return(XML_READER_TYPE_DOCUMENT_FRAGMENT);
2989
case XML_NOTATION_NODE:
2990
return(XML_READER_TYPE_NOTATION);
2991
case XML_DOCUMENT_TYPE_NODE:
2993
return(XML_READER_TYPE_DOCUMENT_TYPE);
2995
case XML_ELEMENT_DECL:
2996
case XML_ATTRIBUTE_DECL:
2997
case XML_ENTITY_DECL:
2998
case XML_XINCLUDE_START:
2999
case XML_XINCLUDE_END:
3000
return(XML_READER_TYPE_NONE);
3006
* xmlTextReaderIsEmptyElement:
3007
* @reader: the xmlTextReaderPtr used
3009
* Check if the current node is empty
3011
* Returns 1 if empty, 0 if not and -1 in case of error
3014
xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
3015
if ((reader == NULL) || (reader->node == NULL))
3017
if (reader->node->type != XML_ELEMENT_NODE)
3019
if (reader->curnode != NULL)
3021
if (reader->node->children != NULL)
3023
if (reader->state == XML_TEXTREADER_END)
3025
if (reader->doc != NULL)
3027
#ifdef LIBXML_XINCLUDE_ENABLED
3028
if (reader->in_xinclude > 0)
3031
return((reader->node->extra & NODE_IS_EMPTY) != 0);
3035
* xmlTextReaderLocalName:
3036
* @reader: the xmlTextReaderPtr used
3038
* The local name of the node.
3040
* Returns the local name or NULL if not available
3043
xmlTextReaderLocalName(xmlTextReaderPtr reader) {
3045
if ((reader == NULL) || (reader->node == NULL))
3047
if (reader->curnode != NULL)
3048
node = reader->curnode;
3050
node = reader->node;
3051
if (node->type == XML_NAMESPACE_DECL) {
3052
xmlNsPtr ns = (xmlNsPtr) node;
3053
if (ns->prefix == NULL)
3054
return(xmlStrdup(BAD_CAST "xmlns"));
3056
return(xmlStrdup(ns->prefix));
3058
if ((node->type != XML_ELEMENT_NODE) &&
3059
(node->type != XML_ATTRIBUTE_NODE))
3060
return(xmlTextReaderName(reader));
3061
return(xmlStrdup(node->name));
3065
* xmlTextReaderConstLocalName:
3066
* @reader: the xmlTextReaderPtr used
3068
* The local name of the node.
3070
* Returns the local name or NULL if not available, the
3071
* string will be deallocated with the reader.
3074
xmlTextReaderConstLocalName(xmlTextReaderPtr reader) {
3076
if ((reader == NULL) || (reader->node == NULL))
3078
if (reader->curnode != NULL)
3079
node = reader->curnode;
3081
node = reader->node;
3082
if (node->type == XML_NAMESPACE_DECL) {
3083
xmlNsPtr ns = (xmlNsPtr) node;
3084
if (ns->prefix == NULL)
3085
return(CONSTSTR(BAD_CAST "xmlns"));
3089
if ((node->type != XML_ELEMENT_NODE) &&
3090
(node->type != XML_ATTRIBUTE_NODE))
3091
return(xmlTextReaderConstName(reader));
3096
* xmlTextReaderName:
3097
* @reader: the xmlTextReaderPtr used
3099
* The qualified name of the node, equal to Prefix :LocalName.
3101
* Returns the local name or NULL if not available
3104
xmlTextReaderName(xmlTextReaderPtr reader) {
3108
if ((reader == NULL) || (reader->node == NULL))
3110
if (reader->curnode != NULL)
3111
node = reader->curnode;
3113
node = reader->node;
3114
switch (node->type) {
3115
case XML_ELEMENT_NODE:
3116
case XML_ATTRIBUTE_NODE:
3117
if ((node->ns == NULL) ||
3118
(node->ns->prefix == NULL))
3119
return(xmlStrdup(node->name));
3121
ret = xmlStrdup(node->ns->prefix);
3122
ret = xmlStrcat(ret, BAD_CAST ":");
3123
ret = xmlStrcat(ret, node->name);
3126
return(xmlStrdup(BAD_CAST "#text"));
3127
case XML_CDATA_SECTION_NODE:
3128
return(xmlStrdup(BAD_CAST "#cdata-section"));
3129
case XML_ENTITY_NODE:
3130
case XML_ENTITY_REF_NODE:
3131
return(xmlStrdup(node->name));
3133
return(xmlStrdup(node->name));
3134
case XML_COMMENT_NODE:
3135
return(xmlStrdup(BAD_CAST "#comment"));
3136
case XML_DOCUMENT_NODE:
3137
case XML_HTML_DOCUMENT_NODE:
3138
#ifdef LIBXML_DOCB_ENABLED
3139
case XML_DOCB_DOCUMENT_NODE:
3141
return(xmlStrdup(BAD_CAST "#document"));
3142
case XML_DOCUMENT_FRAG_NODE:
3143
return(xmlStrdup(BAD_CAST "#document-fragment"));
3144
case XML_NOTATION_NODE:
3145
return(xmlStrdup(node->name));
3146
case XML_DOCUMENT_TYPE_NODE:
3148
return(xmlStrdup(node->name));
3149
case XML_NAMESPACE_DECL: {
3150
xmlNsPtr ns = (xmlNsPtr) node;
3152
ret = xmlStrdup(BAD_CAST "xmlns");
3153
if (ns->prefix == NULL)
3155
ret = xmlStrcat(ret, BAD_CAST ":");
3156
ret = xmlStrcat(ret, ns->prefix);
3160
case XML_ELEMENT_DECL:
3161
case XML_ATTRIBUTE_DECL:
3162
case XML_ENTITY_DECL:
3163
case XML_XINCLUDE_START:
3164
case XML_XINCLUDE_END:
3171
* xmlTextReaderConstName:
3172
* @reader: the xmlTextReaderPtr used
3174
* The qualified name of the node, equal to Prefix :LocalName.
3176
* Returns the local name or NULL if not available, the string is
3177
* deallocated with the reader.
3180
xmlTextReaderConstName(xmlTextReaderPtr reader) {
3183
if ((reader == NULL) || (reader->node == NULL))
3185
if (reader->curnode != NULL)
3186
node = reader->curnode;
3188
node = reader->node;
3189
switch (node->type) {
3190
case XML_ELEMENT_NODE:
3191
case XML_ATTRIBUTE_NODE:
3192
if ((node->ns == NULL) ||
3193
(node->ns->prefix == NULL))
3195
return(CONSTQSTR(node->ns->prefix, node->name));
3197
return(CONSTSTR(BAD_CAST "#text"));
3198
case XML_CDATA_SECTION_NODE:
3199
return(CONSTSTR(BAD_CAST "#cdata-section"));
3200
case XML_ENTITY_NODE:
3201
case XML_ENTITY_REF_NODE:
3202
return(CONSTSTR(node->name));
3204
return(CONSTSTR(node->name));
3205
case XML_COMMENT_NODE:
3206
return(CONSTSTR(BAD_CAST "#comment"));
3207
case XML_DOCUMENT_NODE:
3208
case XML_HTML_DOCUMENT_NODE:
3209
#ifdef LIBXML_DOCB_ENABLED
3210
case XML_DOCB_DOCUMENT_NODE:
3212
return(CONSTSTR(BAD_CAST "#document"));
3213
case XML_DOCUMENT_FRAG_NODE:
3214
return(CONSTSTR(BAD_CAST "#document-fragment"));
3215
case XML_NOTATION_NODE:
3216
return(CONSTSTR(node->name));
3217
case XML_DOCUMENT_TYPE_NODE:
3219
return(CONSTSTR(node->name));
3220
case XML_NAMESPACE_DECL: {
3221
xmlNsPtr ns = (xmlNsPtr) node;
3223
if (ns->prefix == NULL)
3224
return(CONSTSTR(BAD_CAST "xmlns"));
3225
return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));
3228
case XML_ELEMENT_DECL:
3229
case XML_ATTRIBUTE_DECL:
3230
case XML_ENTITY_DECL:
3231
case XML_XINCLUDE_START:
3232
case XML_XINCLUDE_END:
3239
* xmlTextReaderPrefix:
3240
* @reader: the xmlTextReaderPtr used
3242
* A shorthand reference to the namespace associated with the node.
3244
* Returns the prefix or NULL if not available
3247
xmlTextReaderPrefix(xmlTextReaderPtr reader) {
3249
if ((reader == NULL) || (reader->node == NULL))
3251
if (reader->curnode != NULL)
3252
node = reader->curnode;
3254
node = reader->node;
3255
if (node->type == XML_NAMESPACE_DECL) {
3256
xmlNsPtr ns = (xmlNsPtr) node;
3257
if (ns->prefix == NULL)
3259
return(xmlStrdup(BAD_CAST "xmlns"));
3261
if ((node->type != XML_ELEMENT_NODE) &&
3262
(node->type != XML_ATTRIBUTE_NODE))
3264
if ((node->ns != NULL) && (node->ns->prefix != NULL))
3265
return(xmlStrdup(node->ns->prefix));
3270
* xmlTextReaderConstPrefix:
3271
* @reader: the xmlTextReaderPtr used
3273
* A shorthand reference to the namespace associated with the node.
3275
* Returns the prefix or NULL if not available, the string is deallocated
3279
xmlTextReaderConstPrefix(xmlTextReaderPtr reader) {
3281
if ((reader == NULL) || (reader->node == NULL))
3283
if (reader->curnode != NULL)
3284
node = reader->curnode;
3286
node = reader->node;
3287
if (node->type == XML_NAMESPACE_DECL) {
3288
xmlNsPtr ns = (xmlNsPtr) node;
3289
if (ns->prefix == NULL)
3291
return(CONSTSTR(BAD_CAST "xmlns"));
3293
if ((node->type != XML_ELEMENT_NODE) &&
3294
(node->type != XML_ATTRIBUTE_NODE))
3296
if ((node->ns != NULL) && (node->ns->prefix != NULL))
3297
return(CONSTSTR(node->ns->prefix));
3302
* xmlTextReaderNamespaceUri:
3303
* @reader: the xmlTextReaderPtr used
3305
* The URI defining the namespace associated with the node.
3307
* Returns the namespace URI or NULL if not available
3310
xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
3312
if ((reader == NULL) || (reader->node == NULL))
3314
if (reader->curnode != NULL)
3315
node = reader->curnode;
3317
node = reader->node;
3318
if (node->type == XML_NAMESPACE_DECL)
3319
return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));
3320
if ((node->type != XML_ELEMENT_NODE) &&
3321
(node->type != XML_ATTRIBUTE_NODE))
3323
if (node->ns != NULL)
3324
return(xmlStrdup(node->ns->href));
3329
* xmlTextReaderConstNamespaceUri:
3330
* @reader: the xmlTextReaderPtr used
3332
* The URI defining the namespace associated with the node.
3334
* Returns the namespace URI or NULL if not available, the string
3335
* will be deallocated with the reader
3338
xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) {
3340
if ((reader == NULL) || (reader->node == NULL))
3342
if (reader->curnode != NULL)
3343
node = reader->curnode;
3345
node = reader->node;
3346
if (node->type == XML_NAMESPACE_DECL)
3347
return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));
3348
if ((node->type != XML_ELEMENT_NODE) &&
3349
(node->type != XML_ATTRIBUTE_NODE))
3351
if (node->ns != NULL)
3352
return(CONSTSTR(node->ns->href));
3357
* xmlTextReaderBaseUri:
3358
* @reader: the xmlTextReaderPtr used
3360
* The base URI of the node.
3362
* Returns the base URI or NULL if not available
3365
xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
3366
if ((reader == NULL) || (reader->node == NULL))
3368
return(xmlNodeGetBase(NULL, reader->node));
3372
* xmlTextReaderConstBaseUri:
3373
* @reader: the xmlTextReaderPtr used
3375
* The base URI of the node.
3377
* Returns the base URI or NULL if not available, the string
3378
* will be deallocated with the reader
3381
xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) {
3385
if ((reader == NULL) || (reader->node == NULL))
3387
tmp = xmlNodeGetBase(NULL, reader->node);
3390
ret = CONSTSTR(tmp);
3396
* xmlTextReaderDepth:
3397
* @reader: the xmlTextReaderPtr used
3399
* The depth of the node in the tree.
3401
* Returns the depth or -1 in case of error
3404
xmlTextReaderDepth(xmlTextReaderPtr reader) {
3407
if (reader->node == NULL)
3410
if (reader->curnode != NULL) {
3411
if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||
3412
(reader->curnode->type == XML_NAMESPACE_DECL))
3413
return(reader->depth + 1);
3414
return(reader->depth + 2);
3416
return(reader->depth);
3420
* xmlTextReaderHasAttributes:
3421
* @reader: the xmlTextReaderPtr used
3423
* Whether the node has attributes.
3425
* Returns 1 if true, 0 if false, and -1 in case or error
3428
xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
3432
if (reader->node == NULL)
3434
if (reader->curnode != NULL)
3435
node = reader->curnode;
3437
node = reader->node;
3439
if ((node->type == XML_ELEMENT_NODE) &&
3440
((node->properties != NULL) || (node->nsDef != NULL)))
3442
/* TODO: handle the xmlDecl */
3447
* xmlTextReaderHasValue:
3448
* @reader: the xmlTextReaderPtr used
3450
* Whether the node can have a text value.
3452
* Returns 1 if true, 0 if false, and -1 in case or error
3455
xmlTextReaderHasValue(xmlTextReaderPtr reader) {
3459
if (reader->node == NULL)
3461
if (reader->curnode != NULL)
3462
node = reader->curnode;
3464
node = reader->node;
3466
switch (node->type) {
3467
case XML_ATTRIBUTE_NODE:
3469
case XML_CDATA_SECTION_NODE:
3471
case XML_COMMENT_NODE:
3472
case XML_NAMESPACE_DECL:
3481
* xmlTextReaderValue:
3482
* @reader: the xmlTextReaderPtr used
3484
* Provides the text value of the node if present
3486
* Returns the string or NULL if not available. The result must be deallocated
3490
xmlTextReaderValue(xmlTextReaderPtr reader) {
3494
if (reader->node == NULL)
3496
if (reader->curnode != NULL)
3497
node = reader->curnode;
3499
node = reader->node;
3501
switch (node->type) {
3502
case XML_NAMESPACE_DECL:
3503
return(xmlStrdup(((xmlNsPtr) node)->href));
3504
case XML_ATTRIBUTE_NODE:{
3505
xmlAttrPtr attr = (xmlAttrPtr) node;
3507
if (attr->parent != NULL)
3508
return (xmlNodeListGetString
3509
(attr->parent->doc, attr->children, 1));
3511
return (xmlNodeListGetString(NULL, attr->children, 1));
3515
case XML_CDATA_SECTION_NODE:
3517
case XML_COMMENT_NODE:
3518
if (node->content != NULL)
3519
return (xmlStrdup(node->content));
3527
* xmlTextReaderConstValue:
3528
* @reader: the xmlTextReaderPtr used
3530
* Provides the text value of the node if present
3532
* Returns the string or NULL if not available. The result will be
3533
* deallocated on the next Read() operation.
3536
xmlTextReaderConstValue(xmlTextReaderPtr reader) {
3540
if (reader->node == NULL)
3542
if (reader->curnode != NULL)
3543
node = reader->curnode;
3545
node = reader->node;
3547
switch (node->type) {
3548
case XML_NAMESPACE_DECL:
3549
return(((xmlNsPtr) node)->href);
3550
case XML_ATTRIBUTE_NODE:{
3551
xmlAttrPtr attr = (xmlAttrPtr) node;
3553
if ((attr->children != NULL) &&
3554
(attr->children->type == XML_TEXT_NODE) &&
3555
(attr->children->next == NULL))
3556
return(attr->children->content);
3558
if (reader->buffer == NULL)
3559
reader->buffer = xmlBufferCreateSize(100);
3560
if (reader->buffer == NULL) {
3561
xmlGenericError(xmlGenericErrorContext,
3562
"xmlTextReaderSetup : malloc failed\n");
3565
reader->buffer->use = 0;
3566
xmlNodeBufGetContent(reader->buffer, node);
3567
return(reader->buffer->content);
3572
case XML_CDATA_SECTION_NODE:
3574
case XML_COMMENT_NODE:
3575
return(node->content);
3583
* xmlTextReaderIsDefault:
3584
* @reader: the xmlTextReaderPtr used
3586
* Whether an Attribute node was generated from the default value
3587
* defined in the DTD or schema.
3589
* Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3592
xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
3599
* xmlTextReaderQuoteChar:
3600
* @reader: the xmlTextReaderPtr used
3602
* The quotation mark character used to enclose the value of an attribute.
3604
* Returns " or ' and -1 in case of error
3607
xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
3610
/* TODO maybe lookup the attribute value for " first */
3615
* xmlTextReaderXmlLang:
3616
* @reader: the xmlTextReaderPtr used
3618
* The xml:lang scope within which the node resides.
3620
* Returns the xml:lang value or NULL if none exists.
3623
xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
3626
if (reader->node == NULL)
3628
return(xmlNodeGetLang(reader->node));
3632
* xmlTextReaderConstXmlLang:
3633
* @reader: the xmlTextReaderPtr used
3635
* The xml:lang scope within which the node resides.
3637
* Returns the xml:lang value or NULL if none exists.
3640
xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) {
3646
if (reader->node == NULL)
3648
tmp = xmlNodeGetLang(reader->node);
3651
ret = CONSTSTR(tmp);
3657
* xmlTextReaderConstString:
3658
* @reader: the xmlTextReaderPtr used
3659
* @str: the string to intern.
3661
* Get an interned string from the reader, allows for example to
3662
* speedup string name comparisons
3664
* Returns an interned copy of the string or NULL in case of error. The
3665
* string will be deallocated with the reader.
3668
xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) {
3671
return(CONSTSTR(str));
3675
* xmlTextReaderNormalization:
3676
* @reader: the xmlTextReaderPtr used
3678
* The value indicating whether to normalize white space and attribute values.
3679
* Since attribute value and end of line normalizations are a MUST in the XML
3680
* specification only the value true is accepted. The broken bahaviour of
3681
* accepting out of range character entities like � is of course not
3684
* Returns 1 or -1 in case of error.
3687
xmlTextReaderNormalization(xmlTextReaderPtr reader) {
3693
/************************************************************************
3695
* Extensions to the base APIs *
3697
************************************************************************/
3700
* xmlTextReaderSetParserProp:
3701
* @reader: the xmlTextReaderPtr used
3702
* @prop: the xmlParserProperties to set
3703
* @value: usually 0 or 1 to (de)activate it
3705
* Change the parser processing behaviour by changing some of its internal
3706
* properties. Note that some properties can only be changed before any
3707
* read has been done.
3709
* Returns 0 if the call was successful, or -1 in case of error
3712
xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) {
3713
xmlParserProperties p = (xmlParserProperties) prop;
3714
xmlParserCtxtPtr ctxt;
3716
if ((reader == NULL) || (reader->ctxt == NULL))
3718
ctxt = reader->ctxt;
3721
case XML_PARSER_LOADDTD:
3723
if (ctxt->loadsubset == 0) {
3724
if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
3726
ctxt->loadsubset = XML_DETECT_IDS;
3729
ctxt->loadsubset = 0;
3732
case XML_PARSER_DEFAULTATTRS:
3734
ctxt->loadsubset |= XML_COMPLETE_ATTRS;
3736
if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
3737
ctxt->loadsubset -= XML_COMPLETE_ATTRS;
3740
case XML_PARSER_VALIDATE:
3743
reader->validate = XML_TEXTREADER_VALIDATE_DTD;
3748
case XML_PARSER_SUBST_ENTITIES:
3750
ctxt->replaceEntities = 1;
3752
ctxt->replaceEntities = 0;
3760
* xmlTextReaderGetParserProp:
3761
* @reader: the xmlTextReaderPtr used
3762
* @prop: the xmlParserProperties to get
3764
* Read the parser internal property.
3766
* Returns the value, usually 0 or 1, or -1 in case of error.
3769
xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) {
3770
xmlParserProperties p = (xmlParserProperties) prop;
3771
xmlParserCtxtPtr ctxt;
3773
if ((reader == NULL) || (reader->ctxt == NULL))
3775
ctxt = reader->ctxt;
3778
case XML_PARSER_LOADDTD:
3779
if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))
3782
case XML_PARSER_DEFAULTATTRS:
3783
if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
3786
case XML_PARSER_VALIDATE:
3787
return(reader->validate);
3788
case XML_PARSER_SUBST_ENTITIES:
3789
return(ctxt->replaceEntities);
3796
* xmlTextReaderGetParserLineNumber:
3797
* @reader: the user data (XML reader context)
3799
* Provide the line number of the current parsing point.
3801
* Returns an int or 0 if not available
3804
xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)
3806
if ((reader == NULL) || (reader->ctxt == NULL) ||
3807
(reader->ctxt->input == NULL)) {
3810
return (reader->ctxt->input->line);
3814
* xmlTextReaderGetParserColumnNumber:
3815
* @reader: the user data (XML reader context)
3817
* Provide the column number of the current parsing point.
3819
* Returns an int or 0 if not available
3822
xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)
3824
if ((reader == NULL) || (reader->ctxt == NULL) ||
3825
(reader->ctxt->input == NULL)) {
3828
return (reader->ctxt->input->col);
3832
* xmlTextReaderCurrentNode:
3833
* @reader: the xmlTextReaderPtr used
3835
* Hacking interface allowing to get the xmlNodePtr correponding to the
3836
* current node being accessed by the xmlTextReader. This is dangerous
3837
* because the underlying node may be destroyed on the next Reads.
3839
* Returns the xmlNodePtr or NULL in case of error.
3842
xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
3846
if (reader->curnode != NULL)
3847
return(reader->curnode);
3848
return(reader->node);
3852
* xmlTextReaderPreserve:
3853
* @reader: the xmlTextReaderPtr used
3855
* This tells the XML Reader to preserve the current node.
3856
* The caller must also use xmlTextReaderCurrentDoc() to
3857
* keep an handle on the resulting document once parsing has finished
3859
* Returns the xmlNodePtr or NULL in case of error.
3862
xmlTextReaderPreserve(xmlTextReaderPtr reader) {
3863
xmlNodePtr cur, parent;
3868
if (reader->curnode != NULL)
3869
cur = reader->curnode;
3875
if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
3876
cur->extra |= NODE_IS_PRESERVED;
3877
cur->extra |= NODE_IS_SPRESERVED;
3879
reader->preserves++;
3881
parent = cur->parent;;
3882
while (parent != NULL) {
3883
if (parent->type == XML_ELEMENT_NODE)
3884
parent->extra |= NODE_IS_PRESERVED;
3885
parent = parent->parent;
3890
#ifdef LIBXML_PATTERN_ENABLED
3892
* xmlTextReaderPreservePattern:
3893
* @reader: the xmlTextReaderPtr used
3894
* @pattern: an XPath subset pattern
3895
* @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3897
* This tells the XML Reader to preserve all nodes matched by the
3898
* pattern. The caller must also use xmlTextReaderCurrentDoc() to
3899
* keep an handle on the resulting document once parsing has finished
3901
* Returns a positive number in case of success and -1 in case of error
3904
xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
3905
const xmlChar **namespaces)
3909
if ((reader == NULL) || (pattern == NULL))
3912
comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
3916
if (reader->patternMax <= 0) {
3917
reader->patternMax = 4;
3918
reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
3919
sizeof(reader->patternTab[0]));
3920
if (reader->patternTab == NULL) {
3921
xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
3925
if (reader->patternNr >= reader->patternMax) {
3927
reader->patternMax *= 2;
3928
tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
3929
reader->patternMax *
3930
sizeof(reader->patternTab[0]));
3932
xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
3933
reader->patternMax /= 2;
3936
reader->patternTab = tmp;
3938
reader->patternTab[reader->patternNr] = comp;
3939
return(reader->patternNr++);
3944
* xmlTextReaderCurrentDoc:
3945
* @reader: the xmlTextReaderPtr used
3947
* Hacking interface allowing to get the xmlDocPtr correponding to the
3948
* current document being accessed by the xmlTextReader.
3949
* NOTE: as a result of this call, the reader will not destroy the
3950
* associated XML document and calling xmlFreeDoc() on the result
3951
* is needed once the reader parsing has finished.
3953
* Returns the xmlDocPtr or NULL in case of error.
3956
xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) {
3959
if (reader->doc != NULL)
3960
return(reader->doc);
3961
if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
3964
reader->preserve = 1;
3965
return(reader->ctxt->myDoc);
3968
#ifdef LIBXML_SCHEMAS_ENABLED
3971
xmlTextReaderBuildMessage(const char *msg, va_list ap);
3973
static void XMLCDECL
3974
xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
3976
static void XMLCDECL
3977
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
3979
static void XMLCDECL xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
3981
xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
3986
str = xmlTextReaderBuildMessage(msg,ap);
3987
if (!reader->errorFunc) {
3988
xmlTextReaderValidityError(ctx, "%s", str);
3990
reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_ERROR, NULL /* locator */);
3997
static void XMLCDECL xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
3999
xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
4004
str = xmlTextReaderBuildMessage(msg,ap);
4005
if (!reader->errorFunc) {
4006
xmlTextReaderValidityWarning(ctx, "%s", str);
4008
reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_WARNING, NULL /* locator */);
4016
xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
4018
static void xmlTextReaderValidityStructuredRelay(void * userData, xmlErrorPtr error)
4020
xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
4022
if (reader->sErrorFunc) {
4023
reader->sErrorFunc(reader->errorFuncArg, error);
4025
xmlTextReaderStructuredError(reader, error);
4030
* xmlTextReaderRelaxNGSetSchema:
4031
* @reader: the xmlTextReaderPtr used
4032
* @schema: a precompiled RelaxNG schema
4034
* Use RelaxNG to validate the document as it is processed.
4035
* Activation is only possible before the first Read().
4036
* if @schema is NULL, then RelaxNG validation is desactivated.
4037
@ The @schema should not be freed until the reader is deallocated
4038
* or its use has been deactivated.
4040
* Returns 0 in case the RelaxNG validation could be (des)activated and
4041
* -1 in case of error.
4044
xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
4047
if (schema == NULL) {
4048
if (reader->rngSchemas != NULL) {
4049
xmlRelaxNGFree(reader->rngSchemas);
4050
reader->rngSchemas = NULL;
4052
if (reader->rngValidCtxt != NULL) {
4053
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
4054
reader->rngValidCtxt = NULL;
4058
if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
4060
if (reader->rngSchemas != NULL) {
4061
xmlRelaxNGFree(reader->rngSchemas);
4062
reader->rngSchemas = NULL;
4064
if (reader->rngValidCtxt != NULL) {
4065
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
4066
reader->rngValidCtxt = NULL;
4068
reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
4069
if (reader->rngValidCtxt == NULL)
4071
if (reader->errorFunc != NULL) {
4072
xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
4073
xmlTextReaderValidityErrorRelay,
4074
xmlTextReaderValidityWarningRelay,
4077
if (reader->sErrorFunc != NULL) {
4078
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
4079
xmlTextReaderValidityStructuredRelay,
4082
reader->rngValidErrors = 0;
4083
reader->rngFullNode = NULL;
4084
reader->validate = XML_TEXTREADER_VALIDATE_RNG;
4089
* xmlTextReaderSetSchema:
4090
* @reader: the xmlTextReaderPtr used
4091
* @schema: a precompiled Schema schema
4093
* Use XSD Schema to validate the document as it is processed.
4094
* Activation is only possible before the first Read().
4095
* if @schema is NULL, then Schema validation is desactivated.
4096
@ The @schema should not be freed until the reader is deallocated
4097
* or its use has been deactivated.
4099
* Returns 0 in case the Schema validation could be (des)activated and
4100
* -1 in case of error.
4103
xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
4106
if (schema == NULL) {
4107
if (reader->xsdPlug != NULL) {
4108
xmlSchemaSAXUnplug(reader->xsdPlug);
4109
reader->xsdPlug = NULL;
4111
if (reader->xsdValidCtxt != NULL) {
4112
if (! reader->xsdPreserveCtxt)
4113
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
4114
reader->xsdValidCtxt = NULL;
4116
reader->xsdPreserveCtxt = 0;
4117
if (reader->xsdSchemas != NULL) {
4118
xmlSchemaFree(reader->xsdSchemas);
4119
reader->xsdSchemas = NULL;
4123
if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
4125
if (reader->xsdPlug != NULL) {
4126
xmlSchemaSAXUnplug(reader->xsdPlug);
4127
reader->xsdPlug = NULL;
4129
if (reader->xsdValidCtxt != NULL) {
4130
if (! reader->xsdPreserveCtxt)
4131
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
4132
reader->xsdValidCtxt = NULL;
4134
reader->xsdPreserveCtxt = 0;
4135
if (reader->xsdSchemas != NULL) {
4136
xmlSchemaFree(reader->xsdSchemas);
4137
reader->xsdSchemas = NULL;
4139
reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);
4140
if (reader->xsdValidCtxt == NULL) {
4141
xmlSchemaFree(reader->xsdSchemas);
4142
reader->xsdSchemas = NULL;
4145
reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
4146
&(reader->ctxt->sax),
4147
&(reader->ctxt->userData));
4148
if (reader->xsdPlug == NULL) {
4149
xmlSchemaFree(reader->xsdSchemas);
4150
reader->xsdSchemas = NULL;
4151
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
4152
reader->xsdValidCtxt = NULL;
4155
if (reader->errorFunc != NULL) {
4156
xmlSchemaSetValidErrors(reader->xsdValidCtxt,
4157
xmlTextReaderValidityErrorRelay,
4158
xmlTextReaderValidityWarningRelay,
4161
if (reader->sErrorFunc != NULL) {
4162
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
4163
xmlTextReaderValidityStructuredRelay,
4166
reader->xsdValidErrors = 0;
4167
reader->validate = XML_TEXTREADER_VALIDATE_XSD;
4172
* xmlTextReaderRelaxNGValidate:
4173
* @reader: the xmlTextReaderPtr used
4174
* @rng: the path to a RelaxNG schema or NULL
4176
* Use RelaxNG to validate the document as it is processed.
4177
* Activation is only possible before the first Read().
4178
* if @rng is NULL, then RelaxNG validation is deactivated.
4180
* Returns 0 in case the RelaxNG validation could be (de)activated and
4181
* -1 in case of error.
4184
xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng) {
4185
xmlRelaxNGParserCtxtPtr ctxt;
4191
if (reader->rngValidCtxt != NULL) {
4192
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
4193
reader->rngValidCtxt = NULL;
4195
if (reader->rngSchemas != NULL) {
4196
xmlRelaxNGFree(reader->rngSchemas);
4197
reader->rngSchemas = NULL;
4201
if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
4203
if (reader->rngSchemas != NULL) {
4204
xmlRelaxNGFree(reader->rngSchemas);
4205
reader->rngSchemas = NULL;
4207
if (reader->rngValidCtxt != NULL) {
4208
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
4209
reader->rngValidCtxt = NULL;
4211
ctxt = xmlRelaxNGNewParserCtxt(rng);
4212
if (reader->errorFunc != NULL) {
4213
xmlRelaxNGSetParserErrors(ctxt,
4214
xmlTextReaderValidityErrorRelay,
4215
xmlTextReaderValidityWarningRelay,
4218
if (reader->sErrorFunc != NULL) {
4219
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
4220
xmlTextReaderValidityStructuredRelay,
4223
reader->rngSchemas = xmlRelaxNGParse(ctxt);
4224
xmlRelaxNGFreeParserCtxt(ctxt);
4225
if (reader->rngSchemas == NULL)
4227
reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
4228
if (reader->rngValidCtxt == NULL) {
4229
xmlRelaxNGFree(reader->rngSchemas);
4230
reader->rngSchemas = NULL;
4233
if (reader->errorFunc != NULL) {
4234
xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
4235
xmlTextReaderValidityErrorRelay,
4236
xmlTextReaderValidityWarningRelay,
4239
if (reader->sErrorFunc != NULL) {
4240
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
4241
xmlTextReaderValidityStructuredRelay,
4244
reader->rngValidErrors = 0;
4245
reader->rngFullNode = NULL;
4246
reader->validate = XML_TEXTREADER_VALIDATE_RNG;
4251
* xmlTextReaderSchemaValidateInternal:
4252
* @reader: the xmlTextReaderPtr used
4253
* @xsd: the path to a W3C XSD schema or NULL
4254
* @ctxt: the XML Schema validation context or NULL
4255
* @options: options (not used yet)
4257
* Validate the document as it is processed using XML Schema.
4258
* Activation is only possible before the first Read().
4259
* If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4261
* Returns 0 in case the schemas validation could be (de)activated and
4262
* -1 in case of error.
4265
xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
4267
xmlSchemaValidCtxtPtr ctxt,
4268
int options ATTRIBUTE_UNUSED)
4273
if ((xsd != NULL) && (ctxt != NULL))
4276
if (((xsd != NULL) || (ctxt != NULL)) &&
4277
((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
4278
(reader->ctxt == NULL)))
4281
/* Cleanup previous validation stuff. */
4282
if (reader->xsdPlug != NULL) {
4283
xmlSchemaSAXUnplug(reader->xsdPlug);
4284
reader->xsdPlug = NULL;
4286
if (reader->xsdValidCtxt != NULL) {
4287
if (! reader->xsdPreserveCtxt)
4288
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
4289
reader->xsdValidCtxt = NULL;
4291
reader->xsdPreserveCtxt = 0;
4292
if (reader->xsdSchemas != NULL) {
4293
xmlSchemaFree(reader->xsdSchemas);
4294
reader->xsdSchemas = NULL;
4297
if ((xsd == NULL) && (ctxt == NULL)) {
4298
/* We just want to deactivate the validation, so get out. */
4303
xmlSchemaParserCtxtPtr pctxt;
4304
/* Parse the schema and create validation environment. */
4305
pctxt = xmlSchemaNewParserCtxt(xsd);
4306
if (reader->errorFunc != NULL) {
4307
xmlSchemaSetParserErrors(pctxt,
4308
xmlTextReaderValidityErrorRelay,
4309
xmlTextReaderValidityWarningRelay,
4312
reader->xsdSchemas = xmlSchemaParse(pctxt);
4313
xmlSchemaFreeParserCtxt(pctxt);
4314
if (reader->xsdSchemas == NULL)
4316
reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);
4317
if (reader->xsdValidCtxt == NULL) {
4318
xmlSchemaFree(reader->xsdSchemas);
4319
reader->xsdSchemas = NULL;
4322
reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
4323
&(reader->ctxt->sax),
4324
&(reader->ctxt->userData));
4325
if (reader->xsdPlug == NULL) {
4326
xmlSchemaFree(reader->xsdSchemas);
4327
reader->xsdSchemas = NULL;
4328
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
4329
reader->xsdValidCtxt = NULL;
4333
/* Use the given validation context. */
4334
reader->xsdValidCtxt = ctxt;
4335
reader->xsdPreserveCtxt = 1;
4336
reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
4337
&(reader->ctxt->sax),
4338
&(reader->ctxt->userData));
4339
if (reader->xsdPlug == NULL) {
4340
reader->xsdValidCtxt = NULL;
4341
reader->xsdPreserveCtxt = 0;
4346
* Redirect the validation context's error channels to use
4347
* the reader channels.
4348
* TODO: In case the user provides the validation context we
4349
* could make this redirection optional.
4351
if (reader->errorFunc != NULL) {
4352
xmlSchemaSetValidErrors(reader->xsdValidCtxt,
4353
xmlTextReaderValidityErrorRelay,
4354
xmlTextReaderValidityWarningRelay,
4357
if (reader->sErrorFunc != NULL) {
4358
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
4359
xmlTextReaderValidityStructuredRelay,
4362
reader->xsdValidErrors = 0;
4363
reader->validate = XML_TEXTREADER_VALIDATE_XSD;
4368
* xmlTextReaderSchemaValidateCtxt:
4369
* @reader: the xmlTextReaderPtr used
4370
* @ctxt: the XML Schema validation context or NULL
4371
* @options: options (not used yet)
4373
* Use W3C XSD schema context to validate the document as it is processed.
4374
* Activation is only possible before the first Read().
4375
* If @ctxt is NULL, then XML Schema validation is deactivated.
4377
* Returns 0 in case the schemas validation could be (de)activated and
4378
* -1 in case of error.
4381
xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
4382
xmlSchemaValidCtxtPtr ctxt,
4385
return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));
4389
* xmlTextReaderSchemaValidate:
4390
* @reader: the xmlTextReaderPtr used
4391
* @xsd: the path to a W3C XSD schema or NULL
4393
* Use W3C XSD schema to validate the document as it is processed.
4394
* Activation is only possible before the first Read().
4395
* If @xsd is NULL, then XML Schema validation is deactivated.
4397
* Returns 0 in case the schemas validation could be (de)activated and
4398
* -1 in case of error.
4401
xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
4403
return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
4408
* xmlTextReaderIsNamespaceDecl:
4409
* @reader: the xmlTextReaderPtr used
4411
* Determine whether the current node is a namespace declaration
4412
* rather than a regular attribute.
4414
* Returns 1 if the current node is a namespace declaration, 0 if it
4415
* is a regular attribute or other type of node, or -1 in case of
4419
xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) {
4423
if (reader->node == NULL)
4425
if (reader->curnode != NULL)
4426
node = reader->curnode;
4428
node = reader->node;
4430
if (XML_NAMESPACE_DECL == node->type)
4437
* xmlTextReaderConstXmlVersion:
4438
* @reader: the xmlTextReaderPtr used
4440
* Determine the XML version of the document being read.
4442
* Returns a string containing the XML version of the document or NULL
4443
* in case of error. The string is deallocated with the reader.
4446
xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) {
4447
xmlDocPtr doc = NULL;
4450
if (reader->doc != NULL)
4452
else if (reader->ctxt != NULL)
4453
doc = reader->ctxt->myDoc;
4457
if (doc->version == NULL)
4460
return(CONSTSTR(doc->version));
4464
* xmlTextReaderStandalone:
4465
* @reader: the xmlTextReaderPtr used
4467
* Determine the standalone status of the document being read.
4469
* Returns 1 if the document was declared to be standalone, 0 if it
4470
* was declared to be not standalone, or -1 if the document did not
4471
* specify its standalone status or in case of error.
4474
xmlTextReaderStandalone(xmlTextReaderPtr reader) {
4475
xmlDocPtr doc = NULL;
4478
if (reader->doc != NULL)
4480
else if (reader->ctxt != NULL)
4481
doc = reader->ctxt->myDoc;
4485
return(doc->standalone);
4488
/************************************************************************
4490
* Error Handling Extensions *
4492
************************************************************************/
4494
/* helper to build a xmlMalloc'ed string from a format and va_list */
4496
xmlTextReaderBuildMessage(const char *msg, va_list ap) {
4502
str = (char *) xmlMallocAtomic(150);
4504
xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
4511
chars = vsnprintf(str, size, msg, ap);
4512
if ((chars > -1) && (chars < size))
4518
if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
4519
xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
4530
* xmlTextReaderLocatorLineNumber:
4531
* @locator: the xmlTextReaderLocatorPtr used
4533
* Obtain the line number for the given locator.
4535
* Returns the line number or -1 in case of error.
4538
xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
4539
/* we know that locator is a xmlParserCtxtPtr */
4540
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
4543
if (locator == NULL)
4545
if (ctx->node != NULL) {
4546
ret = xmlGetLineNo(ctx->node);
4549
/* inspired from error.c */
4550
xmlParserInputPtr input;
4552
if ((input->filename == NULL) && (ctx->inputNr > 1))
4553
input = ctx->inputTab[ctx->inputNr - 2];
4554
if (input != NULL) {
4566
* xmlTextReaderLocatorBaseURI:
4567
* @locator: the xmlTextReaderLocatorPtr used
4569
* Obtain the base URI for the given locator.
4571
* Returns the base URI or NULL in case of error.
4574
xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
4575
/* we know that locator is a xmlParserCtxtPtr */
4576
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
4577
xmlChar *ret = NULL;
4579
if (locator == NULL)
4581
if (ctx->node != NULL) {
4582
ret = xmlNodeGetBase(NULL,ctx->node);
4585
/* inspired from error.c */
4586
xmlParserInputPtr input;
4588
if ((input->filename == NULL) && (ctx->inputNr > 1))
4589
input = ctx->inputTab[ctx->inputNr - 2];
4590
if (input != NULL) {
4591
ret = xmlStrdup(BAD_CAST input->filename);
4602
xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) {
4603
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
4604
xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private;
4607
if (reader->errorFunc)
4608
reader->errorFunc(reader->errorFuncArg,
4611
(xmlTextReaderLocatorPtr)ctx);
4617
xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error) {
4618
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
4619
xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
4621
if (error && reader->sErrorFunc) {
4622
reader->sErrorFunc(reader->errorFuncArg,
4623
(xmlErrorPtr) error);
4627
static void XMLCDECL
4628
xmlTextReaderError(void *ctxt, const char *msg, ...) {
4632
xmlTextReaderGenericError(ctxt,
4633
XML_PARSER_SEVERITY_ERROR,
4634
xmlTextReaderBuildMessage(msg,ap));
4639
static void XMLCDECL
4640
xmlTextReaderWarning(void *ctxt, const char *msg, ...) {
4644
xmlTextReaderGenericError(ctxt,
4645
XML_PARSER_SEVERITY_WARNING,
4646
xmlTextReaderBuildMessage(msg,ap));
4650
static void XMLCDECL
4651
xmlTextReaderValidityError(void *ctxt, const char *msg, ...) {
4653
int len = xmlStrlen((const xmlChar *) msg);
4655
if ((len > 1) && (msg[len - 2] != ':')) {
4657
* some callbacks only report locator information:
4658
* skip them (mimicking behaviour in error.c)
4661
xmlTextReaderGenericError(ctxt,
4662
XML_PARSER_SEVERITY_VALIDITY_ERROR,
4663
xmlTextReaderBuildMessage(msg,ap));
4668
static void XMLCDECL
4669
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
4671
int len = xmlStrlen((const xmlChar *) msg);
4673
if ((len != 0) && (msg[len - 1] != ':')) {
4675
* some callbacks only report locator information:
4676
* skip them (mimicking behaviour in error.c)
4679
xmlTextReaderGenericError(ctxt,
4680
XML_PARSER_SEVERITY_VALIDITY_WARNING,
4681
xmlTextReaderBuildMessage(msg,ap));
4687
* xmlTextReaderSetErrorHandler:
4688
* @reader: the xmlTextReaderPtr used
4689
* @f: the callback function to call on error and warnings
4690
* @arg: a user argument to pass to the callback function
4692
* Register a callback function that will be called on error and warnings.
4694
* If @f is NULL, the default error and warning handlers are restored.
4697
xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
4698
xmlTextReaderErrorFunc f,
4701
reader->ctxt->sax->error = xmlTextReaderError;
4702
reader->ctxt->sax->serror = NULL;
4703
reader->ctxt->vctxt.error = xmlTextReaderValidityError;
4704
reader->ctxt->sax->warning = xmlTextReaderWarning;
4705
reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
4706
reader->errorFunc = f;
4707
reader->sErrorFunc = NULL;
4708
reader->errorFuncArg = arg;
4709
#ifdef LIBXML_SCHEMAS_ENABLED
4710
if (reader->rngValidCtxt) {
4711
xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
4712
xmlTextReaderValidityErrorRelay,
4713
xmlTextReaderValidityWarningRelay,
4715
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
4717
if (reader->xsdValidCtxt) {
4718
xmlSchemaSetValidErrors(reader->xsdValidCtxt,
4719
xmlTextReaderValidityErrorRelay,
4720
xmlTextReaderValidityWarningRelay,
4722
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
4727
/* restore defaults */
4728
reader->ctxt->sax->error = xmlParserError;
4729
reader->ctxt->vctxt.error = xmlParserValidityError;
4730
reader->ctxt->sax->warning = xmlParserWarning;
4731
reader->ctxt->vctxt.warning = xmlParserValidityWarning;
4732
reader->errorFunc = NULL;
4733
reader->sErrorFunc = NULL;
4734
reader->errorFuncArg = NULL;
4735
#ifdef LIBXML_SCHEMAS_ENABLED
4736
if (reader->rngValidCtxt) {
4737
xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
4738
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
4740
if (reader->xsdValidCtxt) {
4741
xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
4742
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
4749
* xmlTextReaderSetStructuredErrorHandler:
4750
* @reader: the xmlTextReaderPtr used
4751
* @f: the callback function to call on error and warnings
4752
* @arg: a user argument to pass to the callback function
4754
* Register a callback function that will be called on error and warnings.
4756
* If @f is NULL, the default error and warning handlers are restored.
4759
xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
4760
xmlStructuredErrorFunc f,
4763
reader->ctxt->sax->error = NULL;
4764
reader->ctxt->sax->serror = xmlTextReaderStructuredError;
4765
reader->ctxt->vctxt.error = xmlTextReaderValidityError;
4766
reader->ctxt->sax->warning = xmlTextReaderWarning;
4767
reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
4768
reader->sErrorFunc = f;
4769
reader->errorFunc = NULL;
4770
reader->errorFuncArg = arg;
4771
#ifdef LIBXML_SCHEMAS_ENABLED
4772
if (reader->rngValidCtxt) {
4773
xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
4774
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
4775
xmlTextReaderValidityStructuredRelay,
4778
if (reader->xsdValidCtxt) {
4779
xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
4780
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
4781
xmlTextReaderValidityStructuredRelay,
4787
/* restore defaults */
4788
reader->ctxt->sax->error = xmlParserError;
4789
reader->ctxt->sax->serror = NULL;
4790
reader->ctxt->vctxt.error = xmlParserValidityError;
4791
reader->ctxt->sax->warning = xmlParserWarning;
4792
reader->ctxt->vctxt.warning = xmlParserValidityWarning;
4793
reader->errorFunc = NULL;
4794
reader->sErrorFunc = NULL;
4795
reader->errorFuncArg = NULL;
4796
#ifdef LIBXML_SCHEMAS_ENABLED
4797
if (reader->rngValidCtxt) {
4798
xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
4799
xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
4801
if (reader->xsdValidCtxt) {
4802
xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
4803
xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
4810
* xmlTextReaderIsValid:
4811
* @reader: the xmlTextReaderPtr used
4813
* Retrieve the validity status from the parser context
4815
* Returns the flag value 1 if valid, 0 if no, and -1 in case of error
4818
xmlTextReaderIsValid(xmlTextReaderPtr reader) {
4819
if (reader == NULL) return(-1);
4820
#ifdef LIBXML_SCHEMAS_ENABLED
4821
if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
4822
return(reader->rngValidErrors == 0);
4823
if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
4824
return(reader->xsdValidErrors == 0);
4826
if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
4827
return(reader->ctxt->valid);
4832
* xmlTextReaderGetErrorHandler:
4833
* @reader: the xmlTextReaderPtr used
4834
* @f: the callback function or NULL is no callback has been registered
4835
* @arg: a user argument
4837
* Retrieve the error callback function and user argument.
4840
xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
4841
xmlTextReaderErrorFunc *f,
4843
if (f != NULL) *f = reader->errorFunc;
4844
if (arg != NULL) *arg = reader->errorFuncArg;
4848
/************************************************************************
4850
* New set (2.6.0) of simpler and more flexible APIs *
4852
************************************************************************/
4855
* xmlTextReaderSetup:
4856
* @reader: an XML reader
4857
* @input: xmlParserInputBufferPtr used to feed the reader, will
4858
* be destroyed with it.
4859
* @URL: the base URL to use for the document
4860
* @encoding: the document encoding, or NULL
4861
* @options: a combination of xmlParserOption
4863
* Setup an XML reader with new options
4865
* Returns 0 in case of success and -1 in case of error.
4868
xmlTextReaderSetup(xmlTextReaderPtr reader,
4869
xmlParserInputBufferPtr input, const char *URL,
4870
const char *encoding, int options)
4872
if (reader == NULL) {
4874
xmlFreeParserInputBuffer(input);
4879
* we force the generation of compact text nodes on the reader
4880
* since usr applications should never modify the tree
4882
options |= XML_PARSE_COMPACT;
4886
reader->parserFlags = options;
4887
reader->validate = XML_TEXTREADER_NOT_VALIDATE;
4888
if ((input != NULL) && (reader->input != NULL) &&
4889
(reader->allocs & XML_TEXTREADER_INPUT)) {
4890
xmlFreeParserInputBuffer(reader->input);
4891
reader->input = NULL;
4892
reader->allocs -= XML_TEXTREADER_INPUT;
4894
if (input != NULL) {
4895
reader->input = input;
4896
reader->allocs |= XML_TEXTREADER_INPUT;
4898
if (reader->buffer == NULL)
4899
reader->buffer = xmlBufferCreateSize(100);
4900
if (reader->buffer == NULL) {
4901
xmlGenericError(xmlGenericErrorContext,
4902
"xmlTextReaderSetup : malloc failed\n");
4905
if (reader->sax == NULL)
4906
reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
4907
if (reader->sax == NULL) {
4908
xmlGenericError(xmlGenericErrorContext,
4909
"xmlTextReaderSetup : malloc failed\n");
4912
xmlSAXVersion(reader->sax, 2);
4913
reader->startElement = reader->sax->startElement;
4914
reader->sax->startElement = xmlTextReaderStartElement;
4915
reader->endElement = reader->sax->endElement;
4916
reader->sax->endElement = xmlTextReaderEndElement;
4917
#ifdef LIBXML_SAX1_ENABLED
4918
if (reader->sax->initialized == XML_SAX2_MAGIC) {
4919
#endif /* LIBXML_SAX1_ENABLED */
4920
reader->startElementNs = reader->sax->startElementNs;
4921
reader->sax->startElementNs = xmlTextReaderStartElementNs;
4922
reader->endElementNs = reader->sax->endElementNs;
4923
reader->sax->endElementNs = xmlTextReaderEndElementNs;
4924
#ifdef LIBXML_SAX1_ENABLED
4926
reader->startElementNs = NULL;
4927
reader->endElementNs = NULL;
4929
#endif /* LIBXML_SAX1_ENABLED */
4930
reader->characters = reader->sax->characters;
4931
reader->sax->characters = xmlTextReaderCharacters;
4932
reader->sax->ignorableWhitespace = xmlTextReaderCharacters;
4933
reader->cdataBlock = reader->sax->cdataBlock;
4934
reader->sax->cdataBlock = xmlTextReaderCDataBlock;
4936
reader->mode = XML_TEXTREADER_MODE_INITIAL;
4937
reader->node = NULL;
4938
reader->curnode = NULL;
4939
if (input != NULL) {
4940
if (reader->input->buffer->use < 4) {
4941
xmlParserInputBufferRead(input, 4);
4943
if (reader->ctxt == NULL) {
4944
if (reader->input->buffer->use >= 4) {
4945
reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
4946
(const char *) reader->input->buffer->content, 4, URL);
4951
xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);
4956
xmlParserInputPtr inputStream;
4957
xmlParserInputBufferPtr buf;
4958
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
4960
xmlCtxtReset(reader->ctxt);
4961
buf = xmlAllocParserInputBuffer(enc);
4962
if (buf == NULL) return(-1);
4963
inputStream = xmlNewInputStream(reader->ctxt);
4964
if (inputStream == NULL) {
4965
xmlFreeParserInputBuffer(buf);
4970
inputStream->filename = NULL;
4972
inputStream->filename = (char *)
4973
xmlCanonicPath((const xmlChar *) URL);
4974
inputStream->buf = buf;
4975
inputStream->base = inputStream->buf->buffer->content;
4976
inputStream->cur = inputStream->buf->buffer->content;
4978
&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
4980
inputPush(reader->ctxt, inputStream);
4983
if (reader->ctxt == NULL) {
4984
xmlGenericError(xmlGenericErrorContext,
4985
"xmlTextReaderSetup : malloc failed\n");
4989
if (reader->dict != NULL) {
4990
if (reader->ctxt->dict != NULL) {
4991
if (reader->dict != reader->ctxt->dict) {
4992
xmlDictFree(reader->dict);
4993
reader->dict = reader->ctxt->dict;
4996
reader->ctxt->dict = reader->dict;
4999
if (reader->ctxt->dict == NULL)
5000
reader->ctxt->dict = xmlDictCreate();
5001
reader->dict = reader->ctxt->dict;
5003
reader->ctxt->_private = reader;
5004
reader->ctxt->linenumbers = 1;
5005
reader->ctxt->dictNames = 1;
5007
* use the parser dictionnary to allocate all elements and attributes names
5009
reader->ctxt->docdict = 1;
5010
reader->ctxt->parseMode = XML_PARSE_READER;
5012
#ifdef LIBXML_XINCLUDE_ENABLED
5013
if (reader->xincctxt != NULL) {
5014
xmlXIncludeFreeContext(reader->xincctxt);
5015
reader->xincctxt = NULL;
5017
if (options & XML_PARSE_XINCLUDE) {
5018
reader->xinclude = 1;
5019
reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);
5020
options -= XML_PARSE_XINCLUDE;
5022
reader->xinclude = 0;
5023
reader->in_xinclude = 0;
5025
#ifdef LIBXML_PATTERN_ENABLED
5026
if (reader->patternTab == NULL) {
5027
reader->patternNr = 0;
5028
reader->patternMax = 0;
5030
while (reader->patternNr > 0) {
5031
reader->patternNr--;
5032
if (reader->patternTab[reader->patternNr] != NULL) {
5033
xmlFreePattern(reader->patternTab[reader->patternNr]);
5034
reader->patternTab[reader->patternNr] = NULL;
5039
if (options & XML_PARSE_DTDVALID)
5040
reader->validate = XML_TEXTREADER_VALIDATE_DTD;
5042
xmlCtxtUseOptions(reader->ctxt, options);
5043
if (encoding != NULL) {
5044
xmlCharEncodingHandlerPtr hdlr;
5046
hdlr = xmlFindCharEncodingHandler(encoding);
5048
xmlSwitchToEncoding(reader->ctxt, hdlr);
5050
if ((URL != NULL) && (reader->ctxt->input != NULL) &&
5051
(reader->ctxt->input->filename == NULL))
5052
reader->ctxt->input->filename = (char *)
5053
xmlStrdup((const xmlChar *) URL);
5061
* xmlTextReaderByteConsumed:
5062
* @reader: an XML reader
5064
* This function provides the current index of the parser used
5065
* by the reader, relative to the start of the current entity.
5066
* This function actually just wraps a call to xmlBytesConsumed()
5067
* for the parser context associated with the reader.
5068
* See xmlBytesConsumed() for more information.
5070
* Returns the index in bytes from the beginning of the entity or -1
5071
* in case the index could not be computed.
5074
xmlTextReaderByteConsumed(xmlTextReaderPtr reader) {
5075
if ((reader == NULL) || (reader->ctxt == NULL))
5077
return(xmlByteConsumed(reader->ctxt));
5083
* @doc: a preparsed document
5085
* Create an xmltextReader for a preparsed document.
5087
* Returns the new reader or NULL in case of error.
5090
xmlReaderWalker(xmlDocPtr doc)
5092
xmlTextReaderPtr ret;
5097
ret = xmlMalloc(sizeof(xmlTextReader));
5099
xmlGenericError(xmlGenericErrorContext,
5100
"xmlNewTextReader : malloc failed\n");
5103
memset(ret, 0, sizeof(xmlTextReader));
5106
ret->mode = XML_TEXTREADER_MODE_INITIAL;
5108
ret->curnode = NULL;
5111
ret->allocs = XML_TEXTREADER_CTXT;
5113
ret->state = XML_TEXTREADER_START;
5114
ret->dict = xmlDictCreate();
5120
* @cur: a pointer to a zero terminated string
5121
* @URL: the base URL to use for the document
5122
* @encoding: the document encoding, or NULL
5123
* @options: a combination of xmlParserOption
5125
* Create an xmltextReader for an XML in-memory document.
5126
* The parsing flags @options are a combination of xmlParserOption.
5128
* Returns the new reader or NULL in case of error.
5131
xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,
5138
len = xmlStrlen(cur);
5140
return (xmlReaderForMemory
5141
((const char *) cur, len, URL, encoding, options));
5146
* @filename: a file or URL
5147
* @encoding: the document encoding, or NULL
5148
* @options: a combination of xmlParserOption
5150
* parse an XML file from the filesystem or the network.
5151
* The parsing flags @options are a combination of xmlParserOption.
5153
* Returns the new reader or NULL in case of error.
5156
xmlReaderForFile(const char *filename, const char *encoding, int options)
5158
xmlTextReaderPtr reader;
5160
reader = xmlNewTextReaderFilename(filename);
5163
xmlTextReaderSetup(reader, NULL, NULL, encoding, options);
5168
* xmlReaderForMemory:
5169
* @buffer: a pointer to a char array
5170
* @size: the size of the array
5171
* @URL: the base URL to use for the document
5172
* @encoding: the document encoding, or NULL
5173
* @options: a combination of xmlParserOption
5175
* Create an xmltextReader for an XML in-memory document.
5176
* The parsing flags @options are a combination of xmlParserOption.
5178
* Returns the new reader or NULL in case of error.
5181
xmlReaderForMemory(const char *buffer, int size, const char *URL,
5182
const char *encoding, int options)
5184
xmlTextReaderPtr reader;
5185
xmlParserInputBufferPtr buf;
5187
buf = xmlParserInputBufferCreateStatic(buffer, size,
5188
XML_CHAR_ENCODING_NONE);
5192
reader = xmlNewTextReader(buf, URL);
5193
if (reader == NULL) {
5194
xmlFreeParserInputBuffer(buf);
5197
reader->allocs |= XML_TEXTREADER_INPUT;
5198
xmlTextReaderSetup(reader, NULL, URL, encoding, options);
5204
* @fd: an open file descriptor
5205
* @URL: the base URL to use for the document
5206
* @encoding: the document encoding, or NULL
5207
* @options: a combination of xmlParserOption
5209
* Create an xmltextReader for an XML from a file descriptor.
5210
* The parsing flags @options are a combination of xmlParserOption.
5211
* NOTE that the file descriptor will not be closed when the
5212
* reader is closed or reset.
5214
* Returns the new reader or NULL in case of error.
5217
xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)
5219
xmlTextReaderPtr reader;
5220
xmlParserInputBufferPtr input;
5225
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
5228
input->closecallback = NULL;
5229
reader = xmlNewTextReader(input, URL);
5230
if (reader == NULL) {
5231
xmlFreeParserInputBuffer(input);
5234
reader->allocs |= XML_TEXTREADER_INPUT;
5235
xmlTextReaderSetup(reader, NULL, URL, encoding, options);
5241
* @ioread: an I/O read function
5242
* @ioclose: an I/O close function
5243
* @ioctx: an I/O handler
5244
* @URL: the base URL to use for the document
5245
* @encoding: the document encoding, or NULL
5246
* @options: a combination of xmlParserOption
5248
* Create an xmltextReader for an XML document from I/O functions and source.
5249
* The parsing flags @options are a combination of xmlParserOption.
5251
* Returns the new reader or NULL in case of error.
5254
xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
5255
void *ioctx, const char *URL, const char *encoding,
5258
xmlTextReaderPtr reader;
5259
xmlParserInputBufferPtr input;
5264
input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
5265
XML_CHAR_ENCODING_NONE);
5268
reader = xmlNewTextReader(input, URL);
5269
if (reader == NULL) {
5270
xmlFreeParserInputBuffer(input);
5273
reader->allocs |= XML_TEXTREADER_INPUT;
5274
xmlTextReaderSetup(reader, NULL, URL, encoding, options);
5279
* xmlReaderNewWalker:
5280
* @reader: an XML reader
5281
* @doc: a preparsed document
5283
* Setup an xmltextReader to parse a preparsed XML document.
5284
* This reuses the existing @reader xmlTextReader.
5286
* Returns 0 in case of success and -1 in case of error
5289
xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)
5296
if (reader->input != NULL) {
5297
xmlFreeParserInputBuffer(reader->input);
5299
if (reader->ctxt != NULL) {
5300
xmlCtxtReset(reader->ctxt);
5304
reader->input = NULL;
5305
reader->mode = XML_TEXTREADER_MODE_INITIAL;
5306
reader->node = NULL;
5307
reader->curnode = NULL;
5310
reader->allocs = XML_TEXTREADER_CTXT;
5312
reader->state = XML_TEXTREADER_START;
5313
if (reader->dict == NULL) {
5314
if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))
5315
reader->dict = reader->ctxt->dict;
5317
reader->dict = xmlDictCreate();
5324
* @reader: an XML reader
5325
* @cur: a pointer to a zero terminated string
5326
* @URL: the base URL to use for the document
5327
* @encoding: the document encoding, or NULL
5328
* @options: a combination of xmlParserOption
5330
* Setup an xmltextReader to parse an XML in-memory document.
5331
* The parsing flags @options are a combination of xmlParserOption.
5332
* This reuses the existing @reader xmlTextReader.
5334
* Returns 0 in case of success and -1 in case of error
5337
xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,
5338
const char *URL, const char *encoding, int options)
5348
len = xmlStrlen(cur);
5349
return (xmlReaderNewMemory(reader, (const char *)cur, len,
5350
URL, encoding, options));
5355
* @reader: an XML reader
5356
* @filename: a file or URL
5357
* @encoding: the document encoding, or NULL
5358
* @options: a combination of xmlParserOption
5360
* parse an XML file from the filesystem or the network.
5361
* The parsing flags @options are a combination of xmlParserOption.
5362
* This reuses the existing @reader xmlTextReader.
5364
* Returns 0 in case of success and -1 in case of error
5367
xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,
5368
const char *encoding, int options)
5370
xmlParserInputBufferPtr input;
5372
if (filename == NULL)
5378
xmlParserInputBufferCreateFilename(filename,
5379
XML_CHAR_ENCODING_NONE);
5382
return (xmlTextReaderSetup(reader, input, filename, encoding, options));
5386
* xmlReaderNewMemory:
5387
* @reader: an XML reader
5388
* @buffer: a pointer to a char array
5389
* @size: the size of the array
5390
* @URL: the base URL to use for the document
5391
* @encoding: the document encoding, or NULL
5392
* @options: a combination of xmlParserOption
5394
* Setup an xmltextReader to parse an XML in-memory document.
5395
* The parsing flags @options are a combination of xmlParserOption.
5396
* This reuses the existing @reader xmlTextReader.
5398
* Returns 0 in case of success and -1 in case of error
5401
xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,
5402
const char *URL, const char *encoding, int options)
5404
xmlParserInputBufferPtr input;
5411
input = xmlParserInputBufferCreateStatic(buffer, size,
5412
XML_CHAR_ENCODING_NONE);
5413
if (input == NULL) {
5416
return (xmlTextReaderSetup(reader, input, URL, encoding, options));
5421
* @reader: an XML reader
5422
* @fd: an open file descriptor
5423
* @URL: the base URL to use for the document
5424
* @encoding: the document encoding, or NULL
5425
* @options: a combination of xmlParserOption
5427
* Setup an xmltextReader to parse an XML from a file descriptor.
5428
* NOTE that the file descriptor will not be closed when the
5429
* reader is closed or reset.
5430
* The parsing flags @options are a combination of xmlParserOption.
5431
* This reuses the existing @reader xmlTextReader.
5433
* Returns 0 in case of success and -1 in case of error
5436
xmlReaderNewFd(xmlTextReaderPtr reader, int fd,
5437
const char *URL, const char *encoding, int options)
5439
xmlParserInputBufferPtr input;
5446
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
5449
input->closecallback = NULL;
5450
return (xmlTextReaderSetup(reader, input, URL, encoding, options));
5455
* @reader: an XML reader
5456
* @ioread: an I/O read function
5457
* @ioclose: an I/O close function
5458
* @ioctx: an I/O handler
5459
* @URL: the base URL to use for the document
5460
* @encoding: the document encoding, or NULL
5461
* @options: a combination of xmlParserOption
5463
* Setup an xmltextReader to parse an XML document from I/O functions
5465
* The parsing flags @options are a combination of xmlParserOption.
5466
* This reuses the existing @reader xmlTextReader.
5468
* Returns 0 in case of success and -1 in case of error
5471
xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
5472
xmlInputCloseCallback ioclose, void *ioctx,
5473
const char *URL, const char *encoding, int options)
5475
xmlParserInputBufferPtr input;
5482
input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
5483
XML_CHAR_ENCODING_NONE);
5486
return (xmlTextReaderSetup(reader, input, URL, encoding, options));
5488
/************************************************************************
5492
************************************************************************/
5496
* @in: the input buffer
5497
* @inlen: the size of the input (in), the size read from it (out)
5498
* @to: the output buffer
5499
* @tolen: the size of the output (in), the size written to (out)
5501
* Base64 decoder, reads from @in and save in @to
5502
* TODO: tell jody when this is actually exported
5504
* Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5505
* 2 if there wasn't enough space on the output or -1 in case of error.
5508
xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
5509
unsigned char *to, unsigned long *tolen) {
5510
unsigned long incur; /* current index in in[] */
5511
unsigned long inblk; /* last block index in in[] */
5512
unsigned long outcur; /* current index in out[] */
5513
unsigned long inmax; /* size of in[] */
5514
unsigned long outmax; /* size of out[] */
5515
unsigned char cur; /* the current value read from in[] */
5516
unsigned char intmp[4], outtmp[4]; /* temporary buffers for the convert */
5517
int nbintmp; /* number of byte in intmp[] */
5518
int is_ignore; /* cur should be ignored */
5519
int is_end = 0; /* the end of the base64 was found */
5523
if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
5538
if ((cur >= 'A') && (cur <= 'Z'))
5540
else if ((cur >= 'a') && (cur <= 'z'))
5541
cur = cur - 'a' + 26;
5542
else if ((cur >= '0') && (cur <= '9'))
5543
cur = cur - '0' + 52;
5544
else if (cur == '+')
5546
else if (cur == '/')
5548
else if (cur == '.')
5550
else if (cur == '=') /*no op , end of the base64 stream */
5565
if ((nbintmp == 1) || (nbintmp == 2))
5572
intmp[nbintmp++] = cur;
5574
* if intmp is full, push the 4byte sequence as a 3 byte
5579
outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
5581
((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
5582
outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
5583
if (outcur + 3 >= outmax) {
5588
for (i = 0; i < nbouttmp; i++)
5589
to[outcur++] = outtmp[i];
5606
* Test routine for the xmlBase64Decode function
5609
int main(int argc, char **argv) {
5610
char *input = " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5614
unsigned long inlen = strlen(input);
5615
unsigned long outlen = 100;
5617
unsigned long cons, tmp, tmp2, prod;
5622
ret = xmlBase64Decode(input, &inlen, output, &outlen);
5625
printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen, outlen, output);
5632
while (cons < inlen) {
5634
tmp2 = inlen - cons;
5636
printf("%ld %ld\n", cons, prod);
5637
ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
5640
printf("%ld %ld\n", cons, prod);
5642
output2[outlen] = 0;
5643
printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output2);
5650
while (cons < inlen) {
5652
tmp2 = inlen - cons;
5656
printf("%ld %ld\n", cons, prod);
5657
ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
5660
printf("%ld %ld\n", cons, prod);
5662
output3[outlen] = 0;
5663
printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output3);
5668
#endif /* NOT_USED_YET */
5669
#define bottom_xmlreader
5670
#include "elfgcchack.h"
5671
#endif /* LIBXML_READER_ENABLED */