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
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1447 (reader
->node
!= NULL
) &&
1448 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1449 (reader
->node
->ns
!= NULL
) &&
1450 ((xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_NS
)) ||
1451 (xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_OLD_NS
)))) {
1452 if (reader
->xincctxt
== NULL
) {
1453 reader
->xincctxt
= xmlXIncludeNewContext(reader
->ctxt
->myDoc
);
1454 xmlXIncludeSetFlags(reader
->xincctxt
,
1455 reader
->parserFlags
& (~XML_PARSE_NOXINCNODE
));
1456 xmlXIncludeSetStreamingMode(reader
->xincctxt
, 1);
1459 * expand that node and process it
1461 if (xmlTextReaderExpand(reader
) == NULL
)
1463 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1465 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1466 reader
->in_xinclude
++;
1469 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1470 reader
->in_xinclude
--;
1475 * Handle entities enter and exit when in entity replacement mode
1477 if ((reader
->node
!= NULL
) &&
1478 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1479 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1480 if ((reader
->node
->children
!= NULL
) &&
1481 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1482 (reader
->node
->children
->children
!= NULL
)) {
1483 if (xmlTextReaderEntPush(reader
, reader
->node
) < 0)
1485 reader
->node
= reader
->node
->children
->children
;
1487 #ifdef LIBXML_REGEXP_ENABLED
1488 } else if ((reader
->node
!= NULL
) &&
1489 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1490 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1491 xmlTextReaderValidateEntity(reader
);
1492 #endif /* LIBXML_REGEXP_ENABLED */
1494 if ((reader
->node
!= NULL
) &&
1495 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1496 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1497 reader
->node
= xmlTextReaderEntPop(reader
);
1501 #ifdef LIBXML_REGEXP_ENABLED
1502 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
!= NULL
)) {
1503 xmlNodePtr node
= reader
->node
;
1505 if ((node
->type
== XML_ELEMENT_NODE
) &&
1506 ((reader
->state
!= XML_TEXTREADER_END
) &&
1507 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1508 xmlTextReaderValidatePush(reader
);
1509 } else if ((node
->type
== XML_TEXT_NODE
) ||
1510 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1511 xmlTextReaderValidateCData(reader
, node
->content
,
1512 xmlStrlen(node
->content
));
1515 #endif /* LIBXML_REGEXP_ENABLED */
1516 #ifdef LIBXML_PATTERN_ENABLED
1517 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1518 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1520 for (i
= 0;i
< reader
->patternNr
;i
++) {
1521 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1522 xmlTextReaderPreserve(reader
);
1527 #endif /* LIBXML_PATTERN_ENABLED */
1528 #ifdef LIBXML_SCHEMAS_ENABLED
1529 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1530 (reader
->xsdValidErrors
== 0) &&
1531 (reader
->xsdValidCtxt
!= NULL
)) {
1532 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1534 #endif /* LIBXML_PATTERN_ENABLED */
1537 reader
->state
= XML_TEXTREADER_DONE
;
1542 * xmlTextReaderReadState:
1543 * @reader: the xmlTextReaderPtr used
1545 * Gets the read state of the reader.
1547 * Returns the state value, or -1 in case of error
1550 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1553 return(reader
->mode
);
1557 * xmlTextReaderExpand:
1558 * @reader: the xmlTextReaderPtr used
1560 * Reads the contents of the current node and the full subtree. It then makes
1561 * the subtree available until the next xmlTextReaderRead() call
1563 * Returns a node pointer valid until the next xmlTextReaderRead() call
1564 * or NULL in case of error.
1567 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1568 if ((reader
== NULL
) || (reader
->node
== NULL
))
1570 if (reader
->doc
!= NULL
)
1571 return(reader
->node
);
1572 if (reader
->ctxt
== NULL
)
1574 if (xmlTextReaderDoExpand(reader
) < 0)
1576 return(reader
->node
);
1580 * xmlTextReaderNext:
1581 * @reader: the xmlTextReaderPtr used
1583 * Skip to the node following the current one in document order while
1584 * avoiding the subtree if any.
1586 * Returns 1 if the node was read successfully, 0 if there is no more
1587 * nodes to read, or -1 in case of error
1590 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1596 if (reader
->doc
!= NULL
)
1597 return(xmlTextReaderNextTree(reader
));
1599 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1600 return(xmlTextReaderRead(reader
));
1601 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1602 return(xmlTextReaderRead(reader
));
1603 if (cur
->extra
& NODE_IS_EMPTY
)
1604 return(xmlTextReaderRead(reader
));
1606 ret
= xmlTextReaderRead(reader
);
1609 } while (reader
->node
!= cur
);
1610 return(xmlTextReaderRead(reader
));
1613 #ifdef LIBXML_WRITER_ENABLED
1615 * xmlTextReaderReadInnerXml:
1616 * @reader: the xmlTextReaderPtr used
1618 * Reads the contents of the current node, including child nodes and markup.
1620 * Returns a string containing the XML content, or NULL if the current node
1621 * is neither an element nor attribute, or has no child nodes. The
1622 * string must be deallocated by the caller.
1625 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1628 xmlNodePtr node
, cur_node
;
1629 xmlBufferPtr buff
, buff2
;
1632 if (xmlTextReaderExpand(reader
) == NULL
) {
1635 doc
= reader
->node
->doc
;
1636 buff
= xmlBufferCreate();
1639 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1640 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1641 cur_node
= cur_node
->next
) {
1642 /* XXX: Why is the node copied? */
1643 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1644 /* XXX: Why do we need a second buffer? */
1645 buff2
= xmlBufferCreate();
1646 xmlBufferSetAllocationScheme(buff2
, XML_BUFFER_ALLOC_DOUBLEIT
);
1647 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1649 xmlBufferFree(buff2
);
1650 xmlBufferFree(buff
);
1653 xmlBufferCat(buff
, buff2
->content
);
1655 xmlBufferFree(buff2
);
1657 resbuf
= buff
->content
;
1658 buff
->content
= NULL
;
1660 xmlBufferFree(buff
);
1665 #ifdef LIBXML_WRITER_ENABLED
1667 * xmlTextReaderReadOuterXml:
1668 * @reader: the xmlTextReaderPtr used
1670 * Reads the contents of the current node, including child nodes and markup.
1672 * Returns a string containing the node and any XML content, or NULL if the
1673 * current node cannot be serialized. The string must be deallocated
1677 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1684 if (xmlTextReaderExpand(reader
) == NULL
) {
1687 node
= reader
->node
;
1689 /* XXX: Why is the node copied? */
1690 if (node
->type
== XML_DTD_NODE
) {
1691 node
= (xmlNodePtr
) xmlCopyDtd((xmlDtdPtr
) node
);
1693 node
= xmlDocCopyNode(node
, doc
, 1);
1695 buff
= xmlBufferCreate();
1696 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1697 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1699 xmlBufferFree(buff
);
1703 resbuf
= buff
->content
;
1704 buff
->content
= NULL
;
1707 xmlBufferFree(buff
);
1713 * xmlTextReaderReadString:
1714 * @reader: the xmlTextReaderPtr used
1716 * Reads the contents of an element or a text node as a string.
1718 * Returns a string containing the contents of the Element or Text node,
1719 * or NULL if the reader is positioned on any other type of node.
1720 * The string must be deallocated by the caller.
1723 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1727 if ((reader
== NULL
) || (reader
->node
== NULL
))
1730 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1731 switch (node
->type
) {
1733 if (node
->content
!= NULL
)
1734 return(xmlStrdup(node
->content
));
1736 case XML_ELEMENT_NODE
:
1737 if (xmlTextReaderDoExpand(reader
) != -1) {
1738 return xmlTextReaderCollectSiblings(node
->children
);
1741 case XML_ATTRIBUTE_NODE
:
1752 * xmlTextReaderReadBase64:
1753 * @reader: the xmlTextReaderPtr used
1754 * @array: a byte array to store the content.
1755 * @offset: the zero-based index into array where the method should
1757 * @len: the number of bytes to write.
1759 * Reads and decodes the Base64 encoded contents of an element and
1760 * stores the result in a byte buffer.
1762 * Returns the number of bytes written to array, or zero if the current
1763 * instance is not positioned on an element or -1 in case of error.
1766 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1767 unsigned char *array ATTRIBUTE_UNUSED
,
1768 int offset ATTRIBUTE_UNUSED
,
1769 int len ATTRIBUTE_UNUSED
) {
1770 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1772 if (reader
->ctxt
->wellFormed
!= 1)
1775 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1782 * xmlTextReaderReadBinHex:
1783 * @reader: the xmlTextReaderPtr used
1784 * @array: a byte array to store the content.
1785 * @offset: the zero-based index into array where the method should
1787 * @len: the number of bytes to write.
1789 * Reads and decodes the BinHex encoded contents of an element and
1790 * stores the result in a byte buffer.
1792 * Returns the number of bytes written to array, or zero if the current
1793 * instance is not positioned on an element or -1 in case of error.
1796 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1797 unsigned char *array ATTRIBUTE_UNUSED
,
1798 int offset ATTRIBUTE_UNUSED
,
1799 int len ATTRIBUTE_UNUSED
) {
1800 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1802 if (reader
->ctxt
->wellFormed
!= 1)
1805 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1812 /************************************************************************
1814 * Operating on a preparsed tree *
1816 ************************************************************************/
1818 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1823 if (reader
->state
== XML_TEXTREADER_END
)
1826 if (reader
->node
== NULL
) {
1827 if (reader
->doc
->children
== NULL
) {
1828 reader
->state
= XML_TEXTREADER_END
;
1832 reader
->node
= reader
->doc
->children
;
1833 reader
->state
= XML_TEXTREADER_START
;
1837 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1838 /* Here removed traversal to child, because we want to skip the subtree,
1839 replace with traversal to sibling to skip subtree */
1840 if (reader
->node
->next
!= 0) {
1841 /* Move to sibling if present,skipping sub-tree */
1842 reader
->node
= reader
->node
->next
;
1843 reader
->state
= XML_TEXTREADER_START
;
1847 /* if reader->node->next is NULL mean no subtree for current node,
1848 so need to move to sibling of parent node if present */
1849 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1850 /* This will move to parent if present */
1851 xmlTextReaderRead(reader
);
1854 if (reader
->node
->next
!= 0) {
1855 reader
->node
= reader
->node
->next
;
1856 reader
->state
= XML_TEXTREADER_START
;
1860 if (reader
->node
->parent
!= 0) {
1861 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1862 reader
->state
= XML_TEXTREADER_END
;
1866 reader
->node
= reader
->node
->parent
;
1868 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1869 /* Repeat process to move to sibling of parent node if present */
1870 xmlTextReaderNextTree(reader
);
1873 reader
->state
= XML_TEXTREADER_END
;
1879 * xmlTextReaderReadTree:
1880 * @reader: the xmlTextReaderPtr used
1882 * Moves the position of the current instance to the next node in
1883 * the stream, exposing its properties.
1885 * Returns 1 if the node was read successfully, 0 if there is no more
1886 * nodes to read, or -1 in case of error
1889 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1890 if (reader
->state
== XML_TEXTREADER_END
)
1894 if (reader
->node
== NULL
) {
1895 if (reader
->doc
->children
== NULL
) {
1896 reader
->state
= XML_TEXTREADER_END
;
1900 reader
->node
= reader
->doc
->children
;
1901 reader
->state
= XML_TEXTREADER_START
;
1905 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1906 (reader
->node
->type
!= XML_DTD_NODE
) &&
1907 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1908 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1909 if (reader
->node
->children
!= NULL
) {
1910 reader
->node
= reader
->node
->children
;
1912 reader
->state
= XML_TEXTREADER_START
;
1916 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1917 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1922 if (reader
->node
->next
!= NULL
) {
1923 reader
->node
= reader
->node
->next
;
1924 reader
->state
= XML_TEXTREADER_START
;
1928 if (reader
->node
->parent
!= NULL
) {
1929 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
1930 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
1931 reader
->state
= XML_TEXTREADER_END
;
1935 reader
->node
= reader
->node
->parent
;
1937 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1941 reader
->state
= XML_TEXTREADER_END
;
1944 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
1945 (reader
->node
->type
== XML_XINCLUDE_END
))
1952 * xmlTextReaderNextSibling:
1953 * @reader: the xmlTextReaderPtr used
1955 * Skip to the node following the current one in document order while
1956 * avoiding the subtree if any.
1957 * Currently implemented only for Readers built on a document
1959 * Returns 1 if the node was read successfully, 0 if there is no more
1960 * nodes to read, or -1 in case of error
1963 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
1966 if (reader
->doc
== NULL
) {
1971 if (reader
->state
== XML_TEXTREADER_END
)
1974 if (reader
->node
== NULL
)
1975 return(xmlTextReaderNextTree(reader
));
1977 if (reader
->node
->next
!= NULL
) {
1978 reader
->node
= reader
->node
->next
;
1979 reader
->state
= XML_TEXTREADER_START
;
1986 /************************************************************************
1988 * Constructor and destructors *
1990 ************************************************************************/
1993 * @input: the xmlParserInputBufferPtr used to read data
1994 * @URI: the URI information for the source if available
1996 * Create an xmlTextReader structure fed with @input
1998 * Returns the new xmlTextReaderPtr or NULL in case of error
2001 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2002 xmlTextReaderPtr ret
;
2006 ret
= xmlMalloc(sizeof(xmlTextReader
));
2008 xmlGenericError(xmlGenericErrorContext
,
2009 "xmlNewTextReader : malloc failed\n");
2012 memset(ret
, 0, sizeof(xmlTextReader
));
2018 ret
->buffer
= xmlBufCreateSize(100);
2019 if (ret
->buffer
== NULL
) {
2021 xmlGenericError(xmlGenericErrorContext
,
2022 "xmlNewTextReader : malloc failed\n");
2025 /* no operation on a reader should require a huge buffer */
2026 xmlBufSetAllocationScheme(ret
->buffer
,
2027 XML_BUFFER_ALLOC_DOUBLEIT
);
2028 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2029 if (ret
->sax
== NULL
) {
2030 xmlBufFree(ret
->buffer
);
2032 xmlGenericError(xmlGenericErrorContext
,
2033 "xmlNewTextReader : malloc failed\n");
2036 xmlSAXVersion(ret
->sax
, 2);
2037 ret
->startElement
= ret
->sax
->startElement
;
2038 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2039 ret
->endElement
= ret
->sax
->endElement
;
2040 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2041 #ifdef LIBXML_SAX1_ENABLED
2042 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2043 #endif /* LIBXML_SAX1_ENABLED */
2044 ret
->startElementNs
= ret
->sax
->startElementNs
;
2045 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2046 ret
->endElementNs
= ret
->sax
->endElementNs
;
2047 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2048 #ifdef LIBXML_SAX1_ENABLED
2050 ret
->startElementNs
= NULL
;
2051 ret
->endElementNs
= NULL
;
2053 #endif /* LIBXML_SAX1_ENABLED */
2054 ret
->characters
= ret
->sax
->characters
;
2055 ret
->sax
->characters
= xmlTextReaderCharacters
;
2056 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2057 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2058 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2060 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2062 ret
->curnode
= NULL
;
2063 if (xmlBufUse(ret
->input
->buffer
) < 4) {
2064 xmlParserInputBufferRead(input
, 4);
2066 if (xmlBufUse(ret
->input
->buffer
) >= 4) {
2067 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2068 (const char *) xmlBufContent(ret
->input
->buffer
),
2073 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2078 if (ret
->ctxt
== NULL
) {
2079 xmlGenericError(xmlGenericErrorContext
,
2080 "xmlNewTextReader : malloc failed\n");
2081 xmlBufFree(ret
->buffer
);
2086 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2087 ret
->ctxt
->_private
= ret
;
2088 ret
->ctxt
->linenumbers
= 1;
2089 ret
->ctxt
->dictNames
= 1;
2090 ret
->allocs
= XML_TEXTREADER_CTXT
;
2092 * use the parser dictionary to allocate all elements and attributes names
2094 ret
->ctxt
->docdict
= 1;
2095 ret
->dict
= ret
->ctxt
->dict
;
2096 #ifdef LIBXML_XINCLUDE_ENABLED
2099 #ifdef LIBXML_PATTERN_ENABLED
2100 ret
->patternMax
= 0;
2101 ret
->patternTab
= NULL
;
2107 * xmlNewTextReaderFilename:
2108 * @URI: the URI of the resource to process
2110 * Create an xmlTextReader structure fed with the resource at @URI
2112 * Returns the new xmlTextReaderPtr or NULL in case of error
2115 xmlNewTextReaderFilename(const char *URI
) {
2116 xmlParserInputBufferPtr input
;
2117 xmlTextReaderPtr ret
;
2118 char *directory
= NULL
;
2120 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2123 ret
= xmlNewTextReader(input
, URI
);
2125 xmlFreeParserInputBuffer(input
);
2128 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2129 if (ret
->ctxt
->directory
== NULL
)
2130 directory
= xmlParserGetDirectory(URI
);
2131 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2132 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2133 if (directory
!= NULL
)
2139 * xmlFreeTextReader:
2140 * @reader: the xmlTextReaderPtr
2142 * Deallocate all the resources associated to the reader
2145 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2148 #ifdef LIBXML_SCHEMAS_ENABLED
2149 if (reader
->rngSchemas
!= NULL
) {
2150 xmlRelaxNGFree(reader
->rngSchemas
);
2151 reader
->rngSchemas
= NULL
;
2153 if (reader
->rngValidCtxt
!= NULL
) {
2154 if (! reader
->rngPreserveCtxt
)
2155 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2156 reader
->rngValidCtxt
= NULL
;
2158 if (reader
->xsdPlug
!= NULL
) {
2159 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2160 reader
->xsdPlug
= NULL
;
2162 if (reader
->xsdValidCtxt
!= NULL
) {
2163 if (! reader
->xsdPreserveCtxt
)
2164 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2165 reader
->xsdValidCtxt
= NULL
;
2167 if (reader
->xsdSchemas
!= NULL
) {
2168 xmlSchemaFree(reader
->xsdSchemas
);
2169 reader
->xsdSchemas
= NULL
;
2172 #ifdef LIBXML_XINCLUDE_ENABLED
2173 if (reader
->xincctxt
!= NULL
)
2174 xmlXIncludeFreeContext(reader
->xincctxt
);
2176 #ifdef LIBXML_PATTERN_ENABLED
2177 if (reader
->patternTab
!= NULL
) {
2179 for (i
= 0;i
< reader
->patternNr
;i
++) {
2180 if (reader
->patternTab
[i
] != NULL
)
2181 xmlFreePattern(reader
->patternTab
[i
]);
2183 xmlFree(reader
->patternTab
);
2186 if (reader
->mode
!= XML_TEXTREADER_MODE_CLOSED
)
2187 xmlTextReaderClose(reader
);
2188 if (reader
->ctxt
!= NULL
) {
2189 if (reader
->dict
== reader
->ctxt
->dict
)
2190 reader
->dict
= NULL
;
2191 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2192 xmlFreeParserCtxt(reader
->ctxt
);
2194 if (reader
->sax
!= NULL
)
2195 xmlFree(reader
->sax
);
2196 if (reader
->buffer
!= NULL
)
2197 xmlBufFree(reader
->buffer
);
2198 if (reader
->entTab
!= NULL
)
2199 xmlFree(reader
->entTab
);
2200 if (reader
->dict
!= NULL
)
2201 xmlDictFree(reader
->dict
);
2205 /************************************************************************
2207 * Methods for XmlTextReader *
2209 ************************************************************************/
2211 * xmlTextReaderClose:
2212 * @reader: the xmlTextReaderPtr used
2214 * This method releases any resources allocated by the current instance
2215 * changes the state to Closed and close any underlying input.
2217 * Returns 0 or -1 in case of error
2220 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2223 reader
->node
= NULL
;
2224 reader
->curnode
= NULL
;
2225 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2226 if (reader
->faketext
!= NULL
) {
2227 xmlFreeNode(reader
->faketext
);
2228 reader
->faketext
= NULL
;
2230 if (reader
->ctxt
!= NULL
) {
2231 #ifdef LIBXML_VALID_ENABLED
2232 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2233 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2234 #ifdef LIBXML_REGEXP_ENABLED
2235 while (reader
->ctxt
->vctxt
.vstateNr
> 0)
2236 xmlValidatePopElement(&reader
->ctxt
->vctxt
, NULL
, NULL
, NULL
);
2237 #endif /* LIBXML_REGEXP_ENABLED */
2238 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2239 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2240 reader
->ctxt
->vctxt
.vstateMax
= 0;
2242 #endif /* LIBXML_VALID_ENABLED */
2243 xmlStopParser(reader
->ctxt
);
2244 if (reader
->ctxt
->myDoc
!= NULL
) {
2245 if (reader
->preserve
== 0)
2246 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2247 reader
->ctxt
->myDoc
= NULL
;
2250 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2251 xmlFreeParserInputBuffer(reader
->input
);
2252 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2258 * xmlTextReaderGetAttributeNo:
2259 * @reader: the xmlTextReaderPtr used
2260 * @no: the zero-based index of the attribute relative to the containing element
2262 * Provides the value of the attribute with the specified index relative
2263 * to the containing element.
2265 * Returns a string containing the value of the specified attribute, or NULL
2266 * in case of error. The string must be deallocated by the caller.
2269 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2277 if (reader
->node
== NULL
)
2279 if (reader
->curnode
!= NULL
)
2281 /* TODO: handle the xmlDecl */
2282 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2285 ns
= reader
->node
->nsDef
;
2286 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2290 return(xmlStrdup(ns
->href
));
2292 cur
= reader
->node
->properties
;
2300 /* TODO walk the DTD if present */
2302 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2303 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2308 * xmlTextReaderGetAttribute:
2309 * @reader: the xmlTextReaderPtr used
2310 * @name: the qualified name of the attribute.
2312 * Provides the value of the attribute with the specified qualified name.
2314 * Returns a string containing the value of the specified attribute, or NULL
2315 * in case of error. The string must be deallocated by the caller.
2318 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2319 xmlChar
*prefix
= NULL
;
2322 xmlChar
*ret
= NULL
;
2324 if ((reader
== NULL
) || (name
== NULL
))
2326 if (reader
->node
== NULL
)
2328 if (reader
->curnode
!= NULL
)
2331 /* TODO: handle the xmlDecl */
2332 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2335 localname
= xmlSplitQName2(name
, &prefix
);
2336 if (localname
== NULL
) {
2338 * Namespace default decl
2340 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2341 ns
= reader
->node
->nsDef
;
2342 while (ns
!= NULL
) {
2343 if (ns
->prefix
== NULL
) {
2344 return(xmlStrdup(ns
->href
));
2350 return(xmlGetNoNsProp(reader
->node
, name
));
2354 * Namespace default decl
2356 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2357 ns
= reader
->node
->nsDef
;
2358 while (ns
!= NULL
) {
2359 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2360 ret
= xmlStrdup(ns
->href
);
2366 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2368 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2379 * xmlTextReaderGetAttributeNs:
2380 * @reader: the xmlTextReaderPtr used
2381 * @localName: the local name of the attribute.
2382 * @namespaceURI: the namespace URI of the attribute.
2384 * Provides the value of the specified attribute
2386 * Returns a string containing the value of the specified attribute, or NULL
2387 * in case of error. The string must be deallocated by the caller.
2390 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2391 const xmlChar
*namespaceURI
) {
2392 xmlChar
*prefix
= NULL
;
2395 if ((reader
== NULL
) || (localName
== NULL
))
2397 if (reader
->node
== NULL
)
2399 if (reader
->curnode
!= NULL
)
2402 /* TODO: handle the xmlDecl */
2403 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2406 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2407 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2408 prefix
= BAD_CAST localName
;
2410 ns
= reader
->node
->nsDef
;
2411 while (ns
!= NULL
) {
2412 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2413 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2414 return xmlStrdup(ns
->href
);
2421 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2425 * xmlTextReaderGetRemainder:
2426 * @reader: the xmlTextReaderPtr used
2428 * Method to get the remainder of the buffered XML. this method stops the
2429 * parser, set its state to End Of File and return the input stream with
2430 * what is left that the parser did not use.
2432 * The implementation is not good, the parser certainly progressed past
2433 * what's left in reader->input, and there is an allocation problem. Best
2434 * would be to rewrite it differently.
2436 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2439 xmlParserInputBufferPtr
2440 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2441 xmlParserInputBufferPtr ret
= NULL
;
2445 if (reader
->node
== NULL
)
2448 reader
->node
= NULL
;
2449 reader
->curnode
= NULL
;
2450 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2451 if (reader
->ctxt
!= NULL
) {
2452 xmlStopParser(reader
->ctxt
);
2453 if (reader
->ctxt
->myDoc
!= NULL
) {
2454 if (reader
->preserve
== 0)
2455 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2456 reader
->ctxt
->myDoc
= NULL
;
2459 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2460 ret
= reader
->input
;
2461 reader
->input
= NULL
;
2462 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2465 * Hum, one may need to duplicate the data structure because
2466 * without reference counting the input may be freed twice:
2467 * - by the layer which allocated it.
2468 * - by the layer to which would have been returned to.
2477 * xmlTextReaderLookupNamespace:
2478 * @reader: the xmlTextReaderPtr used
2479 * @prefix: the prefix whose namespace URI is to be resolved. To return
2480 * the default namespace, specify NULL
2482 * Resolves a namespace prefix in the scope of the current element.
2484 * Returns a string containing the namespace URI to which the prefix maps
2485 * or NULL in case of error. The string must be deallocated by the caller.
2488 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2493 if (reader
->node
== NULL
)
2496 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2499 return(xmlStrdup(ns
->href
));
2503 * xmlTextReaderMoveToAttributeNo:
2504 * @reader: the xmlTextReaderPtr used
2505 * @no: the zero-based index of the attribute relative to the containing
2508 * Moves the position of the current instance to the attribute with
2509 * the specified index relative to the containing element.
2511 * Returns 1 in case of success, -1 in case of error, 0 if not found
2514 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2521 if (reader
->node
== NULL
)
2523 /* TODO: handle the xmlDecl */
2524 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2527 reader
->curnode
= NULL
;
2529 ns
= reader
->node
->nsDef
;
2530 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2534 reader
->curnode
= (xmlNodePtr
) ns
;
2538 cur
= reader
->node
->properties
;
2546 /* TODO walk the DTD if present */
2548 reader
->curnode
= (xmlNodePtr
) cur
;
2553 * xmlTextReaderMoveToAttribute:
2554 * @reader: the xmlTextReaderPtr used
2555 * @name: the qualified name of the attribute.
2557 * Moves the position of the current instance to the attribute with
2558 * the specified qualified name.
2560 * Returns 1 in case of success, -1 in case of error, 0 if not found
2563 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2564 xmlChar
*prefix
= NULL
;
2569 if ((reader
== NULL
) || (name
== NULL
))
2571 if (reader
->node
== NULL
)
2574 /* TODO: handle the xmlDecl */
2575 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2578 localname
= xmlSplitQName2(name
, &prefix
);
2579 if (localname
== NULL
) {
2581 * Namespace default decl
2583 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2584 ns
= reader
->node
->nsDef
;
2585 while (ns
!= NULL
) {
2586 if (ns
->prefix
== NULL
) {
2587 reader
->curnode
= (xmlNodePtr
) ns
;
2595 prop
= reader
->node
->properties
;
2596 while (prop
!= NULL
) {
2599 * - same attribute names
2600 * - and the attribute carrying that namespace
2602 if ((xmlStrEqual(prop
->name
, name
)) &&
2603 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2604 reader
->curnode
= (xmlNodePtr
) prop
;
2613 * Namespace default decl
2615 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2616 ns
= reader
->node
->nsDef
;
2617 while (ns
!= NULL
) {
2618 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2619 reader
->curnode
= (xmlNodePtr
) ns
;
2626 prop
= reader
->node
->properties
;
2627 while (prop
!= NULL
) {
2630 * - same attribute names
2631 * - and the attribute carrying that namespace
2633 if ((xmlStrEqual(prop
->name
, localname
)) &&
2634 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2635 reader
->curnode
= (xmlNodePtr
) prop
;
2641 if (localname
!= NULL
)
2648 if (localname
!= NULL
)
2656 * xmlTextReaderMoveToAttributeNs:
2657 * @reader: the xmlTextReaderPtr used
2658 * @localName: the local name of the attribute.
2659 * @namespaceURI: the namespace URI of the attribute.
2661 * Moves the position of the current instance to the attribute with the
2662 * specified local name and namespace URI.
2664 * Returns 1 in case of success, -1 in case of error, 0 if not found
2667 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2668 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2672 xmlChar
*prefix
= NULL
;
2674 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2676 if (reader
->node
== NULL
)
2678 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2680 node
= reader
->node
;
2682 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2683 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2684 prefix
= BAD_CAST localName
;
2686 ns
= reader
->node
->nsDef
;
2687 while (ns
!= NULL
) {
2688 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2689 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2690 reader
->curnode
= (xmlNodePtr
) ns
;
2698 prop
= node
->properties
;
2699 while (prop
!= NULL
) {
2702 * - same attribute names
2703 * - and the attribute carrying that namespace
2705 if (xmlStrEqual(prop
->name
, localName
) &&
2706 ((prop
->ns
!= NULL
) &&
2707 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2708 reader
->curnode
= (xmlNodePtr
) prop
;
2717 * xmlTextReaderMoveToFirstAttribute:
2718 * @reader: the xmlTextReaderPtr used
2720 * Moves the position of the current instance to the first attribute
2721 * associated with the current node.
2723 * Returns 1 in case of success, -1 in case of error, 0 if not found
2726 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2729 if (reader
->node
== NULL
)
2731 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2734 if (reader
->node
->nsDef
!= NULL
) {
2735 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2738 if (reader
->node
->properties
!= NULL
) {
2739 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2746 * xmlTextReaderMoveToNextAttribute:
2747 * @reader: the xmlTextReaderPtr used
2749 * Moves the position of the current instance to the next attribute
2750 * associated with the current node.
2752 * Returns 1 in case of success, -1 in case of error, 0 if not found
2755 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2758 if (reader
->node
== NULL
)
2760 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2762 if (reader
->curnode
== NULL
)
2763 return(xmlTextReaderMoveToFirstAttribute(reader
));
2765 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2766 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2767 if (ns
->next
!= NULL
) {
2768 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2771 if (reader
->node
->properties
!= NULL
) {
2772 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2776 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2777 (reader
->curnode
->next
!= NULL
)) {
2778 reader
->curnode
= reader
->curnode
->next
;
2785 * xmlTextReaderMoveToElement:
2786 * @reader: the xmlTextReaderPtr used
2788 * Moves the position of the current instance to the node that
2789 * contains the current Attribute node.
2791 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2794 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2797 if (reader
->node
== NULL
)
2799 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2801 if (reader
->curnode
!= NULL
) {
2802 reader
->curnode
= NULL
;
2809 * xmlTextReaderReadAttributeValue:
2810 * @reader: the xmlTextReaderPtr used
2812 * Parses an attribute value into one or more Text and EntityReference nodes.
2814 * Returns 1 in case of success, 0 if the reader was not positioned on an
2815 * attribute node or all the attribute values have been read, or -1
2819 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2822 if (reader
->node
== NULL
)
2824 if (reader
->curnode
== NULL
)
2826 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2827 if (reader
->curnode
->children
== NULL
)
2829 reader
->curnode
= reader
->curnode
->children
;
2830 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2831 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2833 if (reader
->faketext
== NULL
) {
2834 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2837 if ((reader
->faketext
->content
!= NULL
) &&
2838 (reader
->faketext
->content
!=
2839 (xmlChar
*) &(reader
->faketext
->properties
)))
2840 xmlFree(reader
->faketext
->content
);
2841 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2843 reader
->curnode
= reader
->faketext
;
2845 if (reader
->curnode
->next
== NULL
)
2847 reader
->curnode
= reader
->curnode
->next
;
2853 * xmlTextReaderConstEncoding:
2854 * @reader: the xmlTextReaderPtr used
2856 * Determine the encoding of the document being read.
2858 * Returns a string containing the encoding of the document or NULL in
2859 * case of error. The string is deallocated with the reader.
2862 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2863 xmlDocPtr doc
= NULL
;
2866 if (reader
->doc
!= NULL
)
2868 else if (reader
->ctxt
!= NULL
)
2869 doc
= reader
->ctxt
->myDoc
;
2873 if (doc
->encoding
== NULL
)
2876 return(CONSTSTR(doc
->encoding
));
2880 /************************************************************************
2882 * Access API to the current node *
2884 ************************************************************************/
2886 * xmlTextReaderAttributeCount:
2887 * @reader: the xmlTextReaderPtr used
2889 * Provides the number of attributes of the current node
2891 * Returns 0 i no attributes, -1 in case of error or the attribute count
2894 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2902 if (reader
->node
== NULL
)
2905 if (reader
->curnode
!= NULL
)
2906 node
= reader
->curnode
;
2908 node
= reader
->node
;
2910 if (node
->type
!= XML_ELEMENT_NODE
)
2912 if ((reader
->state
== XML_TEXTREADER_END
) ||
2913 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2916 attr
= node
->properties
;
2917 while (attr
!= NULL
) {
2922 while (ns
!= NULL
) {
2930 * xmlTextReaderNodeType:
2931 * @reader: the xmlTextReaderPtr used
2933 * Get the node type of the current node
2935 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2937 * Returns the xmlReaderTypes of the current node or -1 in case of error
2940 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
2945 if (reader
->node
== NULL
)
2946 return(XML_READER_TYPE_NONE
);
2947 if (reader
->curnode
!= NULL
)
2948 node
= reader
->curnode
;
2950 node
= reader
->node
;
2951 switch (node
->type
) {
2952 case XML_ELEMENT_NODE
:
2953 if ((reader
->state
== XML_TEXTREADER_END
) ||
2954 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2955 return(XML_READER_TYPE_END_ELEMENT
);
2956 return(XML_READER_TYPE_ELEMENT
);
2957 case XML_NAMESPACE_DECL
:
2958 case XML_ATTRIBUTE_NODE
:
2959 return(XML_READER_TYPE_ATTRIBUTE
);
2961 if (xmlIsBlankNode(reader
->node
)) {
2962 if (xmlNodeGetSpacePreserve(reader
->node
))
2963 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
2965 return(XML_READER_TYPE_WHITESPACE
);
2967 return(XML_READER_TYPE_TEXT
);
2969 case XML_CDATA_SECTION_NODE
:
2970 return(XML_READER_TYPE_CDATA
);
2971 case XML_ENTITY_REF_NODE
:
2972 return(XML_READER_TYPE_ENTITY_REFERENCE
);
2973 case XML_ENTITY_NODE
:
2974 return(XML_READER_TYPE_ENTITY
);
2976 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
2977 case XML_COMMENT_NODE
:
2978 return(XML_READER_TYPE_COMMENT
);
2979 case XML_DOCUMENT_NODE
:
2980 case XML_HTML_DOCUMENT_NODE
:
2981 return(XML_READER_TYPE_DOCUMENT
);
2982 case XML_DOCUMENT_FRAG_NODE
:
2983 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
2984 case XML_NOTATION_NODE
:
2985 return(XML_READER_TYPE_NOTATION
);
2986 case XML_DOCUMENT_TYPE_NODE
:
2988 return(XML_READER_TYPE_DOCUMENT_TYPE
);
2990 case XML_ELEMENT_DECL
:
2991 case XML_ATTRIBUTE_DECL
:
2992 case XML_ENTITY_DECL
:
2993 case XML_XINCLUDE_START
:
2994 case XML_XINCLUDE_END
:
2995 return(XML_READER_TYPE_NONE
);
3001 * xmlTextReaderIsEmptyElement:
3002 * @reader: the xmlTextReaderPtr used
3004 * Check if the current node is empty
3006 * Returns 1 if empty, 0 if not and -1 in case of error
3009 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3010 if ((reader
== NULL
) || (reader
->node
== NULL
))
3012 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3014 if (reader
->curnode
!= NULL
)
3016 if (reader
->node
->children
!= NULL
)
3018 if (reader
->state
== XML_TEXTREADER_END
)
3020 if (reader
->doc
!= NULL
)
3022 #ifdef LIBXML_XINCLUDE_ENABLED
3023 if (reader
->in_xinclude
> 0)
3026 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3030 * xmlTextReaderLocalName:
3031 * @reader: the xmlTextReaderPtr used
3033 * The local name of the node.
3035 * Returns the local name or NULL if not available,
3036 * if non NULL it need to be freed by the caller.
3039 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3041 if ((reader
== NULL
) || (reader
->node
== NULL
))
3043 if (reader
->curnode
!= NULL
)
3044 node
= reader
->curnode
;
3046 node
= reader
->node
;
3047 if (node
->type
== XML_NAMESPACE_DECL
) {
3048 xmlNsPtr ns
= (xmlNsPtr
) node
;
3049 if (ns
->prefix
== NULL
)
3050 return(xmlStrdup(BAD_CAST
"xmlns"));
3052 return(xmlStrdup(ns
->prefix
));
3054 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3055 (node
->type
!= XML_ATTRIBUTE_NODE
))
3056 return(xmlTextReaderName(reader
));
3057 return(xmlStrdup(node
->name
));
3061 * xmlTextReaderConstLocalName:
3062 * @reader: the xmlTextReaderPtr used
3064 * The local name of the node.
3066 * Returns the local name or NULL if not available, the
3067 * string will be deallocated with the reader.
3070 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3072 if ((reader
== NULL
) || (reader
->node
== NULL
))
3074 if (reader
->curnode
!= NULL
)
3075 node
= reader
->curnode
;
3077 node
= reader
->node
;
3078 if (node
->type
== XML_NAMESPACE_DECL
) {
3079 xmlNsPtr ns
= (xmlNsPtr
) node
;
3080 if (ns
->prefix
== NULL
)
3081 return(CONSTSTR(BAD_CAST
"xmlns"));
3085 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3086 (node
->type
!= XML_ATTRIBUTE_NODE
))
3087 return(xmlTextReaderConstName(reader
));
3092 * xmlTextReaderName:
3093 * @reader: the xmlTextReaderPtr used
3095 * The qualified name of the node, equal to Prefix :LocalName.
3097 * Returns the local name or NULL if not available,
3098 * if non NULL it need to be freed by the caller.
3101 xmlTextReaderName(xmlTextReaderPtr reader
) {
3105 if ((reader
== NULL
) || (reader
->node
== NULL
))
3107 if (reader
->curnode
!= NULL
)
3108 node
= reader
->curnode
;
3110 node
= reader
->node
;
3111 switch (node
->type
) {
3112 case XML_ELEMENT_NODE
:
3113 case XML_ATTRIBUTE_NODE
:
3114 if ((node
->ns
== NULL
) ||
3115 (node
->ns
->prefix
== NULL
))
3116 return(xmlStrdup(node
->name
));
3118 ret
= xmlStrdup(node
->ns
->prefix
);
3119 ret
= xmlStrcat(ret
, BAD_CAST
":");
3120 ret
= xmlStrcat(ret
, node
->name
);
3123 return(xmlStrdup(BAD_CAST
"#text"));
3124 case XML_CDATA_SECTION_NODE
:
3125 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3126 case XML_ENTITY_NODE
:
3127 case XML_ENTITY_REF_NODE
:
3128 return(xmlStrdup(node
->name
));
3130 return(xmlStrdup(node
->name
));
3131 case XML_COMMENT_NODE
:
3132 return(xmlStrdup(BAD_CAST
"#comment"));
3133 case XML_DOCUMENT_NODE
:
3134 case XML_HTML_DOCUMENT_NODE
:
3135 return(xmlStrdup(BAD_CAST
"#document"));
3136 case XML_DOCUMENT_FRAG_NODE
:
3137 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3138 case XML_NOTATION_NODE
:
3139 return(xmlStrdup(node
->name
));
3140 case XML_DOCUMENT_TYPE_NODE
:
3142 return(xmlStrdup(node
->name
));
3143 case XML_NAMESPACE_DECL
: {
3144 xmlNsPtr ns
= (xmlNsPtr
) node
;
3146 ret
= xmlStrdup(BAD_CAST
"xmlns");
3147 if (ns
->prefix
== NULL
)
3149 ret
= xmlStrcat(ret
, BAD_CAST
":");
3150 ret
= xmlStrcat(ret
, ns
->prefix
);
3154 case XML_ELEMENT_DECL
:
3155 case XML_ATTRIBUTE_DECL
:
3156 case XML_ENTITY_DECL
:
3157 case XML_XINCLUDE_START
:
3158 case XML_XINCLUDE_END
:
3165 * xmlTextReaderConstName:
3166 * @reader: the xmlTextReaderPtr used
3168 * The qualified name of the node, equal to Prefix :LocalName.
3170 * Returns the local name or NULL if not available, the string is
3171 * deallocated with the reader.
3174 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3177 if ((reader
== NULL
) || (reader
->node
== NULL
))
3179 if (reader
->curnode
!= NULL
)
3180 node
= reader
->curnode
;
3182 node
= reader
->node
;
3183 switch (node
->type
) {
3184 case XML_ELEMENT_NODE
:
3185 case XML_ATTRIBUTE_NODE
:
3186 if ((node
->ns
== NULL
) ||
3187 (node
->ns
->prefix
== NULL
))
3189 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3191 return(CONSTSTR(BAD_CAST
"#text"));
3192 case XML_CDATA_SECTION_NODE
:
3193 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3194 case XML_ENTITY_NODE
:
3195 case XML_ENTITY_REF_NODE
:
3196 return(CONSTSTR(node
->name
));
3198 return(CONSTSTR(node
->name
));
3199 case XML_COMMENT_NODE
:
3200 return(CONSTSTR(BAD_CAST
"#comment"));
3201 case XML_DOCUMENT_NODE
:
3202 case XML_HTML_DOCUMENT_NODE
:
3203 return(CONSTSTR(BAD_CAST
"#document"));
3204 case XML_DOCUMENT_FRAG_NODE
:
3205 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3206 case XML_NOTATION_NODE
:
3207 return(CONSTSTR(node
->name
));
3208 case XML_DOCUMENT_TYPE_NODE
:
3210 return(CONSTSTR(node
->name
));
3211 case XML_NAMESPACE_DECL
: {
3212 xmlNsPtr ns
= (xmlNsPtr
) node
;
3214 if (ns
->prefix
== NULL
)
3215 return(CONSTSTR(BAD_CAST
"xmlns"));
3216 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3219 case XML_ELEMENT_DECL
:
3220 case XML_ATTRIBUTE_DECL
:
3221 case XML_ENTITY_DECL
:
3222 case XML_XINCLUDE_START
:
3223 case XML_XINCLUDE_END
:
3230 * xmlTextReaderPrefix:
3231 * @reader: the xmlTextReaderPtr used
3233 * A shorthand reference to the namespace associated with the node.
3235 * Returns the prefix or NULL if not available,
3236 * if non NULL it need to be freed by the caller.
3239 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3241 if ((reader
== NULL
) || (reader
->node
== NULL
))
3243 if (reader
->curnode
!= NULL
)
3244 node
= reader
->curnode
;
3246 node
= reader
->node
;
3247 if (node
->type
== XML_NAMESPACE_DECL
) {
3248 xmlNsPtr ns
= (xmlNsPtr
) node
;
3249 if (ns
->prefix
== NULL
)
3251 return(xmlStrdup(BAD_CAST
"xmlns"));
3253 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3254 (node
->type
!= XML_ATTRIBUTE_NODE
))
3256 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3257 return(xmlStrdup(node
->ns
->prefix
));
3262 * xmlTextReaderConstPrefix:
3263 * @reader: the xmlTextReaderPtr used
3265 * A shorthand reference to the namespace associated with the node.
3267 * Returns the prefix or NULL if not available, the string is deallocated
3271 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3273 if ((reader
== NULL
) || (reader
->node
== NULL
))
3275 if (reader
->curnode
!= NULL
)
3276 node
= reader
->curnode
;
3278 node
= reader
->node
;
3279 if (node
->type
== XML_NAMESPACE_DECL
) {
3280 xmlNsPtr ns
= (xmlNsPtr
) node
;
3281 if (ns
->prefix
== NULL
)
3283 return(CONSTSTR(BAD_CAST
"xmlns"));
3285 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3286 (node
->type
!= XML_ATTRIBUTE_NODE
))
3288 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3289 return(CONSTSTR(node
->ns
->prefix
));
3294 * xmlTextReaderNamespaceUri:
3295 * @reader: the xmlTextReaderPtr used
3297 * The URI defining the namespace associated with the node.
3299 * Returns the namespace URI or NULL if not available,
3300 * if non NULL it need to be freed by the caller.
3303 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3305 if ((reader
== NULL
) || (reader
->node
== NULL
))
3307 if (reader
->curnode
!= NULL
)
3308 node
= reader
->curnode
;
3310 node
= reader
->node
;
3311 if (node
->type
== XML_NAMESPACE_DECL
)
3312 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3313 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3314 (node
->type
!= XML_ATTRIBUTE_NODE
))
3316 if (node
->ns
!= NULL
)
3317 return(xmlStrdup(node
->ns
->href
));
3322 * xmlTextReaderConstNamespaceUri:
3323 * @reader: the xmlTextReaderPtr used
3325 * The URI defining the namespace associated with the node.
3327 * Returns the namespace URI or NULL if not available, the string
3328 * will be deallocated with the reader
3331 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3333 if ((reader
== NULL
) || (reader
->node
== NULL
))
3335 if (reader
->curnode
!= NULL
)
3336 node
= reader
->curnode
;
3338 node
= reader
->node
;
3339 if (node
->type
== XML_NAMESPACE_DECL
)
3340 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3341 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3342 (node
->type
!= XML_ATTRIBUTE_NODE
))
3344 if (node
->ns
!= NULL
)
3345 return(CONSTSTR(node
->ns
->href
));
3350 * xmlTextReaderBaseUri:
3351 * @reader: the xmlTextReaderPtr used
3353 * The base URI of the node.
3355 * Returns the base URI or NULL if not available,
3356 * if non NULL it need to be freed by the caller.
3359 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3360 if ((reader
== NULL
) || (reader
->node
== NULL
))
3362 return(xmlNodeGetBase(NULL
, reader
->node
));
3366 * xmlTextReaderConstBaseUri:
3367 * @reader: the xmlTextReaderPtr used
3369 * The base URI of the node.
3371 * Returns the base URI or NULL if not available, the string
3372 * will be deallocated with the reader
3375 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3379 if ((reader
== NULL
) || (reader
->node
== NULL
))
3381 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3384 ret
= CONSTSTR(tmp
);
3390 * xmlTextReaderDepth:
3391 * @reader: the xmlTextReaderPtr used
3393 * The depth of the node in the tree.
3395 * Returns the depth or -1 in case of error
3398 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3401 if (reader
->node
== NULL
)
3404 if (reader
->curnode
!= NULL
) {
3405 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3406 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3407 return(reader
->depth
+ 1);
3408 return(reader
->depth
+ 2);
3410 return(reader
->depth
);
3414 * xmlTextReaderHasAttributes:
3415 * @reader: the xmlTextReaderPtr used
3417 * Whether the node has attributes.
3419 * Returns 1 if true, 0 if false, and -1 in case or error
3422 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3426 if (reader
->node
== NULL
)
3428 if (reader
->curnode
!= NULL
)
3429 node
= reader
->curnode
;
3431 node
= reader
->node
;
3433 if ((node
->type
== XML_ELEMENT_NODE
) &&
3434 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3436 /* TODO: handle the xmlDecl */
3441 * xmlTextReaderHasValue:
3442 * @reader: the xmlTextReaderPtr used
3444 * Whether the node can have a text value.
3446 * Returns 1 if true, 0 if false, and -1 in case or error
3449 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3453 if (reader
->node
== NULL
)
3455 if (reader
->curnode
!= NULL
)
3456 node
= reader
->curnode
;
3458 node
= reader
->node
;
3460 switch (node
->type
) {
3461 case XML_ATTRIBUTE_NODE
:
3463 case XML_CDATA_SECTION_NODE
:
3465 case XML_COMMENT_NODE
:
3466 case XML_NAMESPACE_DECL
:
3475 * xmlTextReaderValue:
3476 * @reader: the xmlTextReaderPtr used
3478 * Provides the text value of the node if present
3480 * Returns the string or NULL if not available. The result must be deallocated
3484 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3488 if (reader
->node
== NULL
)
3490 if (reader
->curnode
!= NULL
)
3491 node
= reader
->curnode
;
3493 node
= reader
->node
;
3495 switch (node
->type
) {
3496 case XML_NAMESPACE_DECL
:
3497 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3498 case XML_ATTRIBUTE_NODE
:{
3499 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3501 if (attr
->parent
!= NULL
)
3502 return (xmlNodeListGetString
3503 (attr
->parent
->doc
, attr
->children
, 1));
3505 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3509 case XML_CDATA_SECTION_NODE
:
3511 case XML_COMMENT_NODE
:
3512 if (node
->content
!= NULL
)
3513 return (xmlStrdup(node
->content
));
3521 * xmlTextReaderConstValue:
3522 * @reader: the xmlTextReaderPtr used
3524 * Provides the text value of the node if present
3526 * Returns the string or NULL if not available. The result will be
3527 * deallocated on the next Read() operation.
3530 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3534 if (reader
->node
== NULL
)
3536 if (reader
->curnode
!= NULL
)
3537 node
= reader
->curnode
;
3539 node
= reader
->node
;
3541 switch (node
->type
) {
3542 case XML_NAMESPACE_DECL
:
3543 return(((xmlNsPtr
) node
)->href
);
3544 case XML_ATTRIBUTE_NODE
:{
3545 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3548 if ((attr
->children
!= NULL
) &&
3549 (attr
->children
->type
== XML_TEXT_NODE
) &&
3550 (attr
->children
->next
== NULL
))
3551 return(attr
->children
->content
);
3553 if (reader
->buffer
== NULL
) {
3554 reader
->buffer
= xmlBufCreateSize(100);
3555 if (reader
->buffer
== NULL
) {
3556 xmlGenericError(xmlGenericErrorContext
,
3557 "xmlTextReaderSetup : malloc failed\n");
3560 xmlBufSetAllocationScheme(reader
->buffer
,
3561 XML_BUFFER_ALLOC_DOUBLEIT
);
3563 xmlBufEmpty(reader
->buffer
);
3564 xmlBufGetNodeContent(reader
->buffer
, node
);
3565 ret
= xmlBufContent(reader
->buffer
);
3567 /* error on the buffer best to reallocate */
3568 xmlBufFree(reader
->buffer
);
3569 reader
->buffer
= xmlBufCreateSize(100);
3570 xmlBufSetAllocationScheme(reader
->buffer
,
3571 XML_BUFFER_ALLOC_DOUBLEIT
);
3579 case XML_CDATA_SECTION_NODE
:
3581 case XML_COMMENT_NODE
:
3582 return(node
->content
);
3590 * xmlTextReaderIsDefault:
3591 * @reader: the xmlTextReaderPtr used
3593 * Whether an Attribute node was generated from the default value
3594 * defined in the DTD or schema.
3596 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3599 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3606 * xmlTextReaderQuoteChar:
3607 * @reader: the xmlTextReaderPtr used
3609 * The quotation mark character used to enclose the value of an attribute.
3611 * Returns " or ' and -1 in case of error
3614 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3617 /* TODO maybe lookup the attribute value for " first */
3622 * xmlTextReaderXmlLang:
3623 * @reader: the xmlTextReaderPtr used
3625 * The xml:lang scope within which the node resides.
3627 * Returns the xml:lang value or NULL if none exists.,
3628 * if non NULL it need to be freed by the caller.
3631 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3634 if (reader
->node
== NULL
)
3636 return(xmlNodeGetLang(reader
->node
));
3640 * xmlTextReaderConstXmlLang:
3641 * @reader: the xmlTextReaderPtr used
3643 * The xml:lang scope within which the node resides.
3645 * Returns the xml:lang value or NULL if none exists.
3648 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3654 if (reader
->node
== NULL
)
3656 tmp
= xmlNodeGetLang(reader
->node
);
3659 ret
= CONSTSTR(tmp
);
3665 * xmlTextReaderConstString:
3666 * @reader: the xmlTextReaderPtr used
3667 * @str: the string to intern.
3669 * Get an interned string from the reader, allows for example to
3670 * speedup string name comparisons
3672 * Returns an interned copy of the string or NULL in case of error. The
3673 * string will be deallocated with the reader.
3676 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3679 return(CONSTSTR(str
));
3683 * xmlTextReaderNormalization:
3684 * @reader: the xmlTextReaderPtr used
3686 * The value indicating whether to normalize white space and attribute values.
3687 * Since attribute value and end of line normalizations are a MUST in the XML
3688 * specification only the value true is accepted. The broken behaviour of
3689 * accepting out of range character entities like � is of course not
3692 * Returns 1 or -1 in case of error.
3695 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3701 /************************************************************************
3703 * Extensions to the base APIs *
3705 ************************************************************************/
3708 * xmlTextReaderSetParserProp:
3709 * @reader: the xmlTextReaderPtr used
3710 * @prop: the xmlParserProperties to set
3711 * @value: usually 0 or 1 to (de)activate it
3713 * Change the parser processing behaviour by changing some of its internal
3714 * properties. Note that some properties can only be changed before any
3715 * read has been done.
3717 * Returns 0 if the call was successful, or -1 in case of error
3720 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3721 xmlParserProperties p
= (xmlParserProperties
) prop
;
3722 xmlParserCtxtPtr ctxt
;
3724 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3726 ctxt
= reader
->ctxt
;
3729 case XML_PARSER_LOADDTD
:
3731 if (ctxt
->loadsubset
== 0) {
3732 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3734 ctxt
->loadsubset
= XML_DETECT_IDS
;
3737 ctxt
->loadsubset
= 0;
3740 case XML_PARSER_DEFAULTATTRS
:
3742 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3744 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3745 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3748 case XML_PARSER_VALIDATE
:
3750 ctxt
->options
|= XML_PARSE_DTDVALID
;
3752 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3754 ctxt
->options
&= ~XML_PARSE_DTDVALID
;
3758 case XML_PARSER_SUBST_ENTITIES
:
3760 ctxt
->options
|= XML_PARSE_NOENT
;
3761 ctxt
->replaceEntities
= 1;
3763 ctxt
->options
&= ~XML_PARSE_NOENT
;
3764 ctxt
->replaceEntities
= 0;
3772 * xmlTextReaderGetParserProp:
3773 * @reader: the xmlTextReaderPtr used
3774 * @prop: the xmlParserProperties to get
3776 * Read the parser internal property.
3778 * Returns the value, usually 0 or 1, or -1 in case of error.
3781 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3782 xmlParserProperties p
= (xmlParserProperties
) prop
;
3783 xmlParserCtxtPtr ctxt
;
3785 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3787 ctxt
= reader
->ctxt
;
3790 case XML_PARSER_LOADDTD
:
3791 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3794 case XML_PARSER_DEFAULTATTRS
:
3795 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3798 case XML_PARSER_VALIDATE
:
3799 return(reader
->validate
);
3800 case XML_PARSER_SUBST_ENTITIES
:
3801 return(ctxt
->replaceEntities
);
3808 * xmlTextReaderGetParserLineNumber:
3809 * @reader: the user data (XML reader context)
3811 * Provide the line number of the current parsing point.
3813 * Returns an int or 0 if not available
3816 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3818 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3819 (reader
->ctxt
->input
== NULL
)) {
3822 return (reader
->ctxt
->input
->line
);
3826 * xmlTextReaderGetParserColumnNumber:
3827 * @reader: the user data (XML reader context)
3829 * Provide the column number of the current parsing point.
3831 * Returns an int or 0 if not available
3834 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3836 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3837 (reader
->ctxt
->input
== NULL
)) {
3840 return (reader
->ctxt
->input
->col
);
3844 * xmlTextReaderCurrentNode:
3845 * @reader: the xmlTextReaderPtr used
3847 * Hacking interface allowing to get the xmlNodePtr corresponding to the
3848 * current node being accessed by the xmlTextReader. This is dangerous
3849 * because the underlying node may be destroyed on the next Reads.
3851 * Returns the xmlNodePtr or NULL in case of error.
3854 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3858 if (reader
->curnode
!= NULL
)
3859 return(reader
->curnode
);
3860 return(reader
->node
);
3864 * xmlTextReaderPreserve:
3865 * @reader: the xmlTextReaderPtr used
3867 * This tells the XML Reader to preserve the current node.
3868 * The caller must also use xmlTextReaderCurrentDoc() to
3869 * keep an handle on the resulting document once parsing has finished
3871 * Returns the xmlNodePtr or NULL in case of error.
3874 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3875 xmlNodePtr cur
, parent
;
3880 if (reader
->curnode
!= NULL
)
3881 cur
= reader
->curnode
;
3887 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3888 cur
->extra
|= NODE_IS_PRESERVED
;
3889 cur
->extra
|= NODE_IS_SPRESERVED
;
3891 reader
->preserves
++;
3893 parent
= cur
->parent
;
3894 while (parent
!= NULL
) {
3895 if (parent
->type
== XML_ELEMENT_NODE
)
3896 parent
->extra
|= NODE_IS_PRESERVED
;
3897 parent
= parent
->parent
;
3902 #ifdef LIBXML_PATTERN_ENABLED
3904 * xmlTextReaderPreservePattern:
3905 * @reader: the xmlTextReaderPtr used
3906 * @pattern: an XPath subset pattern
3907 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3909 * This tells the XML Reader to preserve all nodes matched by the
3910 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3911 * keep an handle on the resulting document once parsing has finished
3913 * Returns a non-negative number in case of success and -1 in case of error
3916 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3917 const xmlChar
**namespaces
)
3921 if ((reader
== NULL
) || (pattern
== NULL
))
3924 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
3928 if (reader
->patternMax
<= 0) {
3929 reader
->patternMax
= 4;
3930 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
3931 sizeof(reader
->patternTab
[0]));
3932 if (reader
->patternTab
== NULL
) {
3933 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
3937 if (reader
->patternNr
>= reader
->patternMax
) {
3939 reader
->patternMax
*= 2;
3940 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
3941 reader
->patternMax
*
3942 sizeof(reader
->patternTab
[0]));
3944 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
3945 reader
->patternMax
/= 2;
3948 reader
->patternTab
= tmp
;
3950 reader
->patternTab
[reader
->patternNr
] = comp
;
3951 return(reader
->patternNr
++);
3956 * xmlTextReaderCurrentDoc:
3957 * @reader: the xmlTextReaderPtr used
3959 * Hacking interface allowing to get the xmlDocPtr corresponding to the
3960 * current document being accessed by the xmlTextReader.
3961 * NOTE: as a result of this call, the reader will not destroy the
3962 * associated XML document and calling xmlFreeDoc() on the result
3963 * is needed once the reader parsing has finished.
3965 * Returns the xmlDocPtr or NULL in case of error.
3968 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
3971 if (reader
->doc
!= NULL
)
3972 return(reader
->doc
);
3973 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
3976 reader
->preserve
= 1;
3977 return(reader
->ctxt
->myDoc
);
3980 #ifdef LIBXML_SCHEMAS_ENABLED
3981 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
) LIBXML_ATTR_FORMAT(1,0);
3984 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3987 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3990 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3993 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3996 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
3998 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4005 str
= xmlTextReaderBuildMessage(msg
, ap
);
4006 if (!reader
->errorFunc
) {
4007 xmlTextReaderValidityError(ctx
, "%s", str
);
4009 reader
->errorFunc(reader
->errorFuncArg
, str
,
4010 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4011 NULL
/* locator */ );
4019 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4021 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4028 str
= xmlTextReaderBuildMessage(msg
, ap
);
4029 if (!reader
->errorFunc
) {
4030 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4032 reader
->errorFunc(reader
->errorFuncArg
, str
,
4033 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4034 NULL
/* locator */ );
4042 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4045 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4047 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4049 if (reader
->sErrorFunc
) {
4050 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4052 xmlTextReaderStructuredError(reader
, error
);
4056 * xmlTextReaderRelaxNGSetSchema:
4057 * @reader: the xmlTextReaderPtr used
4058 * @schema: a precompiled RelaxNG schema
4060 * Use RelaxNG to validate the document as it is processed.
4061 * Activation is only possible before the first Read().
4062 * if @schema is NULL, then RelaxNG validation is deactivated.
4063 @ The @schema should not be freed until the reader is deallocated
4064 * or its use has been deactivated.
4066 * Returns 0 in case the RelaxNG validation could be (de)activated and
4067 * -1 in case of error.
4070 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4073 if (schema
== NULL
) {
4074 if (reader
->rngSchemas
!= NULL
) {
4075 xmlRelaxNGFree(reader
->rngSchemas
);
4076 reader
->rngSchemas
= NULL
;
4078 if (reader
->rngValidCtxt
!= NULL
) {
4079 if (! reader
->rngPreserveCtxt
)
4080 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4081 reader
->rngValidCtxt
= NULL
;
4083 reader
->rngPreserveCtxt
= 0;
4086 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4088 if (reader
->rngSchemas
!= NULL
) {
4089 xmlRelaxNGFree(reader
->rngSchemas
);
4090 reader
->rngSchemas
= NULL
;
4092 if (reader
->rngValidCtxt
!= NULL
) {
4093 if (! reader
->rngPreserveCtxt
)
4094 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4095 reader
->rngValidCtxt
= NULL
;
4097 reader
->rngPreserveCtxt
= 0;
4098 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4099 if (reader
->rngValidCtxt
== NULL
)
4101 if (reader
->errorFunc
!= NULL
) {
4102 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4103 xmlTextReaderValidityErrorRelay
,
4104 xmlTextReaderValidityWarningRelay
,
4107 if (reader
->sErrorFunc
!= NULL
) {
4108 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4109 xmlTextReaderValidityStructuredRelay
,
4112 reader
->rngValidErrors
= 0;
4113 reader
->rngFullNode
= NULL
;
4114 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4119 * xmlTextReaderLocator:
4120 * @ctx: the xmlTextReaderPtr used
4121 * @file: returned file information
4122 * @line: returned line information
4124 * Internal locator function for the readers
4126 * Returns 0 in case the Schema validation could be (de)activated and
4127 * -1 in case of error.
4130 xmlTextReaderLocator(void *ctx
, const char **file
, unsigned long *line
) {
4131 xmlTextReaderPtr reader
;
4133 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
4141 reader
= (xmlTextReaderPtr
) ctx
;
4142 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->input
!= NULL
)) {
4144 *file
= reader
->ctxt
->input
->filename
;
4146 *line
= reader
->ctxt
->input
->line
;
4149 if (reader
->node
!= NULL
) {
4154 res
= xmlGetLineNo(reader
->node
);
4156 *line
= (unsigned long) res
;
4161 xmlDocPtr doc
= reader
->node
->doc
;
4162 if ((doc
!= NULL
) && (doc
->URL
!= NULL
))
4163 *file
= (const char *) doc
->URL
;
4173 * xmlTextReaderSetSchema:
4174 * @reader: the xmlTextReaderPtr used
4175 * @schema: a precompiled Schema schema
4177 * Use XSD Schema to validate the document as it is processed.
4178 * Activation is only possible before the first Read().
4179 * if @schema is NULL, then Schema validation is deactivated.
4180 * The @schema should not be freed until the reader is deallocated
4181 * or its use has been deactivated.
4183 * Returns 0 in case the Schema validation could be (de)activated and
4184 * -1 in case of error.
4187 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4190 if (schema
== NULL
) {
4191 if (reader
->xsdPlug
!= NULL
) {
4192 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4193 reader
->xsdPlug
= NULL
;
4195 if (reader
->xsdValidCtxt
!= NULL
) {
4196 if (! reader
->xsdPreserveCtxt
)
4197 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4198 reader
->xsdValidCtxt
= NULL
;
4200 reader
->xsdPreserveCtxt
= 0;
4201 if (reader
->xsdSchemas
!= NULL
) {
4202 xmlSchemaFree(reader
->xsdSchemas
);
4203 reader
->xsdSchemas
= NULL
;
4207 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4209 if (reader
->xsdPlug
!= NULL
) {
4210 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4211 reader
->xsdPlug
= NULL
;
4213 if (reader
->xsdValidCtxt
!= NULL
) {
4214 if (! reader
->xsdPreserveCtxt
)
4215 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4216 reader
->xsdValidCtxt
= NULL
;
4218 reader
->xsdPreserveCtxt
= 0;
4219 if (reader
->xsdSchemas
!= NULL
) {
4220 xmlSchemaFree(reader
->xsdSchemas
);
4221 reader
->xsdSchemas
= NULL
;
4223 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4224 if (reader
->xsdValidCtxt
== NULL
) {
4225 xmlSchemaFree(reader
->xsdSchemas
);
4226 reader
->xsdSchemas
= NULL
;
4229 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4230 &(reader
->ctxt
->sax
),
4231 &(reader
->ctxt
->userData
));
4232 if (reader
->xsdPlug
== NULL
) {
4233 xmlSchemaFree(reader
->xsdSchemas
);
4234 reader
->xsdSchemas
= NULL
;
4235 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4236 reader
->xsdValidCtxt
= NULL
;
4239 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4240 xmlTextReaderLocator
,
4243 if (reader
->errorFunc
!= NULL
) {
4244 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4245 xmlTextReaderValidityErrorRelay
,
4246 xmlTextReaderValidityWarningRelay
,
4249 if (reader
->sErrorFunc
!= NULL
) {
4250 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4251 xmlTextReaderValidityStructuredRelay
,
4254 reader
->xsdValidErrors
= 0;
4255 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4260 * xmlTextReaderRelaxNGValidateInternal:
4261 * @reader: the xmlTextReaderPtr used
4262 * @rng: the path to a RelaxNG schema or NULL
4263 * @ctxt: the RelaxNG schema validation context or NULL
4264 * @options: options (not yet used)
4266 * Use RelaxNG to validate the document as it is processed.
4267 * Activation is only possible before the first Read().
4268 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
4270 * Returns 0 in case the RelaxNG validation could be (de)activated and
4271 * -1 in case of error.
4274 xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader
,
4276 xmlRelaxNGValidCtxtPtr ctxt
,
4277 int options ATTRIBUTE_UNUSED
)
4282 if ((rng
!= NULL
) && (ctxt
!= NULL
))
4285 if (((rng
!= NULL
) || (ctxt
!= NULL
)) &&
4286 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4287 (reader
->ctxt
== NULL
)))
4290 /* Cleanup previous validation stuff. */
4291 if (reader
->rngValidCtxt
!= NULL
) {
4292 if ( !reader
->rngPreserveCtxt
)
4293 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4294 reader
->rngValidCtxt
= NULL
;
4296 reader
->rngPreserveCtxt
= 0;
4297 if (reader
->rngSchemas
!= NULL
) {
4298 xmlRelaxNGFree(reader
->rngSchemas
);
4299 reader
->rngSchemas
= NULL
;
4302 if ((rng
== NULL
) && (ctxt
== NULL
)) {
4303 /* We just want to deactivate the validation, so get out. */
4309 xmlRelaxNGParserCtxtPtr pctxt
;
4310 /* Parse the schema and create validation environment. */
4312 pctxt
= xmlRelaxNGNewParserCtxt(rng
);
4313 if (reader
->errorFunc
!= NULL
) {
4314 xmlRelaxNGSetParserErrors(pctxt
,
4315 xmlTextReaderValidityErrorRelay
,
4316 xmlTextReaderValidityWarningRelay
,
4319 if (reader
->sErrorFunc
!= NULL
) {
4320 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4321 xmlTextReaderValidityStructuredRelay
,
4324 reader
->rngSchemas
= xmlRelaxNGParse(pctxt
);
4325 xmlRelaxNGFreeParserCtxt(pctxt
);
4326 if (reader
->rngSchemas
== NULL
)
4328 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4329 if (reader
->rngValidCtxt
== NULL
) {
4330 xmlRelaxNGFree(reader
->rngSchemas
);
4331 reader
->rngSchemas
= NULL
;
4335 /* Use the given validation context. */
4336 reader
->rngValidCtxt
= ctxt
;
4337 reader
->rngPreserveCtxt
= 1;
4340 * Redirect the validation context's error channels to use
4341 * the reader channels.
4342 * TODO: In case the user provides the validation context we
4343 * could make this redirection optional.
4345 if (reader
->errorFunc
!= NULL
) {
4346 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4347 xmlTextReaderValidityErrorRelay
,
4348 xmlTextReaderValidityWarningRelay
,
4351 if (reader
->sErrorFunc
!= NULL
) {
4352 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4353 xmlTextReaderValidityStructuredRelay
,
4356 reader
->rngValidErrors
= 0;
4357 reader
->rngFullNode
= NULL
;
4358 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4363 * xmlTextReaderSchemaValidateInternal:
4364 * @reader: the xmlTextReaderPtr used
4365 * @xsd: the path to a W3C XSD schema or NULL
4366 * @ctxt: the XML Schema validation context or NULL
4367 * @options: options (not used yet)
4369 * Validate the document as it is processed using XML Schema.
4370 * Activation is only possible before the first Read().
4371 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4373 * Returns 0 in case the schemas validation could be (de)activated and
4374 * -1 in case of error.
4377 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4379 xmlSchemaValidCtxtPtr ctxt
,
4380 int options ATTRIBUTE_UNUSED
)
4385 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4388 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4389 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4390 (reader
->ctxt
== NULL
)))
4393 /* Cleanup previous validation stuff. */
4394 if (reader
->xsdPlug
!= NULL
) {
4395 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4396 reader
->xsdPlug
= NULL
;
4398 if (reader
->xsdValidCtxt
!= NULL
) {
4399 if (! reader
->xsdPreserveCtxt
)
4400 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4401 reader
->xsdValidCtxt
= NULL
;
4403 reader
->xsdPreserveCtxt
= 0;
4404 if (reader
->xsdSchemas
!= NULL
) {
4405 xmlSchemaFree(reader
->xsdSchemas
);
4406 reader
->xsdSchemas
= NULL
;
4409 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4410 /* We just want to deactivate the validation, so get out. */
4415 xmlSchemaParserCtxtPtr pctxt
;
4416 /* Parse the schema and create validation environment. */
4417 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4418 if (reader
->errorFunc
!= NULL
) {
4419 xmlSchemaSetParserErrors(pctxt
,
4420 xmlTextReaderValidityErrorRelay
,
4421 xmlTextReaderValidityWarningRelay
,
4424 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4425 xmlSchemaFreeParserCtxt(pctxt
);
4426 if (reader
->xsdSchemas
== NULL
)
4428 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4429 if (reader
->xsdValidCtxt
== NULL
) {
4430 xmlSchemaFree(reader
->xsdSchemas
);
4431 reader
->xsdSchemas
= NULL
;
4434 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4435 &(reader
->ctxt
->sax
),
4436 &(reader
->ctxt
->userData
));
4437 if (reader
->xsdPlug
== NULL
) {
4438 xmlSchemaFree(reader
->xsdSchemas
);
4439 reader
->xsdSchemas
= NULL
;
4440 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4441 reader
->xsdValidCtxt
= NULL
;
4445 /* Use the given validation context. */
4446 reader
->xsdValidCtxt
= ctxt
;
4447 reader
->xsdPreserveCtxt
= 1;
4448 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4449 &(reader
->ctxt
->sax
),
4450 &(reader
->ctxt
->userData
));
4451 if (reader
->xsdPlug
== NULL
) {
4452 reader
->xsdValidCtxt
= NULL
;
4453 reader
->xsdPreserveCtxt
= 0;
4457 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4458 xmlTextReaderLocator
,
4461 * Redirect the validation context's error channels to use
4462 * the reader channels.
4463 * TODO: In case the user provides the validation context we
4464 * could make this redirection optional.
4466 if (reader
->errorFunc
!= NULL
) {
4467 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4468 xmlTextReaderValidityErrorRelay
,
4469 xmlTextReaderValidityWarningRelay
,
4472 if (reader
->sErrorFunc
!= NULL
) {
4473 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4474 xmlTextReaderValidityStructuredRelay
,
4477 reader
->xsdValidErrors
= 0;
4478 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4483 * xmlTextReaderSchemaValidateCtxt:
4484 * @reader: the xmlTextReaderPtr used
4485 * @ctxt: the XML Schema validation context or NULL
4486 * @options: options (not used yet)
4488 * Use W3C XSD schema context to validate the document as it is processed.
4489 * Activation is only possible before the first Read().
4490 * If @ctxt is NULL, then XML Schema validation is deactivated.
4492 * Returns 0 in case the schemas validation could be (de)activated and
4493 * -1 in case of error.
4496 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4497 xmlSchemaValidCtxtPtr ctxt
,
4500 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4504 * xmlTextReaderSchemaValidate:
4505 * @reader: the xmlTextReaderPtr used
4506 * @xsd: the path to a W3C XSD schema or NULL
4508 * Use W3C XSD schema to validate the document as it is processed.
4509 * Activation is only possible before the first Read().
4510 * If @xsd is NULL, then XML Schema validation is deactivated.
4512 * Returns 0 in case the schemas validation could be (de)activated and
4513 * -1 in case of error.
4516 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4518 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4522 * xmlTextReaderRelaxNGValidateCtxt:
4523 * @reader: the xmlTextReaderPtr used
4524 * @ctxt: the RelaxNG schema validation context or NULL
4525 * @options: options (not used yet)
4527 * Use RelaxNG schema context to validate the document as it is processed.
4528 * Activation is only possible before the first Read().
4529 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
4531 * Returns 0 in case the schemas validation could be (de)activated and
4532 * -1 in case of error.
4535 xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader
,
4536 xmlRelaxNGValidCtxtPtr ctxt
,
4539 return(xmlTextReaderRelaxNGValidateInternal(reader
, NULL
, ctxt
, options
));
4543 * xmlTextReaderRelaxNGValidate:
4544 * @reader: the xmlTextReaderPtr used
4545 * @rng: the path to a RelaxNG schema or NULL
4547 * Use RelaxNG schema to validate the document as it is processed.
4548 * Activation is only possible before the first Read().
4549 * If @rng is NULL, then RelaxNG schema validation is deactivated.
4551 * Returns 0 in case the schemas validation could be (de)activated and
4552 * -1 in case of error.
4555 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
)
4557 return(xmlTextReaderRelaxNGValidateInternal(reader
, rng
, NULL
, 0));
4563 * xmlTextReaderIsNamespaceDecl:
4564 * @reader: the xmlTextReaderPtr used
4566 * Determine whether the current node is a namespace declaration
4567 * rather than a regular attribute.
4569 * Returns 1 if the current node is a namespace declaration, 0 if it
4570 * is a regular attribute or other type of node, or -1 in case of
4574 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4578 if (reader
->node
== NULL
)
4580 if (reader
->curnode
!= NULL
)
4581 node
= reader
->curnode
;
4583 node
= reader
->node
;
4585 if (XML_NAMESPACE_DECL
== node
->type
)
4592 * xmlTextReaderConstXmlVersion:
4593 * @reader: the xmlTextReaderPtr used
4595 * Determine the XML version of the document being read.
4597 * Returns a string containing the XML version of the document or NULL
4598 * in case of error. The string is deallocated with the reader.
4601 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4602 xmlDocPtr doc
= NULL
;
4605 if (reader
->doc
!= NULL
)
4607 else if (reader
->ctxt
!= NULL
)
4608 doc
= reader
->ctxt
->myDoc
;
4612 if (doc
->version
== NULL
)
4615 return(CONSTSTR(doc
->version
));
4619 * xmlTextReaderStandalone:
4620 * @reader: the xmlTextReaderPtr used
4622 * Determine the standalone status of the document being read.
4624 * Returns 1 if the document was declared to be standalone, 0 if it
4625 * was declared to be not standalone, or -1 if the document did not
4626 * specify its standalone status or in case of error.
4629 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4630 xmlDocPtr doc
= NULL
;
4633 if (reader
->doc
!= NULL
)
4635 else if (reader
->ctxt
!= NULL
)
4636 doc
= reader
->ctxt
->myDoc
;
4640 return(doc
->standalone
);
4643 /************************************************************************
4645 * Error Handling Extensions *
4647 ************************************************************************/
4649 /* helper to build a xmlMalloc'ed string from a format and va_list */
4651 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4660 chars
= vsnprintf(str
, size
, msg
, aq
);
4663 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4668 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4670 if (chars
< MAX_ERR_MSG_SIZE
)
4673 size
= MAX_ERR_MSG_SIZE
;
4674 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4675 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4687 * xmlTextReaderLocatorLineNumber:
4688 * @locator: the xmlTextReaderLocatorPtr used
4690 * Obtain the line number for the given locator.
4692 * Returns the line number or -1 in case of error.
4695 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4696 /* we know that locator is a xmlParserCtxtPtr */
4697 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4700 if (locator
== NULL
)
4702 if (ctx
->node
!= NULL
) {
4703 ret
= xmlGetLineNo(ctx
->node
);
4706 /* inspired from error.c */
4707 xmlParserInputPtr input
;
4709 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4710 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4711 if (input
!= NULL
) {
4723 * xmlTextReaderLocatorBaseURI:
4724 * @locator: the xmlTextReaderLocatorPtr used
4726 * Obtain the base URI for the given locator.
4728 * Returns the base URI or NULL in case of error,
4729 * if non NULL it need to be freed by the caller.
4732 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4733 /* we know that locator is a xmlParserCtxtPtr */
4734 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4735 xmlChar
*ret
= NULL
;
4737 if (locator
== NULL
)
4739 if (ctx
->node
!= NULL
) {
4740 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4743 /* inspired from error.c */
4744 xmlParserInputPtr input
;
4746 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4747 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4748 if (input
!= NULL
) {
4749 ret
= xmlStrdup(BAD_CAST input
->filename
);
4760 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4763 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4765 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4768 if (reader
->errorFunc
)
4769 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4770 (xmlTextReaderLocatorPtr
) ctx
);
4776 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4778 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4780 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4782 if (error
&& reader
->sErrorFunc
) {
4783 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4787 static void LIBXML_ATTR_FORMAT(2,3)
4788 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4793 xmlTextReaderGenericError(ctxt
,
4794 XML_PARSER_SEVERITY_ERROR
,
4795 xmlTextReaderBuildMessage(msg
, ap
));
4800 static void LIBXML_ATTR_FORMAT(2,3)
4801 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4806 xmlTextReaderGenericError(ctxt
,
4807 XML_PARSER_SEVERITY_WARNING
,
4808 xmlTextReaderBuildMessage(msg
, ap
));
4813 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4817 int len
= xmlStrlen((const xmlChar
*) msg
);
4819 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4821 * some callbacks only report locator information:
4822 * skip them (mimicking behaviour in error.c)
4825 xmlTextReaderGenericError(ctxt
,
4826 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4827 xmlTextReaderBuildMessage(msg
, ap
));
4833 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4837 int len
= xmlStrlen((const xmlChar
*) msg
);
4839 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4841 * some callbacks only report locator information:
4842 * skip them (mimicking behaviour in error.c)
4845 xmlTextReaderGenericError(ctxt
,
4846 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4847 xmlTextReaderBuildMessage(msg
, ap
));
4853 * xmlTextReaderSetErrorHandler:
4854 * @reader: the xmlTextReaderPtr used
4855 * @f: the callback function to call on error and warnings
4856 * @arg: a user argument to pass to the callback function
4858 * Register a callback function that will be called on error and warnings.
4860 * If @f is NULL, the default error and warning handlers are restored.
4863 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4864 xmlTextReaderErrorFunc f
, void *arg
)
4867 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4868 reader
->ctxt
->sax
->serror
= NULL
;
4869 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4870 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4871 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4872 reader
->errorFunc
= f
;
4873 reader
->sErrorFunc
= NULL
;
4874 reader
->errorFuncArg
= arg
;
4875 #ifdef LIBXML_SCHEMAS_ENABLED
4876 if (reader
->rngValidCtxt
) {
4877 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4878 xmlTextReaderValidityErrorRelay
,
4879 xmlTextReaderValidityWarningRelay
,
4881 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4884 if (reader
->xsdValidCtxt
) {
4885 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4886 xmlTextReaderValidityErrorRelay
,
4887 xmlTextReaderValidityWarningRelay
,
4889 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4894 /* restore defaults */
4895 reader
->ctxt
->sax
->error
= xmlParserError
;
4896 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4897 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4898 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4899 reader
->errorFunc
= NULL
;
4900 reader
->sErrorFunc
= NULL
;
4901 reader
->errorFuncArg
= NULL
;
4902 #ifdef LIBXML_SCHEMAS_ENABLED
4903 if (reader
->rngValidCtxt
) {
4904 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4906 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4909 if (reader
->xsdValidCtxt
) {
4910 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4912 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4920 * xmlTextReaderSetStructuredErrorHandler:
4921 * @reader: the xmlTextReaderPtr used
4922 * @f: the callback function to call on error and warnings
4923 * @arg: a user argument to pass to the callback function
4925 * Register a callback function that will be called on error and warnings.
4927 * If @f is NULL, the default error and warning handlers are restored.
4930 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
4931 xmlStructuredErrorFunc f
, void *arg
)
4934 reader
->ctxt
->sax
->error
= NULL
;
4935 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
4936 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4937 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4938 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4939 reader
->sErrorFunc
= f
;
4940 reader
->errorFunc
= NULL
;
4941 reader
->errorFuncArg
= arg
;
4942 #ifdef LIBXML_SCHEMAS_ENABLED
4943 if (reader
->rngValidCtxt
) {
4944 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4946 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4947 xmlTextReaderValidityStructuredRelay
,
4950 if (reader
->xsdValidCtxt
) {
4951 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4953 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4954 xmlTextReaderValidityStructuredRelay
,
4959 /* restore defaults */
4960 reader
->ctxt
->sax
->error
= xmlParserError
;
4961 reader
->ctxt
->sax
->serror
= NULL
;
4962 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4963 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4964 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4965 reader
->errorFunc
= NULL
;
4966 reader
->sErrorFunc
= NULL
;
4967 reader
->errorFuncArg
= NULL
;
4968 #ifdef LIBXML_SCHEMAS_ENABLED
4969 if (reader
->rngValidCtxt
) {
4970 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4972 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4975 if (reader
->xsdValidCtxt
) {
4976 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4978 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4986 * xmlTextReaderIsValid:
4987 * @reader: the xmlTextReaderPtr used
4989 * Retrieve the validity status from the parser context
4991 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
4994 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
4998 #ifdef LIBXML_SCHEMAS_ENABLED
4999 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
5000 return (reader
->rngValidErrors
== 0);
5001 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
5002 return (reader
->xsdValidErrors
== 0);
5004 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
5005 return (reader
->ctxt
->valid
);
5010 * xmlTextReaderGetErrorHandler:
5011 * @reader: the xmlTextReaderPtr used
5012 * @f: the callback function or NULL is no callback has been registered
5013 * @arg: a user argument
5015 * Retrieve the error callback function and user argument.
5018 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
5019 xmlTextReaderErrorFunc
* f
, void **arg
)
5022 *f
= reader
->errorFunc
;
5024 *arg
= reader
->errorFuncArg
;
5026 /************************************************************************
5028 * New set (2.6.0) of simpler and more flexible APIs *
5030 ************************************************************************/
5033 * xmlTextReaderSetup:
5034 * @reader: an XML reader
5035 * @input: xmlParserInputBufferPtr used to feed the reader, will
5036 * be destroyed with it.
5037 * @URL: the base URL to use for the document
5038 * @encoding: the document encoding, or NULL
5039 * @options: a combination of xmlParserOption
5041 * Setup an XML reader with new options
5043 * Returns 0 in case of success and -1 in case of error.
5046 xmlTextReaderSetup(xmlTextReaderPtr reader
,
5047 xmlParserInputBufferPtr input
, const char *URL
,
5048 const char *encoding
, int options
)
5050 if (reader
== NULL
) {
5052 xmlFreeParserInputBuffer(input
);
5057 * we force the generation of compact text nodes on the reader
5058 * since usr applications should never modify the tree
5060 options
|= XML_PARSE_COMPACT
;
5064 reader
->parserFlags
= options
;
5065 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
5066 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
5067 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
5068 xmlFreeParserInputBuffer(reader
->input
);
5069 reader
->input
= NULL
;
5070 reader
->allocs
-= XML_TEXTREADER_INPUT
;
5072 if (input
!= NULL
) {
5073 reader
->input
= input
;
5074 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5076 if (reader
->buffer
== NULL
)
5077 reader
->buffer
= xmlBufCreateSize(100);
5078 if (reader
->buffer
== NULL
) {
5079 xmlGenericError(xmlGenericErrorContext
,
5080 "xmlTextReaderSetup : malloc failed\n");
5083 /* no operation on a reader should require a huge buffer */
5084 xmlBufSetAllocationScheme(reader
->buffer
,
5085 XML_BUFFER_ALLOC_DOUBLEIT
);
5086 if (reader
->sax
== NULL
)
5087 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
5088 if (reader
->sax
== NULL
) {
5089 xmlGenericError(xmlGenericErrorContext
,
5090 "xmlTextReaderSetup : malloc failed\n");
5093 xmlSAXVersion(reader
->sax
, 2);
5094 reader
->startElement
= reader
->sax
->startElement
;
5095 reader
->sax
->startElement
= xmlTextReaderStartElement
;
5096 reader
->endElement
= reader
->sax
->endElement
;
5097 reader
->sax
->endElement
= xmlTextReaderEndElement
;
5098 #ifdef LIBXML_SAX1_ENABLED
5099 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
5100 #endif /* LIBXML_SAX1_ENABLED */
5101 reader
->startElementNs
= reader
->sax
->startElementNs
;
5102 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
5103 reader
->endElementNs
= reader
->sax
->endElementNs
;
5104 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
5105 #ifdef LIBXML_SAX1_ENABLED
5107 reader
->startElementNs
= NULL
;
5108 reader
->endElementNs
= NULL
;
5110 #endif /* LIBXML_SAX1_ENABLED */
5111 reader
->characters
= reader
->sax
->characters
;
5112 reader
->sax
->characters
= xmlTextReaderCharacters
;
5113 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
5114 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
5115 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
5117 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5118 reader
->node
= NULL
;
5119 reader
->curnode
= NULL
;
5120 if (input
!= NULL
) {
5121 if (xmlBufUse(reader
->input
->buffer
) < 4) {
5122 xmlParserInputBufferRead(input
, 4);
5124 if (reader
->ctxt
== NULL
) {
5125 if (xmlBufUse(reader
->input
->buffer
) >= 4) {
5126 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5127 (const char *) xmlBufContent(reader
->input
->buffer
),
5133 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5138 xmlParserInputPtr inputStream
;
5139 xmlParserInputBufferPtr buf
;
5140 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5142 xmlCtxtReset(reader
->ctxt
);
5143 buf
= xmlAllocParserInputBuffer(enc
);
5144 if (buf
== NULL
) return(-1);
5145 inputStream
= xmlNewInputStream(reader
->ctxt
);
5146 if (inputStream
== NULL
) {
5147 xmlFreeParserInputBuffer(buf
);
5152 inputStream
->filename
= NULL
;
5154 inputStream
->filename
= (char *)
5155 xmlCanonicPath((const xmlChar
*) URL
);
5156 inputStream
->buf
= buf
;
5157 xmlBufResetInput(buf
->buffer
, inputStream
);
5159 inputPush(reader
->ctxt
, inputStream
);
5162 if (reader
->ctxt
== NULL
) {
5163 xmlGenericError(xmlGenericErrorContext
,
5164 "xmlTextReaderSetup : malloc failed\n");
5168 if (reader
->dict
!= NULL
) {
5169 if (reader
->ctxt
->dict
!= NULL
) {
5170 if (reader
->dict
!= reader
->ctxt
->dict
) {
5171 xmlDictFree(reader
->dict
);
5172 reader
->dict
= reader
->ctxt
->dict
;
5175 reader
->ctxt
->dict
= reader
->dict
;
5178 if (reader
->ctxt
->dict
== NULL
)
5179 reader
->ctxt
->dict
= xmlDictCreate();
5180 reader
->dict
= reader
->ctxt
->dict
;
5182 reader
->ctxt
->_private
= reader
;
5183 reader
->ctxt
->linenumbers
= 1;
5184 reader
->ctxt
->dictNames
= 1;
5186 * use the parser dictionary to allocate all elements and attributes names
5188 reader
->ctxt
->docdict
= 1;
5189 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5191 #ifdef LIBXML_XINCLUDE_ENABLED
5192 if (reader
->xincctxt
!= NULL
) {
5193 xmlXIncludeFreeContext(reader
->xincctxt
);
5194 reader
->xincctxt
= NULL
;
5196 if (options
& XML_PARSE_XINCLUDE
) {
5197 reader
->xinclude
= 1;
5198 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5199 options
-= XML_PARSE_XINCLUDE
;
5201 reader
->xinclude
= 0;
5202 reader
->in_xinclude
= 0;
5204 #ifdef LIBXML_PATTERN_ENABLED
5205 if (reader
->patternTab
== NULL
) {
5206 reader
->patternNr
= 0;
5207 reader
->patternMax
= 0;
5209 while (reader
->patternNr
> 0) {
5210 reader
->patternNr
--;
5211 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5212 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5213 reader
->patternTab
[reader
->patternNr
] = NULL
;
5218 if (options
& XML_PARSE_DTDVALID
)
5219 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5221 xmlCtxtUseOptions(reader
->ctxt
, options
);
5222 if (encoding
!= NULL
) {
5223 xmlCharEncodingHandlerPtr hdlr
;
5225 hdlr
= xmlFindCharEncodingHandler(encoding
);
5227 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5229 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5230 (reader
->ctxt
->input
->filename
== NULL
))
5231 reader
->ctxt
->input
->filename
= (char *)
5232 xmlStrdup((const xmlChar
*) URL
);
5240 * xmlTextReaderByteConsumed:
5241 * @reader: an XML reader
5243 * This function provides the current index of the parser used
5244 * by the reader, relative to the start of the current entity.
5245 * This function actually just wraps a call to xmlBytesConsumed()
5246 * for the parser context associated with the reader.
5247 * See xmlBytesConsumed() for more information.
5249 * Returns the index in bytes from the beginning of the entity or -1
5250 * in case the index could not be computed.
5253 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5254 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5256 return(xmlByteConsumed(reader
->ctxt
));
5262 * @doc: a preparsed document
5264 * Create an xmltextReader for a preparsed document.
5266 * Returns the new reader or NULL in case of error.
5269 xmlReaderWalker(xmlDocPtr doc
)
5271 xmlTextReaderPtr ret
;
5276 ret
= xmlMalloc(sizeof(xmlTextReader
));
5278 xmlGenericError(xmlGenericErrorContext
,
5279 "xmlNewTextReader : malloc failed\n");
5282 memset(ret
, 0, sizeof(xmlTextReader
));
5285 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5287 ret
->curnode
= NULL
;
5290 ret
->allocs
= XML_TEXTREADER_CTXT
;
5292 ret
->state
= XML_TEXTREADER_START
;
5293 ret
->dict
= xmlDictCreate();
5299 * @cur: a pointer to a zero terminated string
5300 * @URL: the base URL to use for the document
5301 * @encoding: the document encoding, or NULL
5302 * @options: a combination of xmlParserOption
5304 * Create an xmltextReader for an XML in-memory document.
5305 * The parsing flags @options are a combination of xmlParserOption.
5307 * Returns the new reader or NULL in case of error.
5310 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5317 len
= xmlStrlen(cur
);
5319 return (xmlReaderForMemory
5320 ((const char *) cur
, len
, URL
, encoding
, options
));
5325 * @filename: a file or URL
5326 * @encoding: the document encoding, or NULL
5327 * @options: a combination of xmlParserOption
5329 * parse an XML file from the filesystem or the network.
5330 * The parsing flags @options are a combination of xmlParserOption.
5332 * Returns the new reader or NULL in case of error.
5335 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5337 xmlTextReaderPtr reader
;
5339 reader
= xmlNewTextReaderFilename(filename
);
5342 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5347 * xmlReaderForMemory:
5348 * @buffer: a pointer to a char array
5349 * @size: the size of the array
5350 * @URL: the base URL to use for the document
5351 * @encoding: the document encoding, or NULL
5352 * @options: a combination of xmlParserOption
5354 * Create an xmltextReader for an XML in-memory document.
5355 * The parsing flags @options are a combination of xmlParserOption.
5357 * Returns the new reader or NULL in case of error.
5360 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5361 const char *encoding
, int options
)
5363 xmlTextReaderPtr reader
;
5364 xmlParserInputBufferPtr buf
;
5366 buf
= xmlParserInputBufferCreateMem(buffer
, size
, XML_CHAR_ENCODING_NONE
);
5370 reader
= xmlNewTextReader(buf
, URL
);
5371 if (reader
== NULL
) {
5372 xmlFreeParserInputBuffer(buf
);
5375 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5376 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5382 * @fd: an open file descriptor
5383 * @URL: the base URL to use for the document
5384 * @encoding: the document encoding, or NULL
5385 * @options: a combination of xmlParserOption
5387 * Create an xmltextReader for an XML from a file descriptor.
5388 * The parsing flags @options are a combination of xmlParserOption.
5389 * NOTE that the file descriptor will not be closed when the
5390 * reader is closed or reset.
5392 * Returns the new reader or NULL in case of error.
5395 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5397 xmlTextReaderPtr reader
;
5398 xmlParserInputBufferPtr input
;
5403 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5406 input
->closecallback
= NULL
;
5407 reader
= xmlNewTextReader(input
, URL
);
5408 if (reader
== NULL
) {
5409 xmlFreeParserInputBuffer(input
);
5412 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5413 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5419 * @ioread: an I/O read function
5420 * @ioclose: an I/O close function
5421 * @ioctx: an I/O handler
5422 * @URL: the base URL to use for the document
5423 * @encoding: the document encoding, or NULL
5424 * @options: a combination of xmlParserOption
5426 * Create an xmltextReader for an XML document from I/O functions and source.
5427 * The parsing flags @options are a combination of xmlParserOption.
5429 * Returns the new reader or NULL in case of error.
5432 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5433 void *ioctx
, const char *URL
, const char *encoding
,
5436 xmlTextReaderPtr reader
;
5437 xmlParserInputBufferPtr input
;
5442 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5443 XML_CHAR_ENCODING_NONE
);
5444 if (input
== NULL
) {
5445 if (ioclose
!= NULL
)
5449 reader
= xmlNewTextReader(input
, URL
);
5450 if (reader
== NULL
) {
5451 xmlFreeParserInputBuffer(input
);
5454 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5455 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5460 * xmlReaderNewWalker:
5461 * @reader: an XML reader
5462 * @doc: a preparsed document
5464 * Setup an xmltextReader to parse a preparsed XML document.
5465 * This reuses the existing @reader xmlTextReader.
5467 * Returns 0 in case of success and -1 in case of error
5470 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5477 if (reader
->input
!= NULL
) {
5478 xmlFreeParserInputBuffer(reader
->input
);
5480 if (reader
->ctxt
!= NULL
) {
5481 xmlCtxtReset(reader
->ctxt
);
5485 reader
->input
= NULL
;
5486 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5487 reader
->node
= NULL
;
5488 reader
->curnode
= NULL
;
5491 reader
->allocs
= XML_TEXTREADER_CTXT
;
5493 reader
->state
= XML_TEXTREADER_START
;
5494 if (reader
->dict
== NULL
) {
5495 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5496 reader
->dict
= reader
->ctxt
->dict
;
5498 reader
->dict
= xmlDictCreate();
5505 * @reader: an XML reader
5506 * @cur: a pointer to a zero terminated string
5507 * @URL: the base URL to use for the document
5508 * @encoding: the document encoding, or NULL
5509 * @options: a combination of xmlParserOption
5511 * Setup an xmltextReader to parse an XML in-memory document.
5512 * The parsing flags @options are a combination of xmlParserOption.
5513 * This reuses the existing @reader xmlTextReader.
5515 * Returns 0 in case of success and -1 in case of error
5518 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5519 const char *URL
, const char *encoding
, int options
)
5529 len
= xmlStrlen(cur
);
5530 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5531 URL
, encoding
, options
));
5536 * @reader: an XML reader
5537 * @filename: a file or URL
5538 * @encoding: the document encoding, or NULL
5539 * @options: a combination of xmlParserOption
5541 * parse an XML file from the filesystem or the network.
5542 * The parsing flags @options are a combination of xmlParserOption.
5543 * This reuses the existing @reader xmlTextReader.
5545 * Returns 0 in case of success and -1 in case of error
5548 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5549 const char *encoding
, int options
)
5551 xmlParserInputBufferPtr input
;
5553 if (filename
== NULL
)
5559 xmlParserInputBufferCreateFilename(filename
,
5560 XML_CHAR_ENCODING_NONE
);
5563 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5567 * xmlReaderNewMemory:
5568 * @reader: an XML reader
5569 * @buffer: a pointer to a char array
5570 * @size: the size of the array
5571 * @URL: the base URL to use for the document
5572 * @encoding: the document encoding, or NULL
5573 * @options: a combination of xmlParserOption
5575 * Setup an xmltextReader to parse an XML in-memory document.
5576 * The parsing flags @options are a combination of xmlParserOption.
5577 * This reuses the existing @reader xmlTextReader.
5579 * Returns 0 in case of success and -1 in case of error
5582 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5583 const char *URL
, const char *encoding
, int options
)
5585 xmlParserInputBufferPtr input
;
5592 input
= xmlParserInputBufferCreateMem(buffer
, size
,
5593 XML_CHAR_ENCODING_NONE
);
5594 if (input
== NULL
) {
5597 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5602 * @reader: an XML reader
5603 * @fd: an open file descriptor
5604 * @URL: the base URL to use for the document
5605 * @encoding: the document encoding, or NULL
5606 * @options: a combination of xmlParserOption
5608 * Setup an xmltextReader to parse an XML from a file descriptor.
5609 * NOTE that the file descriptor will not be closed when the
5610 * reader is closed or reset.
5611 * The parsing flags @options are a combination of xmlParserOption.
5612 * This reuses the existing @reader xmlTextReader.
5614 * Returns 0 in case of success and -1 in case of error
5617 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5618 const char *URL
, const char *encoding
, int options
)
5620 xmlParserInputBufferPtr input
;
5627 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5630 input
->closecallback
= NULL
;
5631 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5636 * @reader: an XML reader
5637 * @ioread: an I/O read function
5638 * @ioclose: an I/O close function
5639 * @ioctx: an I/O handler
5640 * @URL: the base URL to use for the document
5641 * @encoding: the document encoding, or NULL
5642 * @options: a combination of xmlParserOption
5644 * Setup an xmltextReader to parse an XML document from I/O functions
5646 * The parsing flags @options are a combination of xmlParserOption.
5647 * This reuses the existing @reader xmlTextReader.
5649 * Returns 0 in case of success and -1 in case of error
5652 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5653 xmlInputCloseCallback ioclose
, void *ioctx
,
5654 const char *URL
, const char *encoding
, int options
)
5656 xmlParserInputBufferPtr input
;
5663 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5664 XML_CHAR_ENCODING_NONE
);
5665 if (input
== NULL
) {
5666 if (ioclose
!= NULL
)
5670 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5673 /************************************************************************
5677 ************************************************************************/
5682 * @in: the input buffer
5683 * @inlen: the size of the input (in), the size read from it (out)
5684 * @to: the output buffer
5685 * @tolen: the size of the output (in), the size written to (out)
5687 * Base64 decoder, reads from @in and save in @to
5688 * TODO: tell jody when this is actually exported
5690 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5691 * 2 if there wasn't enough space on the output or -1 in case of error.
5694 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5695 unsigned char *to
, unsigned long *tolen
)
5697 unsigned long incur
; /* current index in in[] */
5699 unsigned long inblk
; /* last block index in in[] */
5701 unsigned long outcur
; /* current index in out[] */
5703 unsigned long inmax
; /* size of in[] */
5705 unsigned long outmax
; /* size of out[] */
5707 unsigned char cur
; /* the current value read from in[] */
5709 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5711 int nbintmp
; /* number of byte in intmp[] */
5713 int is_ignore
; /* cur should be ignored */
5715 int is_end
= 0; /* the end of the base64 was found */
5721 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5736 if ((cur
>= 'A') && (cur
<= 'Z'))
5738 else if ((cur
>= 'a') && (cur
<= 'z'))
5739 cur
= cur
- 'a' + 26;
5740 else if ((cur
>= '0') && (cur
<= '9'))
5741 cur
= cur
- '0' + 52;
5742 else if (cur
== '+')
5744 else if (cur
== '/')
5746 else if (cur
== '.')
5748 else if (cur
== '=') /*no op , end of the base64 stream */
5764 if ((nbintmp
== 1) || (nbintmp
== 2))
5771 intmp
[nbintmp
++] = cur
;
5773 * if intmp is full, push the 4byte sequence as a 3 byte
5778 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5780 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5781 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5782 if (outcur
+ 3 >= outmax
) {
5787 for (i
= 0; i
< nbouttmp
; i
++)
5788 to
[outcur
++] = outtmp
[i
];
5805 * Test routine for the xmlBase64Decode function
5809 main(int argc
, char **argv
)
5811 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5819 unsigned long inlen
= strlen(input
);
5821 unsigned long outlen
= 100;
5825 unsigned long cons
, tmp
, tmp2
, prod
;
5830 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5833 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5834 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5842 while (cons
< inlen
) {
5844 tmp2
= inlen
- cons
;
5846 printf("%ld %ld\n", cons
, prod
);
5847 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5850 printf("%ld %ld\n", cons
, prod
);
5852 output2
[outlen
] = 0;
5853 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5861 while (cons
< inlen
) {
5863 tmp2
= inlen
- cons
;
5867 printf("%ld %ld\n", cons
, prod
);
5868 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5871 printf("%ld %ld\n", cons
, prod
);
5873 output3
[outlen
] = 0;
5874 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5880 #endif /* NOT_USED_YET */
5882 #endif /* LIBXML_READER_ENABLED */