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 ! */
26 #include <libxml/xmlmemory.h>
27 #include <libxml/xmlIO.h>
28 #include <libxml/xmlreader.h>
29 #include <libxml/parserInternals.h>
30 #ifdef LIBXML_SCHEMAS_ENABLED
31 #include <libxml/relaxng.h>
32 #include <libxml/xmlschemas.h>
34 #include <libxml/uri.h>
35 #ifdef LIBXML_XINCLUDE_ENABLED
36 #include <libxml/xinclude.h>
38 #ifdef LIBXML_PATTERN_ENABLED
39 #include <libxml/pattern.h>
42 #include "private/buf.h"
43 #include "private/tree.h"
44 #ifdef LIBXML_XINCLUDE_ENABLED
45 #include "private/xinclude.h"
48 #define MAX_ERR_MSG_SIZE 64000
50 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
51 /* Keeping free objects can hide memory errors. */
52 #define MAX_FREE_NODES 1
54 #define MAX_FREE_NODES 100
58 * The following VA_COPY was coded following an example in
59 * the Samba project. It may not be sufficient for some
60 * esoteric implementations of va_list but (hopefully) will
61 * be sufficient for libxml2.
65 #define VA_COPY(dest, src) va_copy(dest, src)
68 #define VA_COPY(dest,src) __va_copy(dest, src)
70 #ifndef VA_LIST_IS_ARRAY
71 #define VA_COPY(dest,src) (dest) = (src)
74 #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
80 /* #define DEBUG_CALLBACKS */
81 /* #define DEBUG_READER */
86 * macro to flag unimplemented blocks
89 xmlGenericError(xmlGenericErrorContext, \
90 "Unimplemented block at %s:%d\n", \
94 #define DUMP_READER xmlTextReaderDebug(reader);
99 #define CHUNK_SIZE 512
100 /************************************************************************
102 * The parser: maps the Text Reader API on top of the existing *
103 * parsing routines building a tree *
105 ************************************************************************/
107 #define XML_TEXTREADER_INPUT 1
108 #define XML_TEXTREADER_CTXT 2
111 XML_TEXTREADER_NONE
= -1,
112 XML_TEXTREADER_START
= 0,
113 XML_TEXTREADER_ELEMENT
= 1,
114 XML_TEXTREADER_END
= 2,
115 XML_TEXTREADER_EMPTY
= 3,
116 XML_TEXTREADER_BACKTRACK
= 4,
117 XML_TEXTREADER_DONE
= 5,
118 XML_TEXTREADER_ERROR
= 6
119 } xmlTextReaderState
;
122 XML_TEXTREADER_NOT_VALIDATE
= 0,
123 XML_TEXTREADER_VALIDATE_DTD
= 1,
124 XML_TEXTREADER_VALIDATE_RNG
= 2,
125 XML_TEXTREADER_VALIDATE_XSD
= 4
126 } xmlTextReaderValidate
;
128 struct _xmlTextReader
{
129 int mode
; /* the parsing mode */
130 xmlDocPtr doc
; /* when walking an existing doc */
131 xmlTextReaderValidate validate
;/* is there any validation */
132 int allocs
; /* what structure were deallocated */
133 xmlTextReaderState state
;
134 xmlParserCtxtPtr ctxt
; /* the parser context */
135 xmlSAXHandlerPtr sax
; /* the parser SAX callbacks */
136 xmlParserInputBufferPtr input
; /* the input */
137 startElementSAXFunc startElement
;/* initial SAX callbacks */
138 endElementSAXFunc endElement
; /* idem */
139 startElementNsSAX2Func startElementNs
;/* idem */
140 endElementNsSAX2Func endElementNs
; /* idem */
141 charactersSAXFunc characters
;
142 cdataBlockSAXFunc cdataBlock
;
143 unsigned int base
; /* base of the segment in the input */
144 unsigned int cur
; /* current position in the input */
145 xmlNodePtr node
; /* current node */
146 xmlNodePtr curnode
;/* current attribute node */
147 int depth
; /* depth of the current node */
148 xmlNodePtr faketext
;/* fake xmlNs chld */
149 int preserve
;/* preserve the resulting document */
150 xmlBufPtr buffer
; /* used to return const xmlChar * */
151 xmlDictPtr dict
; /* the context dictionary */
153 /* entity stack when traversing entities content */
154 xmlNodePtr ent
; /* Current Entity Ref Node */
155 int entNr
; /* Depth of the entities stack */
156 int entMax
; /* Max depth of the entities stack */
157 xmlNodePtr
*entTab
; /* array of entities */
160 xmlTextReaderErrorFunc errorFunc
; /* callback function */
161 void *errorFuncArg
; /* callback function user argument */
163 #ifdef LIBXML_SCHEMAS_ENABLED
164 /* Handling of RelaxNG validation */
165 xmlRelaxNGPtr rngSchemas
; /* The Relax NG schemas */
166 xmlRelaxNGValidCtxtPtr rngValidCtxt
;/* The Relax NG validation context */
167 int rngPreserveCtxt
; /* 1 if the context was provided by the user */
168 int rngValidErrors
;/* The number of errors detected */
169 xmlNodePtr rngFullNode
; /* the node if RNG not progressive */
170 /* Handling of Schemas validation */
171 xmlSchemaPtr xsdSchemas
; /* The Schemas schemas */
172 xmlSchemaValidCtxtPtr xsdValidCtxt
;/* The Schemas validation context */
173 int xsdPreserveCtxt
; /* 1 if the context was provided by the user */
174 int xsdValidErrors
;/* The number of errors detected */
175 xmlSchemaSAXPlugPtr xsdPlug
; /* the schemas plug in SAX pipeline */
177 #ifdef LIBXML_XINCLUDE_ENABLED
178 /* Handling of XInclude processing */
179 int xinclude
; /* is xinclude asked for */
180 const xmlChar
* xinclude_name
; /* the xinclude name from dict */
181 xmlXIncludeCtxtPtr xincctxt
; /* the xinclude context */
182 int in_xinclude
; /* counts for xinclude */
184 #ifdef LIBXML_PATTERN_ENABLED
185 int patternNr
; /* number of preserve patterns */
186 int patternMax
; /* max preserve patterns */
187 xmlPatternPtr
*patternTab
; /* array of preserve patterns */
189 int preserves
; /* level of preserves */
190 int parserFlags
; /* the set of options set */
191 /* Structured error handling */
192 xmlStructuredErrorFunc sErrorFunc
; /* callback function */
195 #define NODE_IS_EMPTY 0x1
196 #define NODE_IS_PRESERVED 0x2
197 #define NODE_IS_SPRESERVED 0x4
202 * Macro used to return an interned string
204 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
205 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
207 static int xmlTextReaderReadTree(xmlTextReaderPtr reader
);
208 static int xmlTextReaderNextTree(xmlTextReaderPtr reader
);
210 /************************************************************************
212 * Our own version of the freeing routines as we recycle nodes *
214 ************************************************************************/
219 * Free a string if it is not owned by the "dict" dictionary in the
222 #define DICT_FREE(str) \
223 if ((str) && ((!dict) || \
224 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
225 xmlFree((char *)(str));
227 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
);
228 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
);
231 * xmlTextReaderFreeProp:
232 * @reader: the xmlTextReaderPtr used
238 xmlTextReaderFreeProp(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
241 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
242 dict
= reader
->ctxt
->dict
;
245 if (cur
== NULL
) return;
247 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
248 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
250 if (cur
->children
!= NULL
)
251 xmlTextReaderFreeNodeList(reader
, cur
->children
);
253 DICT_FREE(cur
->name
);
254 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
255 (reader
->ctxt
->freeAttrsNr
< MAX_FREE_NODES
)) {
256 cur
->next
= reader
->ctxt
->freeAttrs
;
257 reader
->ctxt
->freeAttrs
= cur
;
258 reader
->ctxt
->freeAttrsNr
++;
265 * xmlTextReaderFreePropList:
266 * @reader: the xmlTextReaderPtr used
267 * @cur: the first property in the list
269 * Free a property and all its siblings, all the children are freed too.
272 xmlTextReaderFreePropList(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
275 while (cur
!= NULL
) {
277 xmlTextReaderFreeProp(reader
, cur
);
283 * xmlTextReaderFreeNodeList:
284 * @reader: the xmlTextReaderPtr used
285 * @cur: the first node in the list
287 * Free a node and all its siblings, this is a recursive behaviour, all
288 * the children are freed too.
291 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
297 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
298 dict
= reader
->ctxt
->dict
;
301 if (cur
== NULL
) return;
302 if (cur
->type
== XML_NAMESPACE_DECL
) {
303 xmlFreeNsList((xmlNsPtr
) cur
);
306 if ((cur
->type
== XML_DOCUMENT_NODE
) ||
307 (cur
->type
== XML_HTML_DOCUMENT_NODE
)) {
308 xmlFreeDoc((xmlDocPtr
) cur
);
312 while ((cur
->type
!= XML_DTD_NODE
) &&
313 (cur
->type
!= XML_ENTITY_REF_NODE
) &&
314 (cur
->children
!= NULL
) &&
315 (cur
->children
->parent
== cur
)) {
321 parent
= cur
->parent
;
323 /* unroll to speed up freeing the document */
324 if (cur
->type
!= XML_DTD_NODE
) {
326 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
327 xmlDeregisterNodeDefaultValue(cur
);
329 if (((cur
->type
== XML_ELEMENT_NODE
) ||
330 (cur
->type
== XML_XINCLUDE_START
) ||
331 (cur
->type
== XML_XINCLUDE_END
)) &&
332 (cur
->properties
!= NULL
))
333 xmlTextReaderFreePropList(reader
, cur
->properties
);
334 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
335 (cur
->type
!= XML_ELEMENT_NODE
) &&
336 (cur
->type
!= XML_XINCLUDE_START
) &&
337 (cur
->type
!= XML_XINCLUDE_END
) &&
338 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
339 DICT_FREE(cur
->content
);
341 if (((cur
->type
== XML_ELEMENT_NODE
) ||
342 (cur
->type
== XML_XINCLUDE_START
) ||
343 (cur
->type
== XML_XINCLUDE_END
)) &&
344 (cur
->nsDef
!= NULL
))
345 xmlFreeNsList(cur
->nsDef
);
348 * we don't free element names here they are interned now
350 if ((cur
->type
!= XML_TEXT_NODE
) &&
351 (cur
->type
!= XML_COMMENT_NODE
))
352 DICT_FREE(cur
->name
);
353 if (((cur
->type
== XML_ELEMENT_NODE
) ||
354 (cur
->type
== XML_TEXT_NODE
)) &&
355 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
356 (reader
->ctxt
->freeElemsNr
< MAX_FREE_NODES
)) {
357 cur
->next
= reader
->ctxt
->freeElems
;
358 reader
->ctxt
->freeElems
= cur
;
359 reader
->ctxt
->freeElemsNr
++;
368 if ((depth
== 0) || (parent
== NULL
))
372 cur
->children
= NULL
;
378 * xmlTextReaderFreeNode:
379 * @reader: the xmlTextReaderPtr used
382 * Free a node, this is a recursive behaviour, all the children are freed too.
383 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
386 xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
389 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
390 dict
= reader
->ctxt
->dict
;
393 if (cur
->type
== XML_DTD_NODE
) {
394 xmlFreeDtd((xmlDtdPtr
) cur
);
397 if (cur
->type
== XML_NAMESPACE_DECL
) {
398 xmlFreeNs((xmlNsPtr
) cur
);
401 if (cur
->type
== XML_ATTRIBUTE_NODE
) {
402 xmlTextReaderFreeProp(reader
, (xmlAttrPtr
) cur
);
406 if ((cur
->children
!= NULL
) &&
407 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
408 if (cur
->children
->parent
== cur
)
409 xmlTextReaderFreeNodeList(reader
, cur
->children
);
410 cur
->children
= NULL
;
413 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
414 xmlDeregisterNodeDefaultValue(cur
);
416 if (((cur
->type
== XML_ELEMENT_NODE
) ||
417 (cur
->type
== XML_XINCLUDE_START
) ||
418 (cur
->type
== XML_XINCLUDE_END
)) &&
419 (cur
->properties
!= NULL
))
420 xmlTextReaderFreePropList(reader
, cur
->properties
);
421 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
422 (cur
->type
!= XML_ELEMENT_NODE
) &&
423 (cur
->type
!= XML_XINCLUDE_START
) &&
424 (cur
->type
!= XML_XINCLUDE_END
) &&
425 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
426 DICT_FREE(cur
->content
);
428 if (((cur
->type
== XML_ELEMENT_NODE
) ||
429 (cur
->type
== XML_XINCLUDE_START
) ||
430 (cur
->type
== XML_XINCLUDE_END
)) &&
431 (cur
->nsDef
!= NULL
))
432 xmlFreeNsList(cur
->nsDef
);
435 * we don't free names here they are interned now
437 if ((cur
->type
!= XML_TEXT_NODE
) &&
438 (cur
->type
!= XML_COMMENT_NODE
))
439 DICT_FREE(cur
->name
);
441 if (((cur
->type
== XML_ELEMENT_NODE
) ||
442 (cur
->type
== XML_TEXT_NODE
)) &&
443 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
444 (reader
->ctxt
->freeElemsNr
< MAX_FREE_NODES
)) {
445 cur
->next
= reader
->ctxt
->freeElems
;
446 reader
->ctxt
->freeElems
= cur
;
447 reader
->ctxt
->freeElemsNr
++;
454 * xmlTextReaderFreeDoc:
455 * @reader: the xmlTextReaderPtr used
456 * @cur: pointer to the document
458 * Free up all the structures used by a document, tree included.
461 xmlTextReaderFreeDoc(xmlTextReaderPtr reader
, xmlDocPtr cur
) {
462 xmlDtdPtr extSubset
, intSubset
;
464 if (cur
== NULL
) return;
466 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
467 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
470 * Do this before freeing the children list to avoid ID lookups
472 if (cur
->ids
!= NULL
) xmlFreeIDTable((xmlIDTablePtr
) cur
->ids
);
474 if (cur
->refs
!= NULL
) xmlFreeRefTable((xmlRefTablePtr
) cur
->refs
);
476 extSubset
= cur
->extSubset
;
477 intSubset
= cur
->intSubset
;
478 if (intSubset
== extSubset
)
480 if (extSubset
!= NULL
) {
481 xmlUnlinkNode((xmlNodePtr
) cur
->extSubset
);
482 cur
->extSubset
= NULL
;
483 xmlFreeDtd(extSubset
);
485 if (intSubset
!= NULL
) {
486 xmlUnlinkNode((xmlNodePtr
) cur
->intSubset
);
487 cur
->intSubset
= NULL
;
488 xmlFreeDtd(intSubset
);
491 if (cur
->children
!= NULL
) xmlTextReaderFreeNodeList(reader
, cur
->children
);
493 if (cur
->version
!= NULL
) xmlFree((char *) cur
->version
);
494 if (cur
->name
!= NULL
) xmlFree((char *) cur
->name
);
495 if (cur
->encoding
!= NULL
) xmlFree((char *) cur
->encoding
);
496 if (cur
->oldNs
!= NULL
) xmlFreeNsList(cur
->oldNs
);
497 if (cur
->URL
!= NULL
) xmlFree((char *) cur
->URL
);
498 if (cur
->dict
!= NULL
) xmlDictFree(cur
->dict
);
503 /************************************************************************
505 * The reader core parser *
507 ************************************************************************/
510 xmlTextReaderDebug(xmlTextReaderPtr reader
) {
511 if ((reader
== NULL
) || (reader
->ctxt
== NULL
)) {
512 fprintf(stderr
, "xmlTextReader NULL\n");
515 fprintf(stderr
, "xmlTextReader: state %d depth %d ",
516 reader
->state
, reader
->depth
);
517 if (reader
->node
== NULL
) {
518 fprintf(stderr
, "node = NULL\n");
520 fprintf(stderr
, "node %s\n", reader
->node
->name
);
522 fprintf(stderr
, " input: base %d, cur %d, depth %d: ",
523 reader
->base
, reader
->cur
, reader
->ctxt
->nodeNr
);
524 if (reader
->input
->buffer
== NULL
) {
525 fprintf(stderr
, "buffer is NULL\n");
527 #ifdef LIBXML_DEBUG_ENABLED
528 xmlDebugDumpString(stderr
,
529 &reader
->input
->buffer
->content
[reader
->cur
]);
531 fprintf(stderr
, "\n");
537 * xmlTextReaderEntPush:
538 * @reader: the xmlTextReaderPtr used
539 * @value: the entity reference node
541 * Pushes a new entity reference node on top of the entities stack
543 * Returns -1 in case of error, the index in the stack otherwise
546 xmlTextReaderEntPush(xmlTextReaderPtr reader
, xmlNodePtr value
)
548 if (reader
->entNr
>= reader
->entMax
) {
549 size_t newSize
= reader
->entMax
== 0 ? 10 : reader
->entMax
* 2;
552 tmp
= (xmlNodePtr
*) xmlRealloc(reader
->entTab
,
553 newSize
* sizeof(*tmp
));
555 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
558 reader
->entTab
= tmp
;
559 reader
->entMax
= newSize
;
561 reader
->entTab
[reader
->entNr
] = value
;
563 return (reader
->entNr
++);
567 * xmlTextReaderEntPop:
568 * @reader: the xmlTextReaderPtr used
570 * Pops the top element entity from the entities stack
572 * Returns the entity just removed
575 xmlTextReaderEntPop(xmlTextReaderPtr reader
)
579 if (reader
->entNr
<= 0)
582 if (reader
->entNr
> 0)
583 reader
->ent
= reader
->entTab
[reader
->entNr
- 1];
586 ret
= reader
->entTab
[reader
->entNr
];
587 reader
->entTab
[reader
->entNr
] = NULL
;
592 * xmlTextReaderStartElement:
593 * @ctx: the user data (XML parser context)
594 * @fullname: The element name, including namespace prefix
595 * @atts: An array of name/value attributes pairs, NULL terminated
597 * called when an opening tag has been processed.
600 xmlTextReaderStartElement(void *ctx
, const xmlChar
*fullname
,
601 const xmlChar
**atts
) {
602 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
603 xmlTextReaderPtr reader
= ctxt
->_private
;
605 #ifdef DEBUG_CALLBACKS
606 printf("xmlTextReaderStartElement(%s)\n", fullname
);
608 if ((reader
!= NULL
) && (reader
->startElement
!= NULL
)) {
609 reader
->startElement(ctx
, fullname
, atts
);
610 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
611 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
612 (ctxt
->input
->cur
[1] == '>'))
613 ctxt
->node
->extra
= NODE_IS_EMPTY
;
616 reader
->state
= XML_TEXTREADER_ELEMENT
;
620 * xmlTextReaderEndElement:
621 * @ctx: the user data (XML parser context)
622 * @fullname: The element name, including namespace prefix
624 * called when an ending tag has been processed.
627 xmlTextReaderEndElement(void *ctx
, const xmlChar
*fullname
) {
628 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
629 xmlTextReaderPtr reader
= ctxt
->_private
;
631 #ifdef DEBUG_CALLBACKS
632 printf("xmlTextReaderEndElement(%s)\n", fullname
);
634 if ((reader
!= NULL
) && (reader
->endElement
!= NULL
)) {
635 reader
->endElement(ctx
, fullname
);
640 * xmlTextReaderStartElementNs:
641 * @ctx: the user data (XML parser context)
642 * @localname: the local name of the element
643 * @prefix: the element namespace prefix if available
644 * @URI: the element namespace name if available
645 * @nb_namespaces: number of namespace definitions on that node
646 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
647 * @nb_attributes: the number of attributes on that node
648 * nb_defaulted: the number of defaulted attributes.
649 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
652 * called when an opening tag has been processed.
655 xmlTextReaderStartElementNs(void *ctx
,
656 const xmlChar
*localname
,
657 const xmlChar
*prefix
,
660 const xmlChar
**namespaces
,
663 const xmlChar
**attributes
)
665 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
666 xmlTextReaderPtr reader
= ctxt
->_private
;
668 #ifdef DEBUG_CALLBACKS
669 printf("xmlTextReaderStartElementNs(%s)\n", localname
);
671 if ((reader
!= NULL
) && (reader
->startElementNs
!= NULL
)) {
672 reader
->startElementNs(ctx
, localname
, prefix
, URI
, nb_namespaces
,
673 namespaces
, nb_attributes
, nb_defaulted
,
675 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
676 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
677 (ctxt
->input
->cur
[1] == '>'))
678 ctxt
->node
->extra
= NODE_IS_EMPTY
;
681 reader
->state
= XML_TEXTREADER_ELEMENT
;
685 * xmlTextReaderEndElementNs:
686 * @ctx: the user data (XML parser context)
687 * @localname: the local name of the element
688 * @prefix: the element namespace prefix if available
689 * @URI: the element namespace name if available
691 * called when an ending tag has been processed.
694 xmlTextReaderEndElementNs(void *ctx
,
695 const xmlChar
* localname
,
696 const xmlChar
* prefix
,
699 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
700 xmlTextReaderPtr reader
= ctxt
->_private
;
702 #ifdef DEBUG_CALLBACKS
703 printf("xmlTextReaderEndElementNs(%s)\n", localname
);
705 if ((reader
!= NULL
) && (reader
->endElementNs
!= NULL
)) {
706 reader
->endElementNs(ctx
, localname
, prefix
, URI
);
712 * xmlTextReaderCharacters:
713 * @ctx: the user data (XML parser context)
714 * @ch: a xmlChar string
715 * @len: the number of xmlChar
717 * receiving some chars from the parser.
720 xmlTextReaderCharacters(void *ctx
, const xmlChar
*ch
, int len
)
722 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
723 xmlTextReaderPtr reader
= ctxt
->_private
;
725 #ifdef DEBUG_CALLBACKS
726 printf("xmlTextReaderCharacters()\n");
728 if ((reader
!= NULL
) && (reader
->characters
!= NULL
)) {
729 reader
->characters(ctx
, ch
, len
);
734 * xmlTextReaderCDataBlock:
735 * @ctx: the user data (XML parser context)
736 * @value: The pcdata content
737 * @len: the block length
739 * called when a pcdata block has been parsed
742 xmlTextReaderCDataBlock(void *ctx
, const xmlChar
*ch
, int len
)
744 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
745 xmlTextReaderPtr reader
= ctxt
->_private
;
747 #ifdef DEBUG_CALLBACKS
748 printf("xmlTextReaderCDataBlock()\n");
750 if ((reader
!= NULL
) && (reader
->cdataBlock
!= NULL
)) {
751 reader
->cdataBlock(ctx
, ch
, len
);
756 * xmlTextReaderPushData:
757 * @reader: the xmlTextReaderPtr used
759 * Push data down the progressive parser until a significant callback
762 * Returns -1 in case of failure, 0 otherwise
765 xmlTextReaderPushData(xmlTextReaderPtr reader
) {
768 xmlTextReaderState oldstate
;
770 if ((reader
->input
== NULL
) || (reader
->input
->buffer
== NULL
))
773 oldstate
= reader
->state
;
774 reader
->state
= XML_TEXTREADER_NONE
;
775 inbuf
= reader
->input
->buffer
;
777 while (reader
->state
== XML_TEXTREADER_NONE
) {
778 if (xmlBufUse(inbuf
) < reader
->cur
+ CHUNK_SIZE
) {
780 * Refill the buffer unless we are at the end of the stream
782 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
783 val
= xmlParserInputBufferRead(reader
->input
, 4096);
785 (reader
->input
->readcallback
== NULL
)) {
786 if (xmlBufUse(inbuf
) == reader
->cur
) {
787 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
788 reader
->state
= oldstate
;
790 } else if (val
< 0) {
791 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
792 reader
->state
= oldstate
;
793 if ((oldstate
!= XML_TEXTREADER_START
) ||
794 (reader
->ctxt
->myDoc
!= NULL
))
796 } else if (val
== 0) {
797 /* mark the end of the stream and process the remains */
798 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
806 * parse by block of CHUNK_SIZE bytes, various tests show that
807 * it's the best tradeoff at least on a 1.2GH Duron
809 if (xmlBufUse(inbuf
) >= reader
->cur
+ CHUNK_SIZE
) {
810 val
= xmlParseChunk(reader
->ctxt
,
811 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
813 reader
->cur
+= CHUNK_SIZE
;
815 reader
->ctxt
->wellFormed
= 0;
816 if (reader
->ctxt
->wellFormed
== 0)
819 s
= xmlBufUse(inbuf
) - reader
->cur
;
820 val
= xmlParseChunk(reader
->ctxt
,
821 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
825 reader
->ctxt
->wellFormed
= 0;
831 * Discard the consumed input when needed and possible
833 if (reader
->mode
== XML_TEXTREADER_MODE_INTERACTIVE
) {
834 if (reader
->input
->readcallback
!= NULL
) {
835 if ((reader
->cur
>= 4096) &&
836 (xmlBufUse(inbuf
) - reader
->cur
<= CHUNK_SIZE
)) {
837 val
= xmlBufShrink(inbuf
, reader
->cur
);
846 * At the end of the stream signal that the work is done to the Push
849 else if (reader
->mode
== XML_TEXTREADER_MODE_EOF
) {
850 if (reader
->state
!= XML_TEXTREADER_DONE
) {
851 s
= xmlBufUse(inbuf
) - reader
->cur
;
852 val
= xmlParseChunk(reader
->ctxt
,
853 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
855 reader
->cur
= xmlBufUse(inbuf
);
856 reader
->state
= XML_TEXTREADER_DONE
;
858 if (reader
->ctxt
->wellFormed
)
859 reader
->ctxt
->wellFormed
= 0;
865 reader
->state
= oldstate
;
866 if (reader
->ctxt
->wellFormed
== 0) {
867 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
874 #ifdef LIBXML_REGEXP_ENABLED
876 * xmlTextReaderValidatePush:
877 * @reader: the xmlTextReaderPtr used
879 * Push the current node for validation
882 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
) {
883 xmlNodePtr node
= reader
->node
;
885 #ifdef LIBXML_VALID_ENABLED
886 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
887 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
888 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
889 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
890 reader
->ctxt
->myDoc
, node
, node
->name
);
892 /* TODO use the BuildQName interface */
895 qname
= xmlStrdup(node
->ns
->prefix
);
896 qname
= xmlStrcat(qname
, BAD_CAST
":");
897 qname
= xmlStrcat(qname
, node
->name
);
898 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
899 reader
->ctxt
->myDoc
, node
, qname
);
904 #endif /* LIBXML_VALID_ENABLED */
905 #ifdef LIBXML_SCHEMAS_ENABLED
906 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
907 (reader
->rngValidCtxt
!= NULL
)) {
910 if (reader
->rngFullNode
!= NULL
) return;
911 ret
= xmlRelaxNGValidatePushElement(reader
->rngValidCtxt
,
916 * this element requires a full tree
918 node
= xmlTextReaderExpand(reader
);
922 ret
= xmlRelaxNGValidateFullElement(reader
->rngValidCtxt
,
925 reader
->rngFullNode
= node
;
929 reader
->rngValidErrors
++;
935 * xmlTextReaderValidateCData:
936 * @reader: the xmlTextReaderPtr used
937 * @data: pointer to the CData
938 * @len: length of the CData block in bytes.
940 * Push some CData for validation
943 xmlTextReaderValidateCData(xmlTextReaderPtr reader
,
944 const xmlChar
*data
, int len
) {
945 #ifdef LIBXML_VALID_ENABLED
946 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
947 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
948 reader
->ctxt
->valid
&= xmlValidatePushCData(&reader
->ctxt
->vctxt
,
951 #endif /* LIBXML_VALID_ENABLED */
952 #ifdef LIBXML_SCHEMAS_ENABLED
953 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
954 (reader
->rngValidCtxt
!= NULL
)) {
957 if (reader
->rngFullNode
!= NULL
) return;
958 ret
= xmlRelaxNGValidatePushCData(reader
->rngValidCtxt
, data
, len
);
960 reader
->rngValidErrors
++;
966 * xmlTextReaderValidatePop:
967 * @reader: the xmlTextReaderPtr used
969 * Pop the current node from validation
972 xmlTextReaderValidatePop(xmlTextReaderPtr reader
) {
973 xmlNodePtr node
= reader
->node
;
975 #ifdef LIBXML_VALID_ENABLED
976 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
977 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
978 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
979 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
980 reader
->ctxt
->myDoc
, node
, node
->name
);
982 /* TODO use the BuildQName interface */
985 qname
= xmlStrdup(node
->ns
->prefix
);
986 qname
= xmlStrcat(qname
, BAD_CAST
":");
987 qname
= xmlStrcat(qname
, node
->name
);
988 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
989 reader
->ctxt
->myDoc
, node
, qname
);
994 #endif /* LIBXML_VALID_ENABLED */
995 #ifdef LIBXML_SCHEMAS_ENABLED
996 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
997 (reader
->rngValidCtxt
!= NULL
)) {
1000 if (reader
->rngFullNode
!= NULL
) {
1001 if (node
== reader
->rngFullNode
)
1002 reader
->rngFullNode
= NULL
;
1005 ret
= xmlRelaxNGValidatePopElement(reader
->rngValidCtxt
,
1006 reader
->ctxt
->myDoc
,
1009 reader
->rngValidErrors
++;
1015 * xmlTextReaderValidateEntity:
1016 * @reader: the xmlTextReaderPtr used
1018 * Handle the validation when an entity reference is encountered and
1019 * entity substitution is not activated. As a result the parser interface
1020 * must walk through the entity and do the validation calls
1023 xmlTextReaderValidateEntity(xmlTextReaderPtr reader
) {
1024 xmlNodePtr oldnode
= reader
->node
;
1025 xmlNodePtr node
= reader
->node
;
1028 if (node
->type
== XML_ENTITY_REF_NODE
) {
1029 if ((node
->children
!= NULL
) &&
1030 (node
->children
->type
== XML_ENTITY_DECL
) &&
1031 (node
->children
->children
!= NULL
)) {
1032 if (xmlTextReaderEntPush(reader
, node
) < 0) {
1033 if (node
== oldnode
)
1037 node
= node
->children
->children
;
1041 * The error has probably been raised already.
1043 if (node
== oldnode
)
1047 #ifdef LIBXML_REGEXP_ENABLED
1048 } else if (node
->type
== XML_ELEMENT_NODE
) {
1049 reader
->node
= node
;
1050 xmlTextReaderValidatePush(reader
);
1051 } else if ((node
->type
== XML_TEXT_NODE
) ||
1052 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1053 xmlTextReaderValidateCData(reader
, node
->content
,
1054 xmlStrlen(node
->content
));
1061 if (node
->children
!= NULL
) {
1062 node
= node
->children
;
1064 } else if (node
->type
== XML_ELEMENT_NODE
) {
1065 xmlTextReaderValidatePop(reader
);
1068 if (node
->next
!= NULL
) {
1073 node
= node
->parent
;
1074 if (node
->type
== XML_ELEMENT_NODE
) {
1076 if (reader
->entNr
== 0) {
1077 while ((tmp
= node
->last
) != NULL
) {
1078 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1080 xmlTextReaderFreeNode(reader
, tmp
);
1085 reader
->node
= node
;
1086 xmlTextReaderValidatePop(reader
);
1088 if ((node
->type
== XML_ENTITY_DECL
) &&
1089 (reader
->ent
!= NULL
) && (reader
->ent
->children
== node
)) {
1090 node
= xmlTextReaderEntPop(reader
);
1092 if (node
== oldnode
)
1094 if (node
->next
!= NULL
) {
1098 } while ((node
!= NULL
) && (node
!= oldnode
));
1099 } while ((node
!= NULL
) && (node
!= oldnode
));
1100 reader
->node
= oldnode
;
1102 #endif /* LIBXML_REGEXP_ENABLED */
1106 * xmlTextReaderGetSuccessor:
1107 * @cur: the current node
1109 * Get the successor of a node if available.
1111 * Returns the successor node or NULL
1114 xmlTextReaderGetSuccessor(xmlNodePtr cur
) {
1115 if (cur
== NULL
) return(NULL
) ; /* ERROR */
1116 if (cur
->next
!= NULL
) return(cur
->next
) ;
1119 if (cur
== NULL
) break;
1120 if (cur
->next
!= NULL
) return(cur
->next
);
1121 } while (cur
!= NULL
);
1126 * xmlTextReaderDoExpand:
1127 * @reader: the xmlTextReaderPtr used
1129 * Makes sure that the current node is fully read as well as all its
1130 * descendant. It means the full DOM subtree must be available at the
1133 * Returns 1 if the node was expanded successfully, 0 if there is no more
1134 * nodes to read, or -1 in case of error
1137 xmlTextReaderDoExpand(xmlTextReaderPtr reader
) {
1140 if ((reader
== NULL
) || (reader
->node
== NULL
) || (reader
->ctxt
== NULL
))
1143 if (reader
->ctxt
->instate
== XML_PARSER_EOF
) return(1);
1145 if (xmlTextReaderGetSuccessor(reader
->node
) != NULL
)
1147 if (reader
->ctxt
->nodeNr
< reader
->depth
)
1149 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1151 val
= xmlTextReaderPushData(reader
);
1153 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1156 } while(reader
->mode
!= XML_TEXTREADER_MODE_EOF
);
1161 * xmlTextReaderCollectSiblings:
1162 * @node: the first child
1164 * Traverse depth-first through all sibling nodes and their children
1165 * nodes and concatenate their content. This is an auxiliary function
1166 * to xmlTextReaderReadString.
1168 * Returns a string containing the content, or NULL in case of error.
1171 xmlTextReaderCollectSiblings(xmlNodePtr node
)
1173 xmlBufferPtr buffer
;
1176 if ((node
== NULL
) || (node
->type
== XML_NAMESPACE_DECL
))
1179 buffer
= xmlBufferCreate();
1182 xmlBufferSetAllocationScheme(buffer
, XML_BUFFER_ALLOC_DOUBLEIT
);
1184 for ( ; node
!= NULL
; node
= node
->next
) {
1185 switch (node
->type
) {
1187 case XML_CDATA_SECTION_NODE
:
1188 xmlBufferCat(buffer
, node
->content
);
1190 case XML_ELEMENT_NODE
: {
1193 tmp
= xmlTextReaderCollectSiblings(node
->children
);
1194 xmlBufferCat(buffer
, tmp
);
1202 ret
= buffer
->content
;
1203 buffer
->content
= NULL
;
1204 xmlBufferFree(buffer
);
1209 * xmlTextReaderRead:
1210 * @reader: the xmlTextReaderPtr used
1212 * Moves the position of the current instance to the next node in
1213 * the stream, exposing its properties.
1215 * Returns 1 if the node was read successfully, 0 if there is no more
1216 * nodes to read, or -1 in case of error
1219 xmlTextReaderRead(xmlTextReaderPtr reader
) {
1220 int val
, olddepth
= 0;
1221 xmlTextReaderState oldstate
= XML_TEXTREADER_START
;
1222 xmlNodePtr oldnode
= NULL
;
1227 reader
->curnode
= NULL
;
1228 if (reader
->doc
!= NULL
)
1229 return(xmlTextReaderReadTree(reader
));
1230 if (reader
->ctxt
== NULL
)
1234 fprintf(stderr
, "\nREAD ");
1237 if (reader
->mode
== XML_TEXTREADER_MODE_INITIAL
) {
1238 reader
->mode
= XML_TEXTREADER_MODE_INTERACTIVE
;
1243 val
= xmlTextReaderPushData(reader
);
1245 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1246 reader
->state
= XML_TEXTREADER_ERROR
;
1249 } while ((reader
->ctxt
->node
== NULL
) &&
1250 ((reader
->mode
!= XML_TEXTREADER_MODE_EOF
) &&
1251 (reader
->state
!= XML_TEXTREADER_DONE
)));
1252 if (reader
->ctxt
->node
== NULL
) {
1253 if (reader
->ctxt
->myDoc
!= NULL
) {
1254 reader
->node
= reader
->ctxt
->myDoc
->children
;
1256 if (reader
->node
== NULL
){
1257 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1258 reader
->state
= XML_TEXTREADER_ERROR
;
1261 reader
->state
= XML_TEXTREADER_ELEMENT
;
1263 if (reader
->ctxt
->myDoc
!= NULL
) {
1264 reader
->node
= reader
->ctxt
->myDoc
->children
;
1266 if (reader
->node
== NULL
)
1267 reader
->node
= reader
->ctxt
->nodeTab
[0];
1268 reader
->state
= XML_TEXTREADER_ELEMENT
;
1271 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
1274 oldstate
= reader
->state
;
1275 olddepth
= reader
->ctxt
->nodeNr
;
1276 oldnode
= reader
->node
;
1279 if (reader
->node
== NULL
) {
1280 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1287 * If we are not backtracking on ancestors or examined nodes,
1288 * that the parser didn't finished or that we aren't at the end
1289 * of stream, continue processing.
1291 while ((reader
->node
!= NULL
) && (reader
->node
->next
== NULL
) &&
1292 (reader
->ctxt
->nodeNr
== olddepth
) &&
1293 ((oldstate
== XML_TEXTREADER_BACKTRACK
) ||
1294 (reader
->node
->children
== NULL
) ||
1295 (reader
->node
->type
== XML_ENTITY_REF_NODE
) ||
1296 ((reader
->node
->children
!= NULL
) &&
1297 (reader
->node
->children
->type
== XML_TEXT_NODE
) &&
1298 (reader
->node
->children
->next
== NULL
)) ||
1299 (reader
->node
->type
== XML_DTD_NODE
) ||
1300 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1301 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) &&
1302 ((reader
->ctxt
->node
== NULL
) ||
1303 (reader
->ctxt
->node
== reader
->node
) ||
1304 (reader
->ctxt
->node
== reader
->node
->parent
)) &&
1305 (reader
->ctxt
->instate
!= XML_PARSER_EOF
)) {
1306 val
= xmlTextReaderPushData(reader
);
1308 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1309 reader
->state
= XML_TEXTREADER_ERROR
;
1312 if (reader
->node
== NULL
)
1315 if (oldstate
!= XML_TEXTREADER_BACKTRACK
) {
1316 if ((reader
->node
->children
!= NULL
) &&
1317 (reader
->node
->type
!= XML_ENTITY_REF_NODE
) &&
1318 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1319 (reader
->node
->type
!= XML_DTD_NODE
)) {
1320 reader
->node
= reader
->node
->children
;
1322 reader
->state
= XML_TEXTREADER_ELEMENT
;
1326 if (reader
->node
->next
!= NULL
) {
1327 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1328 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1329 (reader
->node
->children
== NULL
) &&
1330 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)
1331 #ifdef LIBXML_XINCLUDE_ENABLED
1332 && (reader
->in_xinclude
<= 0)
1335 reader
->state
= XML_TEXTREADER_END
;
1338 #ifdef LIBXML_REGEXP_ENABLED
1339 if ((reader
->validate
) &&
1340 (reader
->node
->type
== XML_ELEMENT_NODE
))
1341 xmlTextReaderValidatePop(reader
);
1342 #endif /* LIBXML_REGEXP_ENABLED */
1343 if ((reader
->preserves
> 0) &&
1344 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1345 reader
->preserves
--;
1346 reader
->node
= reader
->node
->next
;
1347 reader
->state
= XML_TEXTREADER_ELEMENT
;
1350 * Cleanup of the old node
1352 if ((reader
->preserves
== 0) &&
1353 #ifdef LIBXML_XINCLUDE_ENABLED
1354 (reader
->in_xinclude
== 0) &&
1356 (reader
->entNr
== 0) &&
1357 (reader
->node
->prev
!= NULL
) &&
1358 (reader
->node
->prev
->type
!= XML_DTD_NODE
)) {
1359 xmlNodePtr tmp
= reader
->node
->prev
;
1360 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1364 xmlTextReaderFreeNode(reader
, tmp
);
1370 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1371 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1372 (reader
->node
->children
== NULL
) &&
1373 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)) {;
1374 reader
->state
= XML_TEXTREADER_END
;
1377 #ifdef LIBXML_REGEXP_ENABLED
1378 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
->type
== XML_ELEMENT_NODE
))
1379 xmlTextReaderValidatePop(reader
);
1380 #endif /* LIBXML_REGEXP_ENABLED */
1381 if ((reader
->preserves
> 0) &&
1382 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1383 reader
->preserves
--;
1384 reader
->node
= reader
->node
->parent
;
1385 if ((reader
->node
== NULL
) ||
1386 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1387 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) {
1388 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
1389 val
= xmlParseChunk(reader
->ctxt
, "", 0, 1);
1390 reader
->state
= XML_TEXTREADER_DONE
;
1394 reader
->node
= NULL
;
1398 * Cleanup of the old node
1400 if ((oldnode
!= NULL
) && (reader
->preserves
== 0) &&
1401 #ifdef LIBXML_XINCLUDE_ENABLED
1402 (reader
->in_xinclude
== 0) &&
1404 (reader
->entNr
== 0) &&
1405 (oldnode
->type
!= XML_DTD_NODE
) &&
1406 ((oldnode
->extra
& NODE_IS_PRESERVED
) == 0)) {
1407 xmlUnlinkNode(oldnode
);
1408 xmlTextReaderFreeNode(reader
, oldnode
);
1413 if ((reader
->preserves
== 0) &&
1414 #ifdef LIBXML_XINCLUDE_ENABLED
1415 (reader
->in_xinclude
== 0) &&
1417 (reader
->entNr
== 0) &&
1418 (reader
->node
->last
!= NULL
) &&
1419 ((reader
->node
->last
->extra
& NODE_IS_PRESERVED
) == 0)) {
1420 xmlNodePtr tmp
= reader
->node
->last
;
1422 xmlTextReaderFreeNode(reader
, tmp
);
1425 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1431 * If we are in the middle of a piece of CDATA make sure it's finished
1433 if ((reader
->node
!= NULL
) &&
1434 (reader
->node
->next
== NULL
) &&
1435 ((reader
->node
->type
== XML_TEXT_NODE
) ||
1436 (reader
->node
->type
== XML_CDATA_SECTION_NODE
))) {
1437 if (xmlTextReaderExpand(reader
) == NULL
)
1441 #ifdef LIBXML_XINCLUDE_ENABLED
1443 * Handle XInclude if asked for
1445 if ((reader
->xinclude
) && (reader
->in_xinclude
== 0) &&
1446 (reader
->node
!= NULL
) &&
1447 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1448 (reader
->node
->ns
!= NULL
) &&
1449 ((xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_NS
)) ||
1450 (xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_OLD_NS
)))) {
1451 if (reader
->xincctxt
== NULL
) {
1452 reader
->xincctxt
= xmlXIncludeNewContext(reader
->ctxt
->myDoc
);
1453 xmlXIncludeSetFlags(reader
->xincctxt
,
1454 reader
->parserFlags
& (~XML_PARSE_NOXINCNODE
));
1455 xmlXIncludeSetStreamingMode(reader
->xincctxt
, 1);
1458 * expand that node and process it
1460 if (xmlTextReaderExpand(reader
) == NULL
)
1462 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1464 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1465 reader
->in_xinclude
++;
1468 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1469 reader
->in_xinclude
--;
1474 * Handle entities enter and exit when in entity replacement mode
1476 if ((reader
->node
!= NULL
) &&
1477 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1478 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1479 if ((reader
->node
->children
!= NULL
) &&
1480 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1481 (reader
->node
->children
->children
!= NULL
)) {
1482 if (xmlTextReaderEntPush(reader
, reader
->node
) < 0)
1484 reader
->node
= reader
->node
->children
->children
;
1486 #ifdef LIBXML_REGEXP_ENABLED
1487 } else if ((reader
->node
!= NULL
) &&
1488 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1489 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1490 xmlTextReaderValidateEntity(reader
);
1491 #endif /* LIBXML_REGEXP_ENABLED */
1493 if ((reader
->node
!= NULL
) &&
1494 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1495 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1496 reader
->node
= xmlTextReaderEntPop(reader
);
1500 #ifdef LIBXML_REGEXP_ENABLED
1501 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
!= NULL
)) {
1502 xmlNodePtr node
= reader
->node
;
1504 if ((node
->type
== XML_ELEMENT_NODE
) &&
1505 ((reader
->state
!= XML_TEXTREADER_END
) &&
1506 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1507 xmlTextReaderValidatePush(reader
);
1508 } else if ((node
->type
== XML_TEXT_NODE
) ||
1509 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1510 xmlTextReaderValidateCData(reader
, node
->content
,
1511 xmlStrlen(node
->content
));
1514 #endif /* LIBXML_REGEXP_ENABLED */
1515 #ifdef LIBXML_PATTERN_ENABLED
1516 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1517 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1519 for (i
= 0;i
< reader
->patternNr
;i
++) {
1520 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1521 xmlTextReaderPreserve(reader
);
1526 #endif /* LIBXML_PATTERN_ENABLED */
1527 #ifdef LIBXML_SCHEMAS_ENABLED
1528 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1529 (reader
->xsdValidErrors
== 0) &&
1530 (reader
->xsdValidCtxt
!= NULL
)) {
1531 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1533 #endif /* LIBXML_PATTERN_ENABLED */
1536 reader
->state
= XML_TEXTREADER_DONE
;
1541 * xmlTextReaderReadState:
1542 * @reader: the xmlTextReaderPtr used
1544 * Gets the read state of the reader.
1546 * Returns the state value, or -1 in case of error
1549 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1552 return(reader
->mode
);
1556 * xmlTextReaderExpand:
1557 * @reader: the xmlTextReaderPtr used
1559 * Reads the contents of the current node and the full subtree. It then makes
1560 * the subtree available until the next xmlTextReaderRead() call
1562 * Returns a node pointer valid until the next xmlTextReaderRead() call
1563 * or NULL in case of error.
1566 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1567 if ((reader
== NULL
) || (reader
->node
== NULL
))
1569 if (reader
->doc
!= NULL
)
1570 return(reader
->node
);
1571 if (reader
->ctxt
== NULL
)
1573 if (xmlTextReaderDoExpand(reader
) < 0)
1575 return(reader
->node
);
1579 * xmlTextReaderNext:
1580 * @reader: the xmlTextReaderPtr used
1582 * Skip to the node following the current one in document order while
1583 * avoiding the subtree if any.
1585 * Returns 1 if the node was read successfully, 0 if there is no more
1586 * nodes to read, or -1 in case of error
1589 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1595 if (reader
->doc
!= NULL
)
1596 return(xmlTextReaderNextTree(reader
));
1598 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1599 return(xmlTextReaderRead(reader
));
1600 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1601 return(xmlTextReaderRead(reader
));
1602 if (cur
->extra
& NODE_IS_EMPTY
)
1603 return(xmlTextReaderRead(reader
));
1605 ret
= xmlTextReaderRead(reader
);
1608 } while (reader
->node
!= cur
);
1609 return(xmlTextReaderRead(reader
));
1612 #ifdef LIBXML_WRITER_ENABLED
1614 * xmlTextReaderReadInnerXml:
1615 * @reader: the xmlTextReaderPtr used
1617 * Reads the contents of the current node, including child nodes and markup.
1619 * Returns a string containing the XML content, or NULL if the current node
1620 * is neither an element nor attribute, or has no child nodes. The
1621 * string must be deallocated by the caller.
1624 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1627 xmlNodePtr node
, cur_node
;
1628 xmlBufferPtr buff
, buff2
;
1631 if (xmlTextReaderExpand(reader
) == NULL
) {
1634 doc
= reader
->node
->doc
;
1635 buff
= xmlBufferCreate();
1638 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1639 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1640 cur_node
= cur_node
->next
) {
1641 /* XXX: Why is the node copied? */
1642 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1643 /* XXX: Why do we need a second buffer? */
1644 buff2
= xmlBufferCreate();
1645 xmlBufferSetAllocationScheme(buff2
, XML_BUFFER_ALLOC_DOUBLEIT
);
1646 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1648 xmlBufferFree(buff2
);
1649 xmlBufferFree(buff
);
1652 xmlBufferCat(buff
, buff2
->content
);
1654 xmlBufferFree(buff2
);
1656 resbuf
= buff
->content
;
1657 buff
->content
= NULL
;
1659 xmlBufferFree(buff
);
1664 #ifdef LIBXML_WRITER_ENABLED
1666 * xmlTextReaderReadOuterXml:
1667 * @reader: the xmlTextReaderPtr used
1669 * Reads the contents of the current node, including child nodes and markup.
1671 * Returns a string containing the node and any XML content, or NULL if the
1672 * current node cannot be serialized. The string must be deallocated
1676 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1683 if (xmlTextReaderExpand(reader
) == NULL
) {
1686 node
= reader
->node
;
1688 /* XXX: Why is the node copied? */
1689 if (node
->type
== XML_DTD_NODE
) {
1690 node
= (xmlNodePtr
) xmlCopyDtd((xmlDtdPtr
) node
);
1692 node
= xmlDocCopyNode(node
, doc
, 1);
1694 buff
= xmlBufferCreate();
1695 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1696 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1698 xmlBufferFree(buff
);
1702 resbuf
= buff
->content
;
1703 buff
->content
= NULL
;
1706 xmlBufferFree(buff
);
1712 * xmlTextReaderReadString:
1713 * @reader: the xmlTextReaderPtr used
1715 * Reads the contents of an element or a text node as a string.
1717 * Returns a string containing the contents of the Element or Text node,
1718 * or NULL if the reader is positioned on any other type of node.
1719 * The string must be deallocated by the caller.
1722 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1726 if ((reader
== NULL
) || (reader
->node
== NULL
))
1729 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1730 switch (node
->type
) {
1732 if (node
->content
!= NULL
)
1733 return(xmlStrdup(node
->content
));
1735 case XML_ELEMENT_NODE
:
1736 if (xmlTextReaderDoExpand(reader
) != -1) {
1737 return xmlTextReaderCollectSiblings(node
->children
);
1740 case XML_ATTRIBUTE_NODE
:
1751 * xmlTextReaderReadBase64:
1752 * @reader: the xmlTextReaderPtr used
1753 * @array: a byte array to store the content.
1754 * @offset: the zero-based index into array where the method should
1756 * @len: the number of bytes to write.
1758 * Reads and decodes the Base64 encoded contents of an element and
1759 * stores the result in a byte buffer.
1761 * Returns the number of bytes written to array, or zero if the current
1762 * instance is not positioned on an element or -1 in case of error.
1765 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1766 unsigned char *array ATTRIBUTE_UNUSED
,
1767 int offset ATTRIBUTE_UNUSED
,
1768 int len ATTRIBUTE_UNUSED
) {
1769 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1771 if (reader
->ctxt
->wellFormed
!= 1)
1774 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1781 * xmlTextReaderReadBinHex:
1782 * @reader: the xmlTextReaderPtr used
1783 * @array: a byte array to store the content.
1784 * @offset: the zero-based index into array where the method should
1786 * @len: the number of bytes to write.
1788 * Reads and decodes the BinHex encoded contents of an element and
1789 * stores the result in a byte buffer.
1791 * Returns the number of bytes written to array, or zero if the current
1792 * instance is not positioned on an element or -1 in case of error.
1795 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1796 unsigned char *array ATTRIBUTE_UNUSED
,
1797 int offset ATTRIBUTE_UNUSED
,
1798 int len ATTRIBUTE_UNUSED
) {
1799 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1801 if (reader
->ctxt
->wellFormed
!= 1)
1804 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1811 /************************************************************************
1813 * Operating on a preparsed tree *
1815 ************************************************************************/
1817 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1822 if (reader
->state
== XML_TEXTREADER_END
)
1825 if (reader
->node
== NULL
) {
1826 if (reader
->doc
->children
== NULL
) {
1827 reader
->state
= XML_TEXTREADER_END
;
1831 reader
->node
= reader
->doc
->children
;
1832 reader
->state
= XML_TEXTREADER_START
;
1836 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1837 /* Here removed traversal to child, because we want to skip the subtree,
1838 replace with traversal to sibling to skip subtree */
1839 if (reader
->node
->next
!= 0) {
1840 /* Move to sibling if present,skipping sub-tree */
1841 reader
->node
= reader
->node
->next
;
1842 reader
->state
= XML_TEXTREADER_START
;
1846 /* if reader->node->next is NULL mean no subtree for current node,
1847 so need to move to sibling of parent node if present */
1848 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1849 /* This will move to parent if present */
1850 xmlTextReaderRead(reader
);
1853 if (reader
->node
->next
!= 0) {
1854 reader
->node
= reader
->node
->next
;
1855 reader
->state
= XML_TEXTREADER_START
;
1859 if (reader
->node
->parent
!= 0) {
1860 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1861 reader
->state
= XML_TEXTREADER_END
;
1865 reader
->node
= reader
->node
->parent
;
1867 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1868 /* Repeat process to move to sibling of parent node if present */
1869 xmlTextReaderNextTree(reader
);
1872 reader
->state
= XML_TEXTREADER_END
;
1878 * xmlTextReaderReadTree:
1879 * @reader: the xmlTextReaderPtr used
1881 * Moves the position of the current instance to the next node in
1882 * the stream, exposing its properties.
1884 * Returns 1 if the node was read successfully, 0 if there is no more
1885 * nodes to read, or -1 in case of error
1888 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1889 if (reader
->state
== XML_TEXTREADER_END
)
1893 if (reader
->node
== NULL
) {
1894 if (reader
->doc
->children
== NULL
) {
1895 reader
->state
= XML_TEXTREADER_END
;
1899 reader
->node
= reader
->doc
->children
;
1900 reader
->state
= XML_TEXTREADER_START
;
1904 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1905 (reader
->node
->type
!= XML_DTD_NODE
) &&
1906 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1907 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1908 if (reader
->node
->children
!= NULL
) {
1909 reader
->node
= reader
->node
->children
;
1911 reader
->state
= XML_TEXTREADER_START
;
1915 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1916 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1921 if (reader
->node
->next
!= NULL
) {
1922 reader
->node
= reader
->node
->next
;
1923 reader
->state
= XML_TEXTREADER_START
;
1927 if (reader
->node
->parent
!= NULL
) {
1928 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
1929 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
1930 reader
->state
= XML_TEXTREADER_END
;
1934 reader
->node
= reader
->node
->parent
;
1936 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1940 reader
->state
= XML_TEXTREADER_END
;
1943 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
1944 (reader
->node
->type
== XML_XINCLUDE_END
))
1951 * xmlTextReaderNextSibling:
1952 * @reader: the xmlTextReaderPtr used
1954 * Skip to the node following the current one in document order while
1955 * avoiding the subtree if any.
1956 * Currently implemented only for Readers built on a document
1958 * Returns 1 if the node was read successfully, 0 if there is no more
1959 * nodes to read, or -1 in case of error
1962 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
1965 if (reader
->doc
== NULL
) {
1970 if (reader
->state
== XML_TEXTREADER_END
)
1973 if (reader
->node
== NULL
)
1974 return(xmlTextReaderNextTree(reader
));
1976 if (reader
->node
->next
!= NULL
) {
1977 reader
->node
= reader
->node
->next
;
1978 reader
->state
= XML_TEXTREADER_START
;
1985 /************************************************************************
1987 * Constructor and destructors *
1989 ************************************************************************/
1992 * @input: the xmlParserInputBufferPtr used to read data
1993 * @URI: the URI information for the source if available
1995 * Create an xmlTextReader structure fed with @input
1997 * Returns the new xmlTextReaderPtr or NULL in case of error
2000 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2001 xmlTextReaderPtr ret
;
2005 ret
= xmlMalloc(sizeof(xmlTextReader
));
2007 xmlGenericError(xmlGenericErrorContext
,
2008 "xmlNewTextReader : malloc failed\n");
2011 memset(ret
, 0, sizeof(xmlTextReader
));
2017 ret
->buffer
= xmlBufCreateSize(100);
2018 if (ret
->buffer
== NULL
) {
2020 xmlGenericError(xmlGenericErrorContext
,
2021 "xmlNewTextReader : malloc failed\n");
2024 /* no operation on a reader should require a huge buffer */
2025 xmlBufSetAllocationScheme(ret
->buffer
,
2026 XML_BUFFER_ALLOC_DOUBLEIT
);
2027 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2028 if (ret
->sax
== NULL
) {
2029 xmlBufFree(ret
->buffer
);
2031 xmlGenericError(xmlGenericErrorContext
,
2032 "xmlNewTextReader : malloc failed\n");
2035 xmlSAXVersion(ret
->sax
, 2);
2036 ret
->startElement
= ret
->sax
->startElement
;
2037 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2038 ret
->endElement
= ret
->sax
->endElement
;
2039 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2040 #ifdef LIBXML_SAX1_ENABLED
2041 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2042 #endif /* LIBXML_SAX1_ENABLED */
2043 ret
->startElementNs
= ret
->sax
->startElementNs
;
2044 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2045 ret
->endElementNs
= ret
->sax
->endElementNs
;
2046 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2047 #ifdef LIBXML_SAX1_ENABLED
2049 ret
->startElementNs
= NULL
;
2050 ret
->endElementNs
= NULL
;
2052 #endif /* LIBXML_SAX1_ENABLED */
2053 ret
->characters
= ret
->sax
->characters
;
2054 ret
->sax
->characters
= xmlTextReaderCharacters
;
2055 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2056 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2057 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2059 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2061 ret
->curnode
= NULL
;
2062 if (xmlBufUse(ret
->input
->buffer
) < 4) {
2063 xmlParserInputBufferRead(input
, 4);
2065 if (xmlBufUse(ret
->input
->buffer
) >= 4) {
2066 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2067 (const char *) xmlBufContent(ret
->input
->buffer
),
2072 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2077 if (ret
->ctxt
== NULL
) {
2078 xmlGenericError(xmlGenericErrorContext
,
2079 "xmlNewTextReader : malloc failed\n");
2080 xmlBufFree(ret
->buffer
);
2085 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2086 ret
->ctxt
->_private
= ret
;
2087 ret
->ctxt
->linenumbers
= 1;
2088 ret
->ctxt
->dictNames
= 1;
2089 ret
->allocs
= XML_TEXTREADER_CTXT
;
2091 * use the parser dictionary to allocate all elements and attributes names
2093 ret
->ctxt
->docdict
= 1;
2094 ret
->dict
= ret
->ctxt
->dict
;
2095 #ifdef LIBXML_XINCLUDE_ENABLED
2098 #ifdef LIBXML_PATTERN_ENABLED
2099 ret
->patternMax
= 0;
2100 ret
->patternTab
= NULL
;
2106 * xmlNewTextReaderFilename:
2107 * @URI: the URI of the resource to process
2109 * Create an xmlTextReader structure fed with the resource at @URI
2111 * Returns the new xmlTextReaderPtr or NULL in case of error
2114 xmlNewTextReaderFilename(const char *URI
) {
2115 xmlParserInputBufferPtr input
;
2116 xmlTextReaderPtr ret
;
2117 char *directory
= NULL
;
2119 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2122 ret
= xmlNewTextReader(input
, URI
);
2124 xmlFreeParserInputBuffer(input
);
2127 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2128 if (ret
->ctxt
->directory
== NULL
)
2129 directory
= xmlParserGetDirectory(URI
);
2130 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2131 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2132 if (directory
!= NULL
)
2138 * xmlFreeTextReader:
2139 * @reader: the xmlTextReaderPtr
2141 * Deallocate all the resources associated to the reader
2144 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2147 #ifdef LIBXML_SCHEMAS_ENABLED
2148 if (reader
->rngSchemas
!= NULL
) {
2149 xmlRelaxNGFree(reader
->rngSchemas
);
2150 reader
->rngSchemas
= NULL
;
2152 if (reader
->rngValidCtxt
!= NULL
) {
2153 if (! reader
->rngPreserveCtxt
)
2154 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2155 reader
->rngValidCtxt
= NULL
;
2157 if (reader
->xsdPlug
!= NULL
) {
2158 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2159 reader
->xsdPlug
= NULL
;
2161 if (reader
->xsdValidCtxt
!= NULL
) {
2162 if (! reader
->xsdPreserveCtxt
)
2163 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2164 reader
->xsdValidCtxt
= NULL
;
2166 if (reader
->xsdSchemas
!= NULL
) {
2167 xmlSchemaFree(reader
->xsdSchemas
);
2168 reader
->xsdSchemas
= NULL
;
2171 #ifdef LIBXML_XINCLUDE_ENABLED
2172 if (reader
->xincctxt
!= NULL
)
2173 xmlXIncludeFreeContext(reader
->xincctxt
);
2175 #ifdef LIBXML_PATTERN_ENABLED
2176 if (reader
->patternTab
!= NULL
) {
2178 for (i
= 0;i
< reader
->patternNr
;i
++) {
2179 if (reader
->patternTab
[i
] != NULL
)
2180 xmlFreePattern(reader
->patternTab
[i
]);
2182 xmlFree(reader
->patternTab
);
2185 if (reader
->mode
!= XML_TEXTREADER_MODE_CLOSED
)
2186 xmlTextReaderClose(reader
);
2187 if (reader
->ctxt
!= NULL
) {
2188 if (reader
->dict
== reader
->ctxt
->dict
)
2189 reader
->dict
= NULL
;
2190 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2191 xmlFreeParserCtxt(reader
->ctxt
);
2193 if (reader
->sax
!= NULL
)
2194 xmlFree(reader
->sax
);
2195 if (reader
->buffer
!= NULL
)
2196 xmlBufFree(reader
->buffer
);
2197 if (reader
->entTab
!= NULL
)
2198 xmlFree(reader
->entTab
);
2199 if (reader
->dict
!= NULL
)
2200 xmlDictFree(reader
->dict
);
2204 /************************************************************************
2206 * Methods for XmlTextReader *
2208 ************************************************************************/
2210 * xmlTextReaderClose:
2211 * @reader: the xmlTextReaderPtr used
2213 * This method releases any resources allocated by the current instance
2214 * changes the state to Closed and close any underlying input.
2216 * Returns 0 or -1 in case of error
2219 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2222 reader
->node
= NULL
;
2223 reader
->curnode
= NULL
;
2224 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2225 if (reader
->faketext
!= NULL
) {
2226 xmlFreeNode(reader
->faketext
);
2227 reader
->faketext
= NULL
;
2229 if (reader
->ctxt
!= NULL
) {
2230 #ifdef LIBXML_VALID_ENABLED
2231 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2232 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2233 #ifdef LIBXML_REGEXP_ENABLED
2234 while (reader
->ctxt
->vctxt
.vstateNr
> 0)
2235 xmlValidatePopElement(&reader
->ctxt
->vctxt
, NULL
, NULL
, NULL
);
2236 #endif /* LIBXML_REGEXP_ENABLED */
2237 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2238 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2239 reader
->ctxt
->vctxt
.vstateMax
= 0;
2241 #endif /* LIBXML_VALID_ENABLED */
2242 xmlStopParser(reader
->ctxt
);
2243 if (reader
->ctxt
->myDoc
!= NULL
) {
2244 if (reader
->preserve
== 0)
2245 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2246 reader
->ctxt
->myDoc
= NULL
;
2249 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2250 xmlFreeParserInputBuffer(reader
->input
);
2251 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2257 * xmlTextReaderGetAttributeNo:
2258 * @reader: the xmlTextReaderPtr used
2259 * @no: the zero-based index of the attribute relative to the containing element
2261 * Provides the value of the attribute with the specified index relative
2262 * to the containing element.
2264 * Returns a string containing the value of the specified attribute, or NULL
2265 * in case of error. The string must be deallocated by the caller.
2268 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2276 if (reader
->node
== NULL
)
2278 if (reader
->curnode
!= NULL
)
2280 /* TODO: handle the xmlDecl */
2281 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2284 ns
= reader
->node
->nsDef
;
2285 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2289 return(xmlStrdup(ns
->href
));
2291 cur
= reader
->node
->properties
;
2299 /* TODO walk the DTD if present */
2301 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2302 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2307 * xmlTextReaderGetAttribute:
2308 * @reader: the xmlTextReaderPtr used
2309 * @name: the qualified name of the attribute.
2311 * Provides the value of the attribute with the specified qualified name.
2313 * Returns a string containing the value of the specified attribute, or NULL
2314 * in case of error. The string must be deallocated by the caller.
2317 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2318 xmlChar
*prefix
= NULL
;
2321 xmlChar
*ret
= NULL
;
2323 if ((reader
== NULL
) || (name
== NULL
))
2325 if (reader
->node
== NULL
)
2327 if (reader
->curnode
!= NULL
)
2330 /* TODO: handle the xmlDecl */
2331 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2334 localname
= xmlSplitQName2(name
, &prefix
);
2335 if (localname
== NULL
) {
2337 * Namespace default decl
2339 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2340 ns
= reader
->node
->nsDef
;
2341 while (ns
!= NULL
) {
2342 if (ns
->prefix
== NULL
) {
2343 return(xmlStrdup(ns
->href
));
2349 return(xmlGetNoNsProp(reader
->node
, name
));
2353 * Namespace default decl
2355 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2356 ns
= reader
->node
->nsDef
;
2357 while (ns
!= NULL
) {
2358 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2359 ret
= xmlStrdup(ns
->href
);
2365 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2367 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2378 * xmlTextReaderGetAttributeNs:
2379 * @reader: the xmlTextReaderPtr used
2380 * @localName: the local name of the attribute.
2381 * @namespaceURI: the namespace URI of the attribute.
2383 * Provides the value of the specified attribute
2385 * Returns a string containing the value of the specified attribute, or NULL
2386 * in case of error. The string must be deallocated by the caller.
2389 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2390 const xmlChar
*namespaceURI
) {
2391 xmlChar
*prefix
= NULL
;
2394 if ((reader
== NULL
) || (localName
== NULL
))
2396 if (reader
->node
== NULL
)
2398 if (reader
->curnode
!= NULL
)
2401 /* TODO: handle the xmlDecl */
2402 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2405 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2406 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2407 prefix
= BAD_CAST localName
;
2409 ns
= reader
->node
->nsDef
;
2410 while (ns
!= NULL
) {
2411 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2412 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2413 return xmlStrdup(ns
->href
);
2420 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2424 * xmlTextReaderGetRemainder:
2425 * @reader: the xmlTextReaderPtr used
2427 * Method to get the remainder of the buffered XML. this method stops the
2428 * parser, set its state to End Of File and return the input stream with
2429 * what is left that the parser did not use.
2431 * The implementation is not good, the parser certainly progressed past
2432 * what's left in reader->input, and there is an allocation problem. Best
2433 * would be to rewrite it differently.
2435 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2438 xmlParserInputBufferPtr
2439 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2440 xmlParserInputBufferPtr ret
= NULL
;
2444 if (reader
->node
== NULL
)
2447 reader
->node
= NULL
;
2448 reader
->curnode
= NULL
;
2449 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2450 if (reader
->ctxt
!= NULL
) {
2451 xmlStopParser(reader
->ctxt
);
2452 if (reader
->ctxt
->myDoc
!= NULL
) {
2453 if (reader
->preserve
== 0)
2454 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2455 reader
->ctxt
->myDoc
= NULL
;
2458 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2459 ret
= reader
->input
;
2460 reader
->input
= NULL
;
2461 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2464 * Hum, one may need to duplicate the data structure because
2465 * without reference counting the input may be freed twice:
2466 * - by the layer which allocated it.
2467 * - by the layer to which would have been returned to.
2476 * xmlTextReaderLookupNamespace:
2477 * @reader: the xmlTextReaderPtr used
2478 * @prefix: the prefix whose namespace URI is to be resolved. To return
2479 * the default namespace, specify NULL
2481 * Resolves a namespace prefix in the scope of the current element.
2483 * Returns a string containing the namespace URI to which the prefix maps
2484 * or NULL in case of error. The string must be deallocated by the caller.
2487 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2492 if (reader
->node
== NULL
)
2495 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2498 return(xmlStrdup(ns
->href
));
2502 * xmlTextReaderMoveToAttributeNo:
2503 * @reader: the xmlTextReaderPtr used
2504 * @no: the zero-based index of the attribute relative to the containing
2507 * Moves the position of the current instance to the attribute with
2508 * the specified index relative to the containing element.
2510 * Returns 1 in case of success, -1 in case of error, 0 if not found
2513 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2520 if (reader
->node
== NULL
)
2522 /* TODO: handle the xmlDecl */
2523 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2526 reader
->curnode
= NULL
;
2528 ns
= reader
->node
->nsDef
;
2529 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2533 reader
->curnode
= (xmlNodePtr
) ns
;
2537 cur
= reader
->node
->properties
;
2545 /* TODO walk the DTD if present */
2547 reader
->curnode
= (xmlNodePtr
) cur
;
2552 * xmlTextReaderMoveToAttribute:
2553 * @reader: the xmlTextReaderPtr used
2554 * @name: the qualified name of the attribute.
2556 * Moves the position of the current instance to the attribute with
2557 * the specified qualified name.
2559 * Returns 1 in case of success, -1 in case of error, 0 if not found
2562 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2563 xmlChar
*prefix
= NULL
;
2568 if ((reader
== NULL
) || (name
== NULL
))
2570 if (reader
->node
== NULL
)
2573 /* TODO: handle the xmlDecl */
2574 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2577 localname
= xmlSplitQName2(name
, &prefix
);
2578 if (localname
== NULL
) {
2580 * Namespace default decl
2582 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2583 ns
= reader
->node
->nsDef
;
2584 while (ns
!= NULL
) {
2585 if (ns
->prefix
== NULL
) {
2586 reader
->curnode
= (xmlNodePtr
) ns
;
2594 prop
= reader
->node
->properties
;
2595 while (prop
!= NULL
) {
2598 * - same attribute names
2599 * - and the attribute carrying that namespace
2601 if ((xmlStrEqual(prop
->name
, name
)) &&
2602 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2603 reader
->curnode
= (xmlNodePtr
) prop
;
2612 * Namespace default decl
2614 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2615 ns
= reader
->node
->nsDef
;
2616 while (ns
!= NULL
) {
2617 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2618 reader
->curnode
= (xmlNodePtr
) ns
;
2625 prop
= reader
->node
->properties
;
2626 while (prop
!= NULL
) {
2629 * - same attribute names
2630 * - and the attribute carrying that namespace
2632 if ((xmlStrEqual(prop
->name
, localname
)) &&
2633 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2634 reader
->curnode
= (xmlNodePtr
) prop
;
2640 if (localname
!= NULL
)
2647 if (localname
!= NULL
)
2655 * xmlTextReaderMoveToAttributeNs:
2656 * @reader: the xmlTextReaderPtr used
2657 * @localName: the local name of the attribute.
2658 * @namespaceURI: the namespace URI of the attribute.
2660 * Moves the position of the current instance to the attribute with the
2661 * specified local name and namespace URI.
2663 * Returns 1 in case of success, -1 in case of error, 0 if not found
2666 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2667 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2671 xmlChar
*prefix
= NULL
;
2673 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2675 if (reader
->node
== NULL
)
2677 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2679 node
= reader
->node
;
2681 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2682 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2683 prefix
= BAD_CAST localName
;
2685 ns
= reader
->node
->nsDef
;
2686 while (ns
!= NULL
) {
2687 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2688 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2689 reader
->curnode
= (xmlNodePtr
) ns
;
2697 prop
= node
->properties
;
2698 while (prop
!= NULL
) {
2701 * - same attribute names
2702 * - and the attribute carrying that namespace
2704 if (xmlStrEqual(prop
->name
, localName
) &&
2705 ((prop
->ns
!= NULL
) &&
2706 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2707 reader
->curnode
= (xmlNodePtr
) prop
;
2716 * xmlTextReaderMoveToFirstAttribute:
2717 * @reader: the xmlTextReaderPtr used
2719 * Moves the position of the current instance to the first attribute
2720 * associated with the current node.
2722 * Returns 1 in case of success, -1 in case of error, 0 if not found
2725 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2728 if (reader
->node
== NULL
)
2730 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2733 if (reader
->node
->nsDef
!= NULL
) {
2734 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2737 if (reader
->node
->properties
!= NULL
) {
2738 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2745 * xmlTextReaderMoveToNextAttribute:
2746 * @reader: the xmlTextReaderPtr used
2748 * Moves the position of the current instance to the next attribute
2749 * associated with the current node.
2751 * Returns 1 in case of success, -1 in case of error, 0 if not found
2754 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2757 if (reader
->node
== NULL
)
2759 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2761 if (reader
->curnode
== NULL
)
2762 return(xmlTextReaderMoveToFirstAttribute(reader
));
2764 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2765 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2766 if (ns
->next
!= NULL
) {
2767 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2770 if (reader
->node
->properties
!= NULL
) {
2771 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2775 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2776 (reader
->curnode
->next
!= NULL
)) {
2777 reader
->curnode
= reader
->curnode
->next
;
2784 * xmlTextReaderMoveToElement:
2785 * @reader: the xmlTextReaderPtr used
2787 * Moves the position of the current instance to the node that
2788 * contains the current Attribute node.
2790 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2793 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2796 if (reader
->node
== NULL
)
2798 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2800 if (reader
->curnode
!= NULL
) {
2801 reader
->curnode
= NULL
;
2808 * xmlTextReaderReadAttributeValue:
2809 * @reader: the xmlTextReaderPtr used
2811 * Parses an attribute value into one or more Text and EntityReference nodes.
2813 * Returns 1 in case of success, 0 if the reader was not positioned on an
2814 * attribute node or all the attribute values have been read, or -1
2818 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2821 if (reader
->node
== NULL
)
2823 if (reader
->curnode
== NULL
)
2825 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2826 if (reader
->curnode
->children
== NULL
)
2828 reader
->curnode
= reader
->curnode
->children
;
2829 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2830 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2832 if (reader
->faketext
== NULL
) {
2833 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2836 if ((reader
->faketext
->content
!= NULL
) &&
2837 (reader
->faketext
->content
!=
2838 (xmlChar
*) &(reader
->faketext
->properties
)))
2839 xmlFree(reader
->faketext
->content
);
2840 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2842 reader
->curnode
= reader
->faketext
;
2844 if (reader
->curnode
->next
== NULL
)
2846 reader
->curnode
= reader
->curnode
->next
;
2852 * xmlTextReaderConstEncoding:
2853 * @reader: the xmlTextReaderPtr used
2855 * Determine the encoding of the document being read.
2857 * Returns a string containing the encoding of the document or NULL in
2858 * case of error. The string is deallocated with the reader.
2861 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2862 xmlDocPtr doc
= NULL
;
2865 if (reader
->doc
!= NULL
)
2867 else if (reader
->ctxt
!= NULL
)
2868 doc
= reader
->ctxt
->myDoc
;
2872 if (doc
->encoding
== NULL
)
2875 return(CONSTSTR(doc
->encoding
));
2879 /************************************************************************
2881 * Access API to the current node *
2883 ************************************************************************/
2885 * xmlTextReaderAttributeCount:
2886 * @reader: the xmlTextReaderPtr used
2888 * Provides the number of attributes of the current node
2890 * Returns 0 i no attributes, -1 in case of error or the attribute count
2893 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2901 if (reader
->node
== NULL
)
2904 if (reader
->curnode
!= NULL
)
2905 node
= reader
->curnode
;
2907 node
= reader
->node
;
2909 if (node
->type
!= XML_ELEMENT_NODE
)
2911 if ((reader
->state
== XML_TEXTREADER_END
) ||
2912 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2915 attr
= node
->properties
;
2916 while (attr
!= NULL
) {
2921 while (ns
!= NULL
) {
2929 * xmlTextReaderNodeType:
2930 * @reader: the xmlTextReaderPtr used
2932 * Get the node type of the current node
2934 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2936 * Returns the xmlReaderTypes of the current node or -1 in case of error
2939 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
2944 if (reader
->node
== NULL
)
2945 return(XML_READER_TYPE_NONE
);
2946 if (reader
->curnode
!= NULL
)
2947 node
= reader
->curnode
;
2949 node
= reader
->node
;
2950 switch (node
->type
) {
2951 case XML_ELEMENT_NODE
:
2952 if ((reader
->state
== XML_TEXTREADER_END
) ||
2953 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2954 return(XML_READER_TYPE_END_ELEMENT
);
2955 return(XML_READER_TYPE_ELEMENT
);
2956 case XML_NAMESPACE_DECL
:
2957 case XML_ATTRIBUTE_NODE
:
2958 return(XML_READER_TYPE_ATTRIBUTE
);
2960 if (xmlIsBlankNode(reader
->node
)) {
2961 if (xmlNodeGetSpacePreserve(reader
->node
))
2962 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
2964 return(XML_READER_TYPE_WHITESPACE
);
2966 return(XML_READER_TYPE_TEXT
);
2968 case XML_CDATA_SECTION_NODE
:
2969 return(XML_READER_TYPE_CDATA
);
2970 case XML_ENTITY_REF_NODE
:
2971 return(XML_READER_TYPE_ENTITY_REFERENCE
);
2972 case XML_ENTITY_NODE
:
2973 return(XML_READER_TYPE_ENTITY
);
2975 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
2976 case XML_COMMENT_NODE
:
2977 return(XML_READER_TYPE_COMMENT
);
2978 case XML_DOCUMENT_NODE
:
2979 case XML_HTML_DOCUMENT_NODE
:
2980 return(XML_READER_TYPE_DOCUMENT
);
2981 case XML_DOCUMENT_FRAG_NODE
:
2982 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
2983 case XML_NOTATION_NODE
:
2984 return(XML_READER_TYPE_NOTATION
);
2985 case XML_DOCUMENT_TYPE_NODE
:
2987 return(XML_READER_TYPE_DOCUMENT_TYPE
);
2989 case XML_ELEMENT_DECL
:
2990 case XML_ATTRIBUTE_DECL
:
2991 case XML_ENTITY_DECL
:
2992 case XML_XINCLUDE_START
:
2993 case XML_XINCLUDE_END
:
2994 return(XML_READER_TYPE_NONE
);
3000 * xmlTextReaderIsEmptyElement:
3001 * @reader: the xmlTextReaderPtr used
3003 * Check if the current node is empty
3005 * Returns 1 if empty, 0 if not and -1 in case of error
3008 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3009 if ((reader
== NULL
) || (reader
->node
== NULL
))
3011 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3013 if (reader
->curnode
!= NULL
)
3015 if (reader
->node
->children
!= NULL
)
3017 if (reader
->state
== XML_TEXTREADER_END
)
3019 if (reader
->doc
!= NULL
)
3021 #ifdef LIBXML_XINCLUDE_ENABLED
3022 if (reader
->in_xinclude
> 0)
3025 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3029 * xmlTextReaderLocalName:
3030 * @reader: the xmlTextReaderPtr used
3032 * The local name of the node.
3034 * Returns the local name or NULL if not available,
3035 * if non NULL it need to be freed by the caller.
3038 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3040 if ((reader
== NULL
) || (reader
->node
== NULL
))
3042 if (reader
->curnode
!= NULL
)
3043 node
= reader
->curnode
;
3045 node
= reader
->node
;
3046 if (node
->type
== XML_NAMESPACE_DECL
) {
3047 xmlNsPtr ns
= (xmlNsPtr
) node
;
3048 if (ns
->prefix
== NULL
)
3049 return(xmlStrdup(BAD_CAST
"xmlns"));
3051 return(xmlStrdup(ns
->prefix
));
3053 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3054 (node
->type
!= XML_ATTRIBUTE_NODE
))
3055 return(xmlTextReaderName(reader
));
3056 return(xmlStrdup(node
->name
));
3060 * xmlTextReaderConstLocalName:
3061 * @reader: the xmlTextReaderPtr used
3063 * The local name of the node.
3065 * Returns the local name or NULL if not available, the
3066 * string will be deallocated with the reader.
3069 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3071 if ((reader
== NULL
) || (reader
->node
== NULL
))
3073 if (reader
->curnode
!= NULL
)
3074 node
= reader
->curnode
;
3076 node
= reader
->node
;
3077 if (node
->type
== XML_NAMESPACE_DECL
) {
3078 xmlNsPtr ns
= (xmlNsPtr
) node
;
3079 if (ns
->prefix
== NULL
)
3080 return(CONSTSTR(BAD_CAST
"xmlns"));
3084 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3085 (node
->type
!= XML_ATTRIBUTE_NODE
))
3086 return(xmlTextReaderConstName(reader
));
3091 * xmlTextReaderName:
3092 * @reader: the xmlTextReaderPtr used
3094 * The qualified name of the node, equal to Prefix :LocalName.
3096 * Returns the local name or NULL if not available,
3097 * if non NULL it need to be freed by the caller.
3100 xmlTextReaderName(xmlTextReaderPtr reader
) {
3104 if ((reader
== NULL
) || (reader
->node
== NULL
))
3106 if (reader
->curnode
!= NULL
)
3107 node
= reader
->curnode
;
3109 node
= reader
->node
;
3110 switch (node
->type
) {
3111 case XML_ELEMENT_NODE
:
3112 case XML_ATTRIBUTE_NODE
:
3113 if ((node
->ns
== NULL
) ||
3114 (node
->ns
->prefix
== NULL
))
3115 return(xmlStrdup(node
->name
));
3117 ret
= xmlStrdup(node
->ns
->prefix
);
3118 ret
= xmlStrcat(ret
, BAD_CAST
":");
3119 ret
= xmlStrcat(ret
, node
->name
);
3122 return(xmlStrdup(BAD_CAST
"#text"));
3123 case XML_CDATA_SECTION_NODE
:
3124 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3125 case XML_ENTITY_NODE
:
3126 case XML_ENTITY_REF_NODE
:
3127 return(xmlStrdup(node
->name
));
3129 return(xmlStrdup(node
->name
));
3130 case XML_COMMENT_NODE
:
3131 return(xmlStrdup(BAD_CAST
"#comment"));
3132 case XML_DOCUMENT_NODE
:
3133 case XML_HTML_DOCUMENT_NODE
:
3134 return(xmlStrdup(BAD_CAST
"#document"));
3135 case XML_DOCUMENT_FRAG_NODE
:
3136 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3137 case XML_NOTATION_NODE
:
3138 return(xmlStrdup(node
->name
));
3139 case XML_DOCUMENT_TYPE_NODE
:
3141 return(xmlStrdup(node
->name
));
3142 case XML_NAMESPACE_DECL
: {
3143 xmlNsPtr ns
= (xmlNsPtr
) node
;
3145 ret
= xmlStrdup(BAD_CAST
"xmlns");
3146 if (ns
->prefix
== NULL
)
3148 ret
= xmlStrcat(ret
, BAD_CAST
":");
3149 ret
= xmlStrcat(ret
, ns
->prefix
);
3153 case XML_ELEMENT_DECL
:
3154 case XML_ATTRIBUTE_DECL
:
3155 case XML_ENTITY_DECL
:
3156 case XML_XINCLUDE_START
:
3157 case XML_XINCLUDE_END
:
3164 * xmlTextReaderConstName:
3165 * @reader: the xmlTextReaderPtr used
3167 * The qualified name of the node, equal to Prefix :LocalName.
3169 * Returns the local name or NULL if not available, the string is
3170 * deallocated with the reader.
3173 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3176 if ((reader
== NULL
) || (reader
->node
== NULL
))
3178 if (reader
->curnode
!= NULL
)
3179 node
= reader
->curnode
;
3181 node
= reader
->node
;
3182 switch (node
->type
) {
3183 case XML_ELEMENT_NODE
:
3184 case XML_ATTRIBUTE_NODE
:
3185 if ((node
->ns
== NULL
) ||
3186 (node
->ns
->prefix
== NULL
))
3188 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3190 return(CONSTSTR(BAD_CAST
"#text"));
3191 case XML_CDATA_SECTION_NODE
:
3192 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3193 case XML_ENTITY_NODE
:
3194 case XML_ENTITY_REF_NODE
:
3195 return(CONSTSTR(node
->name
));
3197 return(CONSTSTR(node
->name
));
3198 case XML_COMMENT_NODE
:
3199 return(CONSTSTR(BAD_CAST
"#comment"));
3200 case XML_DOCUMENT_NODE
:
3201 case XML_HTML_DOCUMENT_NODE
:
3202 return(CONSTSTR(BAD_CAST
"#document"));
3203 case XML_DOCUMENT_FRAG_NODE
:
3204 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3205 case XML_NOTATION_NODE
:
3206 return(CONSTSTR(node
->name
));
3207 case XML_DOCUMENT_TYPE_NODE
:
3209 return(CONSTSTR(node
->name
));
3210 case XML_NAMESPACE_DECL
: {
3211 xmlNsPtr ns
= (xmlNsPtr
) node
;
3213 if (ns
->prefix
== NULL
)
3214 return(CONSTSTR(BAD_CAST
"xmlns"));
3215 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3218 case XML_ELEMENT_DECL
:
3219 case XML_ATTRIBUTE_DECL
:
3220 case XML_ENTITY_DECL
:
3221 case XML_XINCLUDE_START
:
3222 case XML_XINCLUDE_END
:
3229 * xmlTextReaderPrefix:
3230 * @reader: the xmlTextReaderPtr used
3232 * A shorthand reference to the namespace associated with the node.
3234 * Returns the prefix or NULL if not available,
3235 * if non NULL it need to be freed by the caller.
3238 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3240 if ((reader
== NULL
) || (reader
->node
== NULL
))
3242 if (reader
->curnode
!= NULL
)
3243 node
= reader
->curnode
;
3245 node
= reader
->node
;
3246 if (node
->type
== XML_NAMESPACE_DECL
) {
3247 xmlNsPtr ns
= (xmlNsPtr
) node
;
3248 if (ns
->prefix
== NULL
)
3250 return(xmlStrdup(BAD_CAST
"xmlns"));
3252 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3253 (node
->type
!= XML_ATTRIBUTE_NODE
))
3255 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3256 return(xmlStrdup(node
->ns
->prefix
));
3261 * xmlTextReaderConstPrefix:
3262 * @reader: the xmlTextReaderPtr used
3264 * A shorthand reference to the namespace associated with the node.
3266 * Returns the prefix or NULL if not available, the string is deallocated
3270 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3272 if ((reader
== NULL
) || (reader
->node
== NULL
))
3274 if (reader
->curnode
!= NULL
)
3275 node
= reader
->curnode
;
3277 node
= reader
->node
;
3278 if (node
->type
== XML_NAMESPACE_DECL
) {
3279 xmlNsPtr ns
= (xmlNsPtr
) node
;
3280 if (ns
->prefix
== NULL
)
3282 return(CONSTSTR(BAD_CAST
"xmlns"));
3284 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3285 (node
->type
!= XML_ATTRIBUTE_NODE
))
3287 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3288 return(CONSTSTR(node
->ns
->prefix
));
3293 * xmlTextReaderNamespaceUri:
3294 * @reader: the xmlTextReaderPtr used
3296 * The URI defining the namespace associated with the node.
3298 * Returns the namespace URI or NULL if not available,
3299 * if non NULL it need to be freed by the caller.
3302 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3304 if ((reader
== NULL
) || (reader
->node
== NULL
))
3306 if (reader
->curnode
!= NULL
)
3307 node
= reader
->curnode
;
3309 node
= reader
->node
;
3310 if (node
->type
== XML_NAMESPACE_DECL
)
3311 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3312 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3313 (node
->type
!= XML_ATTRIBUTE_NODE
))
3315 if (node
->ns
!= NULL
)
3316 return(xmlStrdup(node
->ns
->href
));
3321 * xmlTextReaderConstNamespaceUri:
3322 * @reader: the xmlTextReaderPtr used
3324 * The URI defining the namespace associated with the node.
3326 * Returns the namespace URI or NULL if not available, the string
3327 * will be deallocated with the reader
3330 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3332 if ((reader
== NULL
) || (reader
->node
== NULL
))
3334 if (reader
->curnode
!= NULL
)
3335 node
= reader
->curnode
;
3337 node
= reader
->node
;
3338 if (node
->type
== XML_NAMESPACE_DECL
)
3339 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3340 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3341 (node
->type
!= XML_ATTRIBUTE_NODE
))
3343 if (node
->ns
!= NULL
)
3344 return(CONSTSTR(node
->ns
->href
));
3349 * xmlTextReaderBaseUri:
3350 * @reader: the xmlTextReaderPtr used
3352 * The base URI of the node.
3354 * Returns the base URI or NULL if not available,
3355 * if non NULL it need to be freed by the caller.
3358 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3359 if ((reader
== NULL
) || (reader
->node
== NULL
))
3361 return(xmlNodeGetBase(NULL
, reader
->node
));
3365 * xmlTextReaderConstBaseUri:
3366 * @reader: the xmlTextReaderPtr used
3368 * The base URI of the node.
3370 * Returns the base URI or NULL if not available, the string
3371 * will be deallocated with the reader
3374 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3378 if ((reader
== NULL
) || (reader
->node
== NULL
))
3380 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3383 ret
= CONSTSTR(tmp
);
3389 * xmlTextReaderDepth:
3390 * @reader: the xmlTextReaderPtr used
3392 * The depth of the node in the tree.
3394 * Returns the depth or -1 in case of error
3397 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3400 if (reader
->node
== NULL
)
3403 if (reader
->curnode
!= NULL
) {
3404 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3405 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3406 return(reader
->depth
+ 1);
3407 return(reader
->depth
+ 2);
3409 return(reader
->depth
);
3413 * xmlTextReaderHasAttributes:
3414 * @reader: the xmlTextReaderPtr used
3416 * Whether the node has attributes.
3418 * Returns 1 if true, 0 if false, and -1 in case or error
3421 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3425 if (reader
->node
== NULL
)
3427 if (reader
->curnode
!= NULL
)
3428 node
= reader
->curnode
;
3430 node
= reader
->node
;
3432 if ((node
->type
== XML_ELEMENT_NODE
) &&
3433 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3435 /* TODO: handle the xmlDecl */
3440 * xmlTextReaderHasValue:
3441 * @reader: the xmlTextReaderPtr used
3443 * Whether the node can have a text value.
3445 * Returns 1 if true, 0 if false, and -1 in case or error
3448 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3452 if (reader
->node
== NULL
)
3454 if (reader
->curnode
!= NULL
)
3455 node
= reader
->curnode
;
3457 node
= reader
->node
;
3459 switch (node
->type
) {
3460 case XML_ATTRIBUTE_NODE
:
3462 case XML_CDATA_SECTION_NODE
:
3464 case XML_COMMENT_NODE
:
3465 case XML_NAMESPACE_DECL
:
3474 * xmlTextReaderValue:
3475 * @reader: the xmlTextReaderPtr used
3477 * Provides the text value of the node if present
3479 * Returns the string or NULL if not available. The result must be deallocated
3483 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3487 if (reader
->node
== NULL
)
3489 if (reader
->curnode
!= NULL
)
3490 node
= reader
->curnode
;
3492 node
= reader
->node
;
3494 switch (node
->type
) {
3495 case XML_NAMESPACE_DECL
:
3496 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3497 case XML_ATTRIBUTE_NODE
:{
3498 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3500 if (attr
->parent
!= NULL
)
3501 return (xmlNodeListGetString
3502 (attr
->parent
->doc
, attr
->children
, 1));
3504 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3508 case XML_CDATA_SECTION_NODE
:
3510 case XML_COMMENT_NODE
:
3511 if (node
->content
!= NULL
)
3512 return (xmlStrdup(node
->content
));
3520 * xmlTextReaderConstValue:
3521 * @reader: the xmlTextReaderPtr used
3523 * Provides the text value of the node if present
3525 * Returns the string or NULL if not available. The result will be
3526 * deallocated on the next Read() operation.
3529 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3533 if (reader
->node
== NULL
)
3535 if (reader
->curnode
!= NULL
)
3536 node
= reader
->curnode
;
3538 node
= reader
->node
;
3540 switch (node
->type
) {
3541 case XML_NAMESPACE_DECL
:
3542 return(((xmlNsPtr
) node
)->href
);
3543 case XML_ATTRIBUTE_NODE
:{
3544 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3547 if ((attr
->children
!= NULL
) &&
3548 (attr
->children
->type
== XML_TEXT_NODE
) &&
3549 (attr
->children
->next
== NULL
))
3550 return(attr
->children
->content
);
3552 if (reader
->buffer
== NULL
) {
3553 reader
->buffer
= xmlBufCreateSize(100);
3554 if (reader
->buffer
== NULL
) {
3555 xmlGenericError(xmlGenericErrorContext
,
3556 "xmlTextReaderSetup : malloc failed\n");
3559 xmlBufSetAllocationScheme(reader
->buffer
,
3560 XML_BUFFER_ALLOC_DOUBLEIT
);
3562 xmlBufEmpty(reader
->buffer
);
3563 xmlBufGetNodeContent(reader
->buffer
, node
);
3564 ret
= xmlBufContent(reader
->buffer
);
3566 /* error on the buffer best to reallocate */
3567 xmlBufFree(reader
->buffer
);
3568 reader
->buffer
= xmlBufCreateSize(100);
3569 xmlBufSetAllocationScheme(reader
->buffer
,
3570 XML_BUFFER_ALLOC_DOUBLEIT
);
3578 case XML_CDATA_SECTION_NODE
:
3580 case XML_COMMENT_NODE
:
3581 return(node
->content
);
3589 * xmlTextReaderIsDefault:
3590 * @reader: the xmlTextReaderPtr used
3592 * Whether an Attribute node was generated from the default value
3593 * defined in the DTD or schema.
3595 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3598 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3605 * xmlTextReaderQuoteChar:
3606 * @reader: the xmlTextReaderPtr used
3608 * The quotation mark character used to enclose the value of an attribute.
3610 * Returns " or ' and -1 in case of error
3613 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3616 /* TODO maybe lookup the attribute value for " first */
3621 * xmlTextReaderXmlLang:
3622 * @reader: the xmlTextReaderPtr used
3624 * The xml:lang scope within which the node resides.
3626 * Returns the xml:lang value or NULL if none exists.,
3627 * if non NULL it need to be freed by the caller.
3630 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3633 if (reader
->node
== NULL
)
3635 return(xmlNodeGetLang(reader
->node
));
3639 * xmlTextReaderConstXmlLang:
3640 * @reader: the xmlTextReaderPtr used
3642 * The xml:lang scope within which the node resides.
3644 * Returns the xml:lang value or NULL if none exists.
3647 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3653 if (reader
->node
== NULL
)
3655 tmp
= xmlNodeGetLang(reader
->node
);
3658 ret
= CONSTSTR(tmp
);
3664 * xmlTextReaderConstString:
3665 * @reader: the xmlTextReaderPtr used
3666 * @str: the string to intern.
3668 * Get an interned string from the reader, allows for example to
3669 * speedup string name comparisons
3671 * Returns an interned copy of the string or NULL in case of error. The
3672 * string will be deallocated with the reader.
3675 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3678 return(CONSTSTR(str
));
3682 * xmlTextReaderNormalization:
3683 * @reader: the xmlTextReaderPtr used
3685 * The value indicating whether to normalize white space and attribute values.
3686 * Since attribute value and end of line normalizations are a MUST in the XML
3687 * specification only the value true is accepted. The broken behaviour of
3688 * accepting out of range character entities like � is of course not
3691 * Returns 1 or -1 in case of error.
3694 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3700 /************************************************************************
3702 * Extensions to the base APIs *
3704 ************************************************************************/
3707 * xmlTextReaderSetParserProp:
3708 * @reader: the xmlTextReaderPtr used
3709 * @prop: the xmlParserProperties to set
3710 * @value: usually 0 or 1 to (de)activate it
3712 * Change the parser processing behaviour by changing some of its internal
3713 * properties. Note that some properties can only be changed before any
3714 * read has been done.
3716 * Returns 0 if the call was successful, or -1 in case of error
3719 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3720 xmlParserProperties p
= (xmlParserProperties
) prop
;
3721 xmlParserCtxtPtr ctxt
;
3723 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3725 ctxt
= reader
->ctxt
;
3728 case XML_PARSER_LOADDTD
:
3730 if (ctxt
->loadsubset
== 0) {
3731 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3733 ctxt
->loadsubset
= XML_DETECT_IDS
;
3736 ctxt
->loadsubset
= 0;
3739 case XML_PARSER_DEFAULTATTRS
:
3741 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3743 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3744 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3747 case XML_PARSER_VALIDATE
:
3749 ctxt
->options
|= XML_PARSE_DTDVALID
;
3751 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3753 ctxt
->options
&= ~XML_PARSE_DTDVALID
;
3757 case XML_PARSER_SUBST_ENTITIES
:
3759 ctxt
->options
|= XML_PARSE_NOENT
;
3760 ctxt
->replaceEntities
= 1;
3762 ctxt
->options
&= ~XML_PARSE_NOENT
;
3763 ctxt
->replaceEntities
= 0;
3771 * xmlTextReaderGetParserProp:
3772 * @reader: the xmlTextReaderPtr used
3773 * @prop: the xmlParserProperties to get
3775 * Read the parser internal property.
3777 * Returns the value, usually 0 or 1, or -1 in case of error.
3780 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3781 xmlParserProperties p
= (xmlParserProperties
) prop
;
3782 xmlParserCtxtPtr ctxt
;
3784 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3786 ctxt
= reader
->ctxt
;
3789 case XML_PARSER_LOADDTD
:
3790 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3793 case XML_PARSER_DEFAULTATTRS
:
3794 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3797 case XML_PARSER_VALIDATE
:
3798 return(reader
->validate
);
3799 case XML_PARSER_SUBST_ENTITIES
:
3800 return(ctxt
->replaceEntities
);
3807 * xmlTextReaderGetParserLineNumber:
3808 * @reader: the user data (XML reader context)
3810 * Provide the line number of the current parsing point.
3812 * Returns an int or 0 if not available
3815 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3817 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3818 (reader
->ctxt
->input
== NULL
)) {
3821 return (reader
->ctxt
->input
->line
);
3825 * xmlTextReaderGetParserColumnNumber:
3826 * @reader: the user data (XML reader context)
3828 * Provide the column number of the current parsing point.
3830 * Returns an int or 0 if not available
3833 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3835 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3836 (reader
->ctxt
->input
== NULL
)) {
3839 return (reader
->ctxt
->input
->col
);
3843 * xmlTextReaderCurrentNode:
3844 * @reader: the xmlTextReaderPtr used
3846 * Hacking interface allowing to get the xmlNodePtr corresponding to the
3847 * current node being accessed by the xmlTextReader. This is dangerous
3848 * because the underlying node may be destroyed on the next Reads.
3850 * Returns the xmlNodePtr or NULL in case of error.
3853 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3857 if (reader
->curnode
!= NULL
)
3858 return(reader
->curnode
);
3859 return(reader
->node
);
3863 * xmlTextReaderPreserve:
3864 * @reader: the xmlTextReaderPtr used
3866 * This tells the XML Reader to preserve the current node.
3867 * The caller must also use xmlTextReaderCurrentDoc() to
3868 * keep an handle on the resulting document once parsing has finished
3870 * Returns the xmlNodePtr or NULL in case of error.
3873 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3874 xmlNodePtr cur
, parent
;
3879 if (reader
->curnode
!= NULL
)
3880 cur
= reader
->curnode
;
3886 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3887 cur
->extra
|= NODE_IS_PRESERVED
;
3888 cur
->extra
|= NODE_IS_SPRESERVED
;
3890 reader
->preserves
++;
3892 parent
= cur
->parent
;;
3893 while (parent
!= NULL
) {
3894 if (parent
->type
== XML_ELEMENT_NODE
)
3895 parent
->extra
|= NODE_IS_PRESERVED
;
3896 parent
= parent
->parent
;
3901 #ifdef LIBXML_PATTERN_ENABLED
3903 * xmlTextReaderPreservePattern:
3904 * @reader: the xmlTextReaderPtr used
3905 * @pattern: an XPath subset pattern
3906 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3908 * This tells the XML Reader to preserve all nodes matched by the
3909 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3910 * keep an handle on the resulting document once parsing has finished
3912 * Returns a non-negative number in case of success and -1 in case of error
3915 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3916 const xmlChar
**namespaces
)
3920 if ((reader
== NULL
) || (pattern
== NULL
))
3923 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
3927 if (reader
->patternMax
<= 0) {
3928 reader
->patternMax
= 4;
3929 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
3930 sizeof(reader
->patternTab
[0]));
3931 if (reader
->patternTab
== NULL
) {
3932 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
3936 if (reader
->patternNr
>= reader
->patternMax
) {
3938 reader
->patternMax
*= 2;
3939 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
3940 reader
->patternMax
*
3941 sizeof(reader
->patternTab
[0]));
3943 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
3944 reader
->patternMax
/= 2;
3947 reader
->patternTab
= tmp
;
3949 reader
->patternTab
[reader
->patternNr
] = comp
;
3950 return(reader
->patternNr
++);
3955 * xmlTextReaderCurrentDoc:
3956 * @reader: the xmlTextReaderPtr used
3958 * Hacking interface allowing to get the xmlDocPtr corresponding to the
3959 * current document being accessed by the xmlTextReader.
3960 * NOTE: as a result of this call, the reader will not destroy the
3961 * associated XML document and calling xmlFreeDoc() on the result
3962 * is needed once the reader parsing has finished.
3964 * Returns the xmlDocPtr or NULL in case of error.
3967 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
3970 if (reader
->doc
!= NULL
)
3971 return(reader
->doc
);
3972 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
3975 reader
->preserve
= 1;
3976 return(reader
->ctxt
->myDoc
);
3979 #ifdef LIBXML_SCHEMAS_ENABLED
3980 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
) LIBXML_ATTR_FORMAT(1,0);
3982 static void XMLCDECL
3983 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3985 static void XMLCDECL
3986 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3988 static void XMLCDECL
3989 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3991 static void XMLCDECL
3992 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3994 static void XMLCDECL
3995 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
3997 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4004 str
= xmlTextReaderBuildMessage(msg
, ap
);
4005 if (!reader
->errorFunc
) {
4006 xmlTextReaderValidityError(ctx
, "%s", str
);
4008 reader
->errorFunc(reader
->errorFuncArg
, str
,
4009 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4010 NULL
/* locator */ );
4017 static void XMLCDECL
4018 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4020 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4027 str
= xmlTextReaderBuildMessage(msg
, ap
);
4028 if (!reader
->errorFunc
) {
4029 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4031 reader
->errorFunc(reader
->errorFuncArg
, str
,
4032 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4033 NULL
/* locator */ );
4041 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4044 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4046 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4048 if (reader
->sErrorFunc
) {
4049 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4051 xmlTextReaderStructuredError(reader
, error
);
4055 * xmlTextReaderRelaxNGSetSchema:
4056 * @reader: the xmlTextReaderPtr used
4057 * @schema: a precompiled RelaxNG schema
4059 * Use RelaxNG to validate the document as it is processed.
4060 * Activation is only possible before the first Read().
4061 * if @schema is NULL, then RelaxNG validation is deactivated.
4062 @ The @schema should not be freed until the reader is deallocated
4063 * or its use has been deactivated.
4065 * Returns 0 in case the RelaxNG validation could be (de)activated and
4066 * -1 in case of error.
4069 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4072 if (schema
== NULL
) {
4073 if (reader
->rngSchemas
!= NULL
) {
4074 xmlRelaxNGFree(reader
->rngSchemas
);
4075 reader
->rngSchemas
= NULL
;
4077 if (reader
->rngValidCtxt
!= NULL
) {
4078 if (! reader
->rngPreserveCtxt
)
4079 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4080 reader
->rngValidCtxt
= NULL
;
4082 reader
->rngPreserveCtxt
= 0;
4085 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4087 if (reader
->rngSchemas
!= NULL
) {
4088 xmlRelaxNGFree(reader
->rngSchemas
);
4089 reader
->rngSchemas
= NULL
;
4091 if (reader
->rngValidCtxt
!= NULL
) {
4092 if (! reader
->rngPreserveCtxt
)
4093 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4094 reader
->rngValidCtxt
= NULL
;
4096 reader
->rngPreserveCtxt
= 0;
4097 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4098 if (reader
->rngValidCtxt
== NULL
)
4100 if (reader
->errorFunc
!= NULL
) {
4101 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4102 xmlTextReaderValidityErrorRelay
,
4103 xmlTextReaderValidityWarningRelay
,
4106 if (reader
->sErrorFunc
!= NULL
) {
4107 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4108 xmlTextReaderValidityStructuredRelay
,
4111 reader
->rngValidErrors
= 0;
4112 reader
->rngFullNode
= NULL
;
4113 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4118 * xmlTextReaderLocator:
4119 * @ctx: the xmlTextReaderPtr used
4120 * @file: returned file information
4121 * @line: returned line information
4123 * Internal locator function for the readers
4125 * Returns 0 in case the Schema validation could be (de)activated and
4126 * -1 in case of error.
4129 xmlTextReaderLocator(void *ctx
, const char **file
, unsigned long *line
) {
4130 xmlTextReaderPtr reader
;
4132 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
4140 reader
= (xmlTextReaderPtr
) ctx
;
4141 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->input
!= NULL
)) {
4143 *file
= reader
->ctxt
->input
->filename
;
4145 *line
= reader
->ctxt
->input
->line
;
4148 if (reader
->node
!= NULL
) {
4153 res
= xmlGetLineNo(reader
->node
);
4155 *line
= (unsigned long) res
;
4160 xmlDocPtr doc
= reader
->node
->doc
;
4161 if ((doc
!= NULL
) && (doc
->URL
!= NULL
))
4162 *file
= (const char *) doc
->URL
;
4172 * xmlTextReaderSetSchema:
4173 * @reader: the xmlTextReaderPtr used
4174 * @schema: a precompiled Schema schema
4176 * Use XSD Schema to validate the document as it is processed.
4177 * Activation is only possible before the first Read().
4178 * if @schema is NULL, then Schema validation is deactivated.
4179 * The @schema should not be freed until the reader is deallocated
4180 * or its use has been deactivated.
4182 * Returns 0 in case the Schema validation could be (de)activated and
4183 * -1 in case of error.
4186 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4189 if (schema
== NULL
) {
4190 if (reader
->xsdPlug
!= NULL
) {
4191 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4192 reader
->xsdPlug
= NULL
;
4194 if (reader
->xsdValidCtxt
!= NULL
) {
4195 if (! reader
->xsdPreserveCtxt
)
4196 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4197 reader
->xsdValidCtxt
= NULL
;
4199 reader
->xsdPreserveCtxt
= 0;
4200 if (reader
->xsdSchemas
!= NULL
) {
4201 xmlSchemaFree(reader
->xsdSchemas
);
4202 reader
->xsdSchemas
= NULL
;
4206 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4208 if (reader
->xsdPlug
!= NULL
) {
4209 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4210 reader
->xsdPlug
= NULL
;
4212 if (reader
->xsdValidCtxt
!= NULL
) {
4213 if (! reader
->xsdPreserveCtxt
)
4214 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4215 reader
->xsdValidCtxt
= NULL
;
4217 reader
->xsdPreserveCtxt
= 0;
4218 if (reader
->xsdSchemas
!= NULL
) {
4219 xmlSchemaFree(reader
->xsdSchemas
);
4220 reader
->xsdSchemas
= NULL
;
4222 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4223 if (reader
->xsdValidCtxt
== NULL
) {
4224 xmlSchemaFree(reader
->xsdSchemas
);
4225 reader
->xsdSchemas
= NULL
;
4228 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4229 &(reader
->ctxt
->sax
),
4230 &(reader
->ctxt
->userData
));
4231 if (reader
->xsdPlug
== NULL
) {
4232 xmlSchemaFree(reader
->xsdSchemas
);
4233 reader
->xsdSchemas
= NULL
;
4234 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4235 reader
->xsdValidCtxt
= NULL
;
4238 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4239 xmlTextReaderLocator
,
4242 if (reader
->errorFunc
!= NULL
) {
4243 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4244 xmlTextReaderValidityErrorRelay
,
4245 xmlTextReaderValidityWarningRelay
,
4248 if (reader
->sErrorFunc
!= NULL
) {
4249 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4250 xmlTextReaderValidityStructuredRelay
,
4253 reader
->xsdValidErrors
= 0;
4254 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4259 * xmlTextReaderRelaxNGValidateInternal:
4260 * @reader: the xmlTextReaderPtr used
4261 * @rng: the path to a RelaxNG schema or NULL
4262 * @ctxt: the RelaxNG schema validation context or NULL
4263 * @options: options (not yet used)
4265 * Use RelaxNG to validate the document as it is processed.
4266 * Activation is only possible before the first Read().
4267 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
4269 * Returns 0 in case the RelaxNG validation could be (de)activated and
4270 * -1 in case of error.
4273 xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader
,
4275 xmlRelaxNGValidCtxtPtr ctxt
,
4276 int options ATTRIBUTE_UNUSED
)
4281 if ((rng
!= NULL
) && (ctxt
!= NULL
))
4284 if (((rng
!= NULL
) || (ctxt
!= NULL
)) &&
4285 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4286 (reader
->ctxt
== NULL
)))
4289 /* Cleanup previous validation stuff. */
4290 if (reader
->rngValidCtxt
!= NULL
) {
4291 if ( !reader
->rngPreserveCtxt
)
4292 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4293 reader
->rngValidCtxt
= NULL
;
4295 reader
->rngPreserveCtxt
= 0;
4296 if (reader
->rngSchemas
!= NULL
) {
4297 xmlRelaxNGFree(reader
->rngSchemas
);
4298 reader
->rngSchemas
= NULL
;
4301 if ((rng
== NULL
) && (ctxt
== NULL
)) {
4302 /* We just want to deactivate the validation, so get out. */
4308 xmlRelaxNGParserCtxtPtr pctxt
;
4309 /* Parse the schema and create validation environment. */
4311 pctxt
= xmlRelaxNGNewParserCtxt(rng
);
4312 if (reader
->errorFunc
!= NULL
) {
4313 xmlRelaxNGSetParserErrors(pctxt
,
4314 xmlTextReaderValidityErrorRelay
,
4315 xmlTextReaderValidityWarningRelay
,
4318 if (reader
->sErrorFunc
!= NULL
) {
4319 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4320 xmlTextReaderValidityStructuredRelay
,
4323 reader
->rngSchemas
= xmlRelaxNGParse(pctxt
);
4324 xmlRelaxNGFreeParserCtxt(pctxt
);
4325 if (reader
->rngSchemas
== NULL
)
4327 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4328 if (reader
->rngValidCtxt
== NULL
) {
4329 xmlRelaxNGFree(reader
->rngSchemas
);
4330 reader
->rngSchemas
= NULL
;
4334 /* Use the given validation context. */
4335 reader
->rngValidCtxt
= ctxt
;
4336 reader
->rngPreserveCtxt
= 1;
4339 * Redirect the validation context's error channels to use
4340 * the reader channels.
4341 * TODO: In case the user provides the validation context we
4342 * could make this redirection optional.
4344 if (reader
->errorFunc
!= NULL
) {
4345 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4346 xmlTextReaderValidityErrorRelay
,
4347 xmlTextReaderValidityWarningRelay
,
4350 if (reader
->sErrorFunc
!= NULL
) {
4351 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4352 xmlTextReaderValidityStructuredRelay
,
4355 reader
->rngValidErrors
= 0;
4356 reader
->rngFullNode
= NULL
;
4357 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4362 * xmlTextReaderSchemaValidateInternal:
4363 * @reader: the xmlTextReaderPtr used
4364 * @xsd: the path to a W3C XSD schema or NULL
4365 * @ctxt: the XML Schema validation context or NULL
4366 * @options: options (not used yet)
4368 * Validate the document as it is processed using XML Schema.
4369 * Activation is only possible before the first Read().
4370 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4372 * Returns 0 in case the schemas validation could be (de)activated and
4373 * -1 in case of error.
4376 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4378 xmlSchemaValidCtxtPtr ctxt
,
4379 int options ATTRIBUTE_UNUSED
)
4384 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4387 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4388 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4389 (reader
->ctxt
== NULL
)))
4392 /* Cleanup previous validation stuff. */
4393 if (reader
->xsdPlug
!= NULL
) {
4394 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4395 reader
->xsdPlug
= NULL
;
4397 if (reader
->xsdValidCtxt
!= NULL
) {
4398 if (! reader
->xsdPreserveCtxt
)
4399 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4400 reader
->xsdValidCtxt
= NULL
;
4402 reader
->xsdPreserveCtxt
= 0;
4403 if (reader
->xsdSchemas
!= NULL
) {
4404 xmlSchemaFree(reader
->xsdSchemas
);
4405 reader
->xsdSchemas
= NULL
;
4408 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4409 /* We just want to deactivate the validation, so get out. */
4414 xmlSchemaParserCtxtPtr pctxt
;
4415 /* Parse the schema and create validation environment. */
4416 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4417 if (reader
->errorFunc
!= NULL
) {
4418 xmlSchemaSetParserErrors(pctxt
,
4419 xmlTextReaderValidityErrorRelay
,
4420 xmlTextReaderValidityWarningRelay
,
4423 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4424 xmlSchemaFreeParserCtxt(pctxt
);
4425 if (reader
->xsdSchemas
== NULL
)
4427 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4428 if (reader
->xsdValidCtxt
== NULL
) {
4429 xmlSchemaFree(reader
->xsdSchemas
);
4430 reader
->xsdSchemas
= NULL
;
4433 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4434 &(reader
->ctxt
->sax
),
4435 &(reader
->ctxt
->userData
));
4436 if (reader
->xsdPlug
== NULL
) {
4437 xmlSchemaFree(reader
->xsdSchemas
);
4438 reader
->xsdSchemas
= NULL
;
4439 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4440 reader
->xsdValidCtxt
= NULL
;
4444 /* Use the given validation context. */
4445 reader
->xsdValidCtxt
= ctxt
;
4446 reader
->xsdPreserveCtxt
= 1;
4447 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4448 &(reader
->ctxt
->sax
),
4449 &(reader
->ctxt
->userData
));
4450 if (reader
->xsdPlug
== NULL
) {
4451 reader
->xsdValidCtxt
= NULL
;
4452 reader
->xsdPreserveCtxt
= 0;
4456 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4457 xmlTextReaderLocator
,
4460 * Redirect the validation context's error channels to use
4461 * the reader channels.
4462 * TODO: In case the user provides the validation context we
4463 * could make this redirection optional.
4465 if (reader
->errorFunc
!= NULL
) {
4466 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4467 xmlTextReaderValidityErrorRelay
,
4468 xmlTextReaderValidityWarningRelay
,
4471 if (reader
->sErrorFunc
!= NULL
) {
4472 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4473 xmlTextReaderValidityStructuredRelay
,
4476 reader
->xsdValidErrors
= 0;
4477 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4482 * xmlTextReaderSchemaValidateCtxt:
4483 * @reader: the xmlTextReaderPtr used
4484 * @ctxt: the XML Schema validation context or NULL
4485 * @options: options (not used yet)
4487 * Use W3C XSD schema context to validate the document as it is processed.
4488 * Activation is only possible before the first Read().
4489 * If @ctxt is NULL, then XML Schema validation is deactivated.
4491 * Returns 0 in case the schemas validation could be (de)activated and
4492 * -1 in case of error.
4495 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4496 xmlSchemaValidCtxtPtr ctxt
,
4499 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4503 * xmlTextReaderSchemaValidate:
4504 * @reader: the xmlTextReaderPtr used
4505 * @xsd: the path to a W3C XSD schema or NULL
4507 * Use W3C XSD schema to validate the document as it is processed.
4508 * Activation is only possible before the first Read().
4509 * If @xsd is NULL, then XML Schema validation is deactivated.
4511 * Returns 0 in case the schemas validation could be (de)activated and
4512 * -1 in case of error.
4515 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4517 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4521 * xmlTextReaderRelaxNGValidateCtxt:
4522 * @reader: the xmlTextReaderPtr used
4523 * @ctxt: the RelaxNG schema validation context or NULL
4524 * @options: options (not used yet)
4526 * Use RelaxNG schema context to validate the document as it is processed.
4527 * Activation is only possible before the first Read().
4528 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
4530 * Returns 0 in case the schemas validation could be (de)activated and
4531 * -1 in case of error.
4534 xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader
,
4535 xmlRelaxNGValidCtxtPtr ctxt
,
4538 return(xmlTextReaderRelaxNGValidateInternal(reader
, NULL
, ctxt
, options
));
4542 * xmlTextReaderRelaxNGValidate:
4543 * @reader: the xmlTextReaderPtr used
4544 * @rng: the path to a RelaxNG schema or NULL
4546 * Use RelaxNG schema to validate the document as it is processed.
4547 * Activation is only possible before the first Read().
4548 * If @rng is NULL, then RelaxNG schema validation is deactivated.
4550 * Returns 0 in case the schemas validation could be (de)activated and
4551 * -1 in case of error.
4554 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
)
4556 return(xmlTextReaderRelaxNGValidateInternal(reader
, rng
, NULL
, 0));
4562 * xmlTextReaderIsNamespaceDecl:
4563 * @reader: the xmlTextReaderPtr used
4565 * Determine whether the current node is a namespace declaration
4566 * rather than a regular attribute.
4568 * Returns 1 if the current node is a namespace declaration, 0 if it
4569 * is a regular attribute or other type of node, or -1 in case of
4573 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4577 if (reader
->node
== NULL
)
4579 if (reader
->curnode
!= NULL
)
4580 node
= reader
->curnode
;
4582 node
= reader
->node
;
4584 if (XML_NAMESPACE_DECL
== node
->type
)
4591 * xmlTextReaderConstXmlVersion:
4592 * @reader: the xmlTextReaderPtr used
4594 * Determine the XML version of the document being read.
4596 * Returns a string containing the XML version of the document or NULL
4597 * in case of error. The string is deallocated with the reader.
4600 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4601 xmlDocPtr doc
= NULL
;
4604 if (reader
->doc
!= NULL
)
4606 else if (reader
->ctxt
!= NULL
)
4607 doc
= reader
->ctxt
->myDoc
;
4611 if (doc
->version
== NULL
)
4614 return(CONSTSTR(doc
->version
));
4618 * xmlTextReaderStandalone:
4619 * @reader: the xmlTextReaderPtr used
4621 * Determine the standalone status of the document being read.
4623 * Returns 1 if the document was declared to be standalone, 0 if it
4624 * was declared to be not standalone, or -1 if the document did not
4625 * specify its standalone status or in case of error.
4628 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4629 xmlDocPtr doc
= NULL
;
4632 if (reader
->doc
!= NULL
)
4634 else if (reader
->ctxt
!= NULL
)
4635 doc
= reader
->ctxt
->myDoc
;
4639 return(doc
->standalone
);
4642 /************************************************************************
4644 * Error Handling Extensions *
4646 ************************************************************************/
4648 /* helper to build a xmlMalloc'ed string from a format and va_list */
4650 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4659 chars
= vsnprintf(str
, size
, msg
, aq
);
4662 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4667 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4669 if (chars
< MAX_ERR_MSG_SIZE
)
4672 size
= MAX_ERR_MSG_SIZE
;
4673 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4674 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4686 * xmlTextReaderLocatorLineNumber:
4687 * @locator: the xmlTextReaderLocatorPtr used
4689 * Obtain the line number for the given locator.
4691 * Returns the line number or -1 in case of error.
4694 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4695 /* we know that locator is a xmlParserCtxtPtr */
4696 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4699 if (locator
== NULL
)
4701 if (ctx
->node
!= NULL
) {
4702 ret
= xmlGetLineNo(ctx
->node
);
4705 /* inspired from error.c */
4706 xmlParserInputPtr input
;
4708 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4709 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4710 if (input
!= NULL
) {
4722 * xmlTextReaderLocatorBaseURI:
4723 * @locator: the xmlTextReaderLocatorPtr used
4725 * Obtain the base URI for the given locator.
4727 * Returns the base URI or NULL in case of error,
4728 * if non NULL it need to be freed by the caller.
4731 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4732 /* we know that locator is a xmlParserCtxtPtr */
4733 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4734 xmlChar
*ret
= NULL
;
4736 if (locator
== NULL
)
4738 if (ctx
->node
!= NULL
) {
4739 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4742 /* inspired from error.c */
4743 xmlParserInputPtr input
;
4745 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4746 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4747 if (input
!= NULL
) {
4748 ret
= xmlStrdup(BAD_CAST input
->filename
);
4759 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4762 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4764 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4767 if (reader
->errorFunc
)
4768 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4769 (xmlTextReaderLocatorPtr
) ctx
);
4775 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4777 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4779 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4781 if (error
&& reader
->sErrorFunc
) {
4782 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4786 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4787 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4792 xmlTextReaderGenericError(ctxt
,
4793 XML_PARSER_SEVERITY_ERROR
,
4794 xmlTextReaderBuildMessage(msg
, ap
));
4799 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4800 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4805 xmlTextReaderGenericError(ctxt
,
4806 XML_PARSER_SEVERITY_WARNING
,
4807 xmlTextReaderBuildMessage(msg
, ap
));
4811 static void XMLCDECL
4812 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4816 int len
= xmlStrlen((const xmlChar
*) msg
);
4818 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4820 * some callbacks only report locator information:
4821 * skip them (mimicking behaviour in error.c)
4824 xmlTextReaderGenericError(ctxt
,
4825 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4826 xmlTextReaderBuildMessage(msg
, ap
));
4831 static void XMLCDECL
4832 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4836 int len
= xmlStrlen((const xmlChar
*) msg
);
4838 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4840 * some callbacks only report locator information:
4841 * skip them (mimicking behaviour in error.c)
4844 xmlTextReaderGenericError(ctxt
,
4845 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4846 xmlTextReaderBuildMessage(msg
, ap
));
4852 * xmlTextReaderSetErrorHandler:
4853 * @reader: the xmlTextReaderPtr used
4854 * @f: the callback function to call on error and warnings
4855 * @arg: a user argument to pass to the callback function
4857 * Register a callback function that will be called on error and warnings.
4859 * If @f is NULL, the default error and warning handlers are restored.
4862 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4863 xmlTextReaderErrorFunc f
, void *arg
)
4866 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4867 reader
->ctxt
->sax
->serror
= NULL
;
4868 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4869 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4870 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4871 reader
->errorFunc
= f
;
4872 reader
->sErrorFunc
= NULL
;
4873 reader
->errorFuncArg
= arg
;
4874 #ifdef LIBXML_SCHEMAS_ENABLED
4875 if (reader
->rngValidCtxt
) {
4876 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4877 xmlTextReaderValidityErrorRelay
,
4878 xmlTextReaderValidityWarningRelay
,
4880 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4883 if (reader
->xsdValidCtxt
) {
4884 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4885 xmlTextReaderValidityErrorRelay
,
4886 xmlTextReaderValidityWarningRelay
,
4888 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4893 /* restore defaults */
4894 reader
->ctxt
->sax
->error
= xmlParserError
;
4895 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4896 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4897 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4898 reader
->errorFunc
= NULL
;
4899 reader
->sErrorFunc
= NULL
;
4900 reader
->errorFuncArg
= NULL
;
4901 #ifdef LIBXML_SCHEMAS_ENABLED
4902 if (reader
->rngValidCtxt
) {
4903 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4905 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4908 if (reader
->xsdValidCtxt
) {
4909 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4911 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4919 * xmlTextReaderSetStructuredErrorHandler:
4920 * @reader: the xmlTextReaderPtr used
4921 * @f: the callback function to call on error and warnings
4922 * @arg: a user argument to pass to the callback function
4924 * Register a callback function that will be called on error and warnings.
4926 * If @f is NULL, the default error and warning handlers are restored.
4929 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
4930 xmlStructuredErrorFunc f
, void *arg
)
4933 reader
->ctxt
->sax
->error
= NULL
;
4934 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
4935 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4936 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4937 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4938 reader
->sErrorFunc
= f
;
4939 reader
->errorFunc
= NULL
;
4940 reader
->errorFuncArg
= arg
;
4941 #ifdef LIBXML_SCHEMAS_ENABLED
4942 if (reader
->rngValidCtxt
) {
4943 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4945 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4946 xmlTextReaderValidityStructuredRelay
,
4949 if (reader
->xsdValidCtxt
) {
4950 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4952 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4953 xmlTextReaderValidityStructuredRelay
,
4958 /* restore defaults */
4959 reader
->ctxt
->sax
->error
= xmlParserError
;
4960 reader
->ctxt
->sax
->serror
= NULL
;
4961 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4962 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4963 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4964 reader
->errorFunc
= NULL
;
4965 reader
->sErrorFunc
= NULL
;
4966 reader
->errorFuncArg
= NULL
;
4967 #ifdef LIBXML_SCHEMAS_ENABLED
4968 if (reader
->rngValidCtxt
) {
4969 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4971 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4974 if (reader
->xsdValidCtxt
) {
4975 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4977 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4985 * xmlTextReaderIsValid:
4986 * @reader: the xmlTextReaderPtr used
4988 * Retrieve the validity status from the parser context
4990 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
4993 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
4997 #ifdef LIBXML_SCHEMAS_ENABLED
4998 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
4999 return (reader
->rngValidErrors
== 0);
5000 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
5001 return (reader
->xsdValidErrors
== 0);
5003 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
5004 return (reader
->ctxt
->valid
);
5009 * xmlTextReaderGetErrorHandler:
5010 * @reader: the xmlTextReaderPtr used
5011 * @f: the callback function or NULL is no callback has been registered
5012 * @arg: a user argument
5014 * Retrieve the error callback function and user argument.
5017 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
5018 xmlTextReaderErrorFunc
* f
, void **arg
)
5021 *f
= reader
->errorFunc
;
5023 *arg
= reader
->errorFuncArg
;
5025 /************************************************************************
5027 * New set (2.6.0) of simpler and more flexible APIs *
5029 ************************************************************************/
5032 * xmlTextReaderSetup:
5033 * @reader: an XML reader
5034 * @input: xmlParserInputBufferPtr used to feed the reader, will
5035 * be destroyed with it.
5036 * @URL: the base URL to use for the document
5037 * @encoding: the document encoding, or NULL
5038 * @options: a combination of xmlParserOption
5040 * Setup an XML reader with new options
5042 * Returns 0 in case of success and -1 in case of error.
5045 xmlTextReaderSetup(xmlTextReaderPtr reader
,
5046 xmlParserInputBufferPtr input
, const char *URL
,
5047 const char *encoding
, int options
)
5049 if (reader
== NULL
) {
5051 xmlFreeParserInputBuffer(input
);
5056 * we force the generation of compact text nodes on the reader
5057 * since usr applications should never modify the tree
5059 options
|= XML_PARSE_COMPACT
;
5063 reader
->parserFlags
= options
;
5064 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
5065 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
5066 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
5067 xmlFreeParserInputBuffer(reader
->input
);
5068 reader
->input
= NULL
;
5069 reader
->allocs
-= XML_TEXTREADER_INPUT
;
5071 if (input
!= NULL
) {
5072 reader
->input
= input
;
5073 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5075 if (reader
->buffer
== NULL
)
5076 reader
->buffer
= xmlBufCreateSize(100);
5077 if (reader
->buffer
== NULL
) {
5078 xmlGenericError(xmlGenericErrorContext
,
5079 "xmlTextReaderSetup : malloc failed\n");
5082 /* no operation on a reader should require a huge buffer */
5083 xmlBufSetAllocationScheme(reader
->buffer
,
5084 XML_BUFFER_ALLOC_DOUBLEIT
);
5085 if (reader
->sax
== NULL
)
5086 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
5087 if (reader
->sax
== NULL
) {
5088 xmlGenericError(xmlGenericErrorContext
,
5089 "xmlTextReaderSetup : malloc failed\n");
5092 xmlSAXVersion(reader
->sax
, 2);
5093 reader
->startElement
= reader
->sax
->startElement
;
5094 reader
->sax
->startElement
= xmlTextReaderStartElement
;
5095 reader
->endElement
= reader
->sax
->endElement
;
5096 reader
->sax
->endElement
= xmlTextReaderEndElement
;
5097 #ifdef LIBXML_SAX1_ENABLED
5098 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
5099 #endif /* LIBXML_SAX1_ENABLED */
5100 reader
->startElementNs
= reader
->sax
->startElementNs
;
5101 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
5102 reader
->endElementNs
= reader
->sax
->endElementNs
;
5103 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
5104 #ifdef LIBXML_SAX1_ENABLED
5106 reader
->startElementNs
= NULL
;
5107 reader
->endElementNs
= NULL
;
5109 #endif /* LIBXML_SAX1_ENABLED */
5110 reader
->characters
= reader
->sax
->characters
;
5111 reader
->sax
->characters
= xmlTextReaderCharacters
;
5112 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
5113 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
5114 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
5116 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5117 reader
->node
= NULL
;
5118 reader
->curnode
= NULL
;
5119 if (input
!= NULL
) {
5120 if (xmlBufUse(reader
->input
->buffer
) < 4) {
5121 xmlParserInputBufferRead(input
, 4);
5123 if (reader
->ctxt
== NULL
) {
5124 if (xmlBufUse(reader
->input
->buffer
) >= 4) {
5125 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5126 (const char *) xmlBufContent(reader
->input
->buffer
),
5132 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5137 xmlParserInputPtr inputStream
;
5138 xmlParserInputBufferPtr buf
;
5139 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5141 xmlCtxtReset(reader
->ctxt
);
5142 buf
= xmlAllocParserInputBuffer(enc
);
5143 if (buf
== NULL
) return(-1);
5144 inputStream
= xmlNewInputStream(reader
->ctxt
);
5145 if (inputStream
== NULL
) {
5146 xmlFreeParserInputBuffer(buf
);
5151 inputStream
->filename
= NULL
;
5153 inputStream
->filename
= (char *)
5154 xmlCanonicPath((const xmlChar
*) URL
);
5155 inputStream
->buf
= buf
;
5156 xmlBufResetInput(buf
->buffer
, inputStream
);
5158 inputPush(reader
->ctxt
, inputStream
);
5161 if (reader
->ctxt
== NULL
) {
5162 xmlGenericError(xmlGenericErrorContext
,
5163 "xmlTextReaderSetup : malloc failed\n");
5167 if (reader
->dict
!= NULL
) {
5168 if (reader
->ctxt
->dict
!= NULL
) {
5169 if (reader
->dict
!= reader
->ctxt
->dict
) {
5170 xmlDictFree(reader
->dict
);
5171 reader
->dict
= reader
->ctxt
->dict
;
5174 reader
->ctxt
->dict
= reader
->dict
;
5177 if (reader
->ctxt
->dict
== NULL
)
5178 reader
->ctxt
->dict
= xmlDictCreate();
5179 reader
->dict
= reader
->ctxt
->dict
;
5181 reader
->ctxt
->_private
= reader
;
5182 reader
->ctxt
->linenumbers
= 1;
5183 reader
->ctxt
->dictNames
= 1;
5185 * use the parser dictionary to allocate all elements and attributes names
5187 reader
->ctxt
->docdict
= 1;
5188 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5190 #ifdef LIBXML_XINCLUDE_ENABLED
5191 if (reader
->xincctxt
!= NULL
) {
5192 xmlXIncludeFreeContext(reader
->xincctxt
);
5193 reader
->xincctxt
= NULL
;
5195 if (options
& XML_PARSE_XINCLUDE
) {
5196 reader
->xinclude
= 1;
5197 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5198 options
-= XML_PARSE_XINCLUDE
;
5200 reader
->xinclude
= 0;
5201 reader
->in_xinclude
= 0;
5203 #ifdef LIBXML_PATTERN_ENABLED
5204 if (reader
->patternTab
== NULL
) {
5205 reader
->patternNr
= 0;
5206 reader
->patternMax
= 0;
5208 while (reader
->patternNr
> 0) {
5209 reader
->patternNr
--;
5210 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5211 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5212 reader
->patternTab
[reader
->patternNr
] = NULL
;
5217 if (options
& XML_PARSE_DTDVALID
)
5218 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5220 xmlCtxtUseOptions(reader
->ctxt
, options
);
5221 if (encoding
!= NULL
) {
5222 xmlCharEncodingHandlerPtr hdlr
;
5224 hdlr
= xmlFindCharEncodingHandler(encoding
);
5226 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5228 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5229 (reader
->ctxt
->input
->filename
== NULL
))
5230 reader
->ctxt
->input
->filename
= (char *)
5231 xmlStrdup((const xmlChar
*) URL
);
5239 * xmlTextReaderByteConsumed:
5240 * @reader: an XML reader
5242 * This function provides the current index of the parser used
5243 * by the reader, relative to the start of the current entity.
5244 * This function actually just wraps a call to xmlBytesConsumed()
5245 * for the parser context associated with the reader.
5246 * See xmlBytesConsumed() for more information.
5248 * Returns the index in bytes from the beginning of the entity or -1
5249 * in case the index could not be computed.
5252 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5253 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5255 return(xmlByteConsumed(reader
->ctxt
));
5261 * @doc: a preparsed document
5263 * Create an xmltextReader for a preparsed document.
5265 * Returns the new reader or NULL in case of error.
5268 xmlReaderWalker(xmlDocPtr doc
)
5270 xmlTextReaderPtr ret
;
5275 ret
= xmlMalloc(sizeof(xmlTextReader
));
5277 xmlGenericError(xmlGenericErrorContext
,
5278 "xmlNewTextReader : malloc failed\n");
5281 memset(ret
, 0, sizeof(xmlTextReader
));
5284 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5286 ret
->curnode
= NULL
;
5289 ret
->allocs
= XML_TEXTREADER_CTXT
;
5291 ret
->state
= XML_TEXTREADER_START
;
5292 ret
->dict
= xmlDictCreate();
5298 * @cur: a pointer to a zero terminated string
5299 * @URL: the base URL to use for the document
5300 * @encoding: the document encoding, or NULL
5301 * @options: a combination of xmlParserOption
5303 * Create an xmltextReader for an XML in-memory document.
5304 * The parsing flags @options are a combination of xmlParserOption.
5306 * Returns the new reader or NULL in case of error.
5309 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5316 len
= xmlStrlen(cur
);
5318 return (xmlReaderForMemory
5319 ((const char *) cur
, len
, URL
, encoding
, options
));
5324 * @filename: a file or URL
5325 * @encoding: the document encoding, or NULL
5326 * @options: a combination of xmlParserOption
5328 * parse an XML file from the filesystem or the network.
5329 * The parsing flags @options are a combination of xmlParserOption.
5331 * Returns the new reader or NULL in case of error.
5334 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5336 xmlTextReaderPtr reader
;
5338 reader
= xmlNewTextReaderFilename(filename
);
5341 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5346 * xmlReaderForMemory:
5347 * @buffer: a pointer to a char array
5348 * @size: the size of the array
5349 * @URL: the base URL to use for the document
5350 * @encoding: the document encoding, or NULL
5351 * @options: a combination of xmlParserOption
5353 * Create an xmltextReader for an XML in-memory document.
5354 * The parsing flags @options are a combination of xmlParserOption.
5356 * Returns the new reader or NULL in case of error.
5359 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5360 const char *encoding
, int options
)
5362 xmlTextReaderPtr reader
;
5363 xmlParserInputBufferPtr buf
;
5365 buf
= xmlParserInputBufferCreateMem(buffer
, size
, XML_CHAR_ENCODING_NONE
);
5369 reader
= xmlNewTextReader(buf
, URL
);
5370 if (reader
== NULL
) {
5371 xmlFreeParserInputBuffer(buf
);
5374 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5375 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5381 * @fd: an open file descriptor
5382 * @URL: the base URL to use for the document
5383 * @encoding: the document encoding, or NULL
5384 * @options: a combination of xmlParserOption
5386 * Create an xmltextReader for an XML from a file descriptor.
5387 * The parsing flags @options are a combination of xmlParserOption.
5388 * NOTE that the file descriptor will not be closed when the
5389 * reader is closed or reset.
5391 * Returns the new reader or NULL in case of error.
5394 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5396 xmlTextReaderPtr reader
;
5397 xmlParserInputBufferPtr input
;
5402 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5405 input
->closecallback
= NULL
;
5406 reader
= xmlNewTextReader(input
, URL
);
5407 if (reader
== NULL
) {
5408 xmlFreeParserInputBuffer(input
);
5411 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5412 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5418 * @ioread: an I/O read function
5419 * @ioclose: an I/O close function
5420 * @ioctx: an I/O handler
5421 * @URL: the base URL to use for the document
5422 * @encoding: the document encoding, or NULL
5423 * @options: a combination of xmlParserOption
5425 * Create an xmltextReader for an XML document from I/O functions and source.
5426 * The parsing flags @options are a combination of xmlParserOption.
5428 * Returns the new reader or NULL in case of error.
5431 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5432 void *ioctx
, const char *URL
, const char *encoding
,
5435 xmlTextReaderPtr reader
;
5436 xmlParserInputBufferPtr input
;
5441 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5442 XML_CHAR_ENCODING_NONE
);
5443 if (input
== NULL
) {
5444 if (ioclose
!= NULL
)
5448 reader
= xmlNewTextReader(input
, URL
);
5449 if (reader
== NULL
) {
5450 xmlFreeParserInputBuffer(input
);
5453 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5454 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5459 * xmlReaderNewWalker:
5460 * @reader: an XML reader
5461 * @doc: a preparsed document
5463 * Setup an xmltextReader to parse a preparsed XML document.
5464 * This reuses the existing @reader xmlTextReader.
5466 * Returns 0 in case of success and -1 in case of error
5469 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5476 if (reader
->input
!= NULL
) {
5477 xmlFreeParserInputBuffer(reader
->input
);
5479 if (reader
->ctxt
!= NULL
) {
5480 xmlCtxtReset(reader
->ctxt
);
5484 reader
->input
= NULL
;
5485 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5486 reader
->node
= NULL
;
5487 reader
->curnode
= NULL
;
5490 reader
->allocs
= XML_TEXTREADER_CTXT
;
5492 reader
->state
= XML_TEXTREADER_START
;
5493 if (reader
->dict
== NULL
) {
5494 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5495 reader
->dict
= reader
->ctxt
->dict
;
5497 reader
->dict
= xmlDictCreate();
5504 * @reader: an XML reader
5505 * @cur: a pointer to a zero terminated string
5506 * @URL: the base URL to use for the document
5507 * @encoding: the document encoding, or NULL
5508 * @options: a combination of xmlParserOption
5510 * Setup an xmltextReader to parse an XML in-memory document.
5511 * The parsing flags @options are a combination of xmlParserOption.
5512 * This reuses the existing @reader xmlTextReader.
5514 * Returns 0 in case of success and -1 in case of error
5517 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5518 const char *URL
, const char *encoding
, int options
)
5528 len
= xmlStrlen(cur
);
5529 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5530 URL
, encoding
, options
));
5535 * @reader: an XML reader
5536 * @filename: a file or URL
5537 * @encoding: the document encoding, or NULL
5538 * @options: a combination of xmlParserOption
5540 * parse an XML file from the filesystem or the network.
5541 * The parsing flags @options are a combination of xmlParserOption.
5542 * This reuses the existing @reader xmlTextReader.
5544 * Returns 0 in case of success and -1 in case of error
5547 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5548 const char *encoding
, int options
)
5550 xmlParserInputBufferPtr input
;
5552 if (filename
== NULL
)
5558 xmlParserInputBufferCreateFilename(filename
,
5559 XML_CHAR_ENCODING_NONE
);
5562 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5566 * xmlReaderNewMemory:
5567 * @reader: an XML reader
5568 * @buffer: a pointer to a char array
5569 * @size: the size of the array
5570 * @URL: the base URL to use for the document
5571 * @encoding: the document encoding, or NULL
5572 * @options: a combination of xmlParserOption
5574 * Setup an xmltextReader to parse an XML in-memory document.
5575 * The parsing flags @options are a combination of xmlParserOption.
5576 * This reuses the existing @reader xmlTextReader.
5578 * Returns 0 in case of success and -1 in case of error
5581 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5582 const char *URL
, const char *encoding
, int options
)
5584 xmlParserInputBufferPtr input
;
5591 input
= xmlParserInputBufferCreateMem(buffer
, size
,
5592 XML_CHAR_ENCODING_NONE
);
5593 if (input
== NULL
) {
5596 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5601 * @reader: an XML reader
5602 * @fd: an open file descriptor
5603 * @URL: the base URL to use for the document
5604 * @encoding: the document encoding, or NULL
5605 * @options: a combination of xmlParserOption
5607 * Setup an xmltextReader to parse an XML from a file descriptor.
5608 * NOTE that the file descriptor will not be closed when the
5609 * reader is closed or reset.
5610 * The parsing flags @options are a combination of xmlParserOption.
5611 * This reuses the existing @reader xmlTextReader.
5613 * Returns 0 in case of success and -1 in case of error
5616 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5617 const char *URL
, const char *encoding
, int options
)
5619 xmlParserInputBufferPtr input
;
5626 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5629 input
->closecallback
= NULL
;
5630 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5635 * @reader: an XML reader
5636 * @ioread: an I/O read function
5637 * @ioclose: an I/O close function
5638 * @ioctx: an I/O handler
5639 * @URL: the base URL to use for the document
5640 * @encoding: the document encoding, or NULL
5641 * @options: a combination of xmlParserOption
5643 * Setup an xmltextReader to parse an XML document from I/O functions
5645 * The parsing flags @options are a combination of xmlParserOption.
5646 * This reuses the existing @reader xmlTextReader.
5648 * Returns 0 in case of success and -1 in case of error
5651 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5652 xmlInputCloseCallback ioclose
, void *ioctx
,
5653 const char *URL
, const char *encoding
, int options
)
5655 xmlParserInputBufferPtr input
;
5662 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5663 XML_CHAR_ENCODING_NONE
);
5664 if (input
== NULL
) {
5665 if (ioclose
!= NULL
)
5669 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5672 /************************************************************************
5676 ************************************************************************/
5681 * @in: the input buffer
5682 * @inlen: the size of the input (in), the size read from it (out)
5683 * @to: the output buffer
5684 * @tolen: the size of the output (in), the size written to (out)
5686 * Base64 decoder, reads from @in and save in @to
5687 * TODO: tell jody when this is actually exported
5689 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5690 * 2 if there wasn't enough space on the output or -1 in case of error.
5693 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5694 unsigned char *to
, unsigned long *tolen
)
5696 unsigned long incur
; /* current index in in[] */
5698 unsigned long inblk
; /* last block index in in[] */
5700 unsigned long outcur
; /* current index in out[] */
5702 unsigned long inmax
; /* size of in[] */
5704 unsigned long outmax
; /* size of out[] */
5706 unsigned char cur
; /* the current value read from in[] */
5708 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5710 int nbintmp
; /* number of byte in intmp[] */
5712 int is_ignore
; /* cur should be ignored */
5714 int is_end
= 0; /* the end of the base64 was found */
5720 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5735 if ((cur
>= 'A') && (cur
<= 'Z'))
5737 else if ((cur
>= 'a') && (cur
<= 'z'))
5738 cur
= cur
- 'a' + 26;
5739 else if ((cur
>= '0') && (cur
<= '9'))
5740 cur
= cur
- '0' + 52;
5741 else if (cur
== '+')
5743 else if (cur
== '/')
5745 else if (cur
== '.')
5747 else if (cur
== '=') /*no op , end of the base64 stream */
5763 if ((nbintmp
== 1) || (nbintmp
== 2))
5770 intmp
[nbintmp
++] = cur
;
5772 * if intmp is full, push the 4byte sequence as a 3 byte
5777 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5779 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5780 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5781 if (outcur
+ 3 >= outmax
) {
5786 for (i
= 0; i
< nbouttmp
; i
++)
5787 to
[outcur
++] = outtmp
[i
];
5804 * Test routine for the xmlBase64Decode function
5808 main(int argc
, char **argv
)
5810 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5818 unsigned long inlen
= strlen(input
);
5820 unsigned long outlen
= 100;
5824 unsigned long cons
, tmp
, tmp2
, prod
;
5829 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5832 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5833 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5841 while (cons
< inlen
) {
5843 tmp2
= inlen
- cons
;
5845 printf("%ld %ld\n", cons
, prod
);
5846 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5849 printf("%ld %ld\n", cons
, prod
);
5851 output2
[outlen
] = 0;
5852 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5860 while (cons
< inlen
) {
5862 tmp2
= inlen
- cons
;
5866 printf("%ld %ld\n", cons
, prod
);
5867 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5870 printf("%ld %ld\n", cons
, prod
);
5872 output3
[outlen
] = 0;
5873 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5879 #endif /* NOT_USED_YET */
5881 #endif /* LIBXML_READER_ENABLED */