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>
44 #define MAX_ERR_MSG_SIZE 64000
46 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
47 /* Keeping free objects can hide memory errors. */
48 #define MAX_FREE_NODES 1
50 #define MAX_FREE_NODES 100
54 * The following VA_COPY was coded following an example in
55 * the Samba project. It may not be sufficient for some
56 * esoteric implementations of va_list but (hopefully) will
57 * be sufficient for libxml2.
61 #define VA_COPY(dest, src) va_copy(dest, src)
64 #define VA_COPY(dest,src) __va_copy(dest, src)
66 #ifndef VA_LIST_IS_ARRAY
67 #define VA_COPY(dest,src) (dest) = (src)
70 #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
76 /* #define DEBUG_CALLBACKS */
77 /* #define DEBUG_READER */
82 * macro to flag unimplemented blocks
85 xmlGenericError(xmlGenericErrorContext, \
86 "Unimplemented block at %s:%d\n", \
90 #define DUMP_READER xmlTextReaderDebug(reader);
95 #define CHUNK_SIZE 512
96 /************************************************************************
98 * The parser: maps the Text Reader API on top of the existing *
99 * parsing routines building a tree *
101 ************************************************************************/
103 #define XML_TEXTREADER_INPUT 1
104 #define XML_TEXTREADER_CTXT 2
107 XML_TEXTREADER_NONE
= -1,
108 XML_TEXTREADER_START
= 0,
109 XML_TEXTREADER_ELEMENT
= 1,
110 XML_TEXTREADER_END
= 2,
111 XML_TEXTREADER_EMPTY
= 3,
112 XML_TEXTREADER_BACKTRACK
= 4,
113 XML_TEXTREADER_DONE
= 5,
114 XML_TEXTREADER_ERROR
= 6
115 } xmlTextReaderState
;
118 XML_TEXTREADER_NOT_VALIDATE
= 0,
119 XML_TEXTREADER_VALIDATE_DTD
= 1,
120 XML_TEXTREADER_VALIDATE_RNG
= 2,
121 XML_TEXTREADER_VALIDATE_XSD
= 4
122 } xmlTextReaderValidate
;
124 struct _xmlTextReader
{
125 int mode
; /* the parsing mode */
126 xmlDocPtr doc
; /* when walking an existing doc */
127 xmlTextReaderValidate validate
;/* is there any validation */
128 int allocs
; /* what structure were deallocated */
129 xmlTextReaderState state
;
130 xmlParserCtxtPtr ctxt
; /* the parser context */
131 xmlSAXHandlerPtr sax
; /* the parser SAX callbacks */
132 xmlParserInputBufferPtr input
; /* the input */
133 startElementSAXFunc startElement
;/* initial SAX callbacks */
134 endElementSAXFunc endElement
; /* idem */
135 startElementNsSAX2Func startElementNs
;/* idem */
136 endElementNsSAX2Func endElementNs
; /* idem */
137 charactersSAXFunc characters
;
138 cdataBlockSAXFunc cdataBlock
;
139 unsigned int base
; /* base of the segment in the input */
140 unsigned int cur
; /* current position in the input */
141 xmlNodePtr node
; /* current node */
142 xmlNodePtr curnode
;/* current attribute node */
143 int depth
; /* depth of the current node */
144 xmlNodePtr faketext
;/* fake xmlNs chld */
145 int preserve
;/* preserve the resulting document */
146 xmlBufPtr buffer
; /* used to return const xmlChar * */
147 xmlDictPtr dict
; /* the context dictionary */
149 /* entity stack when traversing entities content */
150 xmlNodePtr ent
; /* Current Entity Ref Node */
151 int entNr
; /* Depth of the entities stack */
152 int entMax
; /* Max depth of the entities stack */
153 xmlNodePtr
*entTab
; /* array of entities */
156 xmlTextReaderErrorFunc errorFunc
; /* callback function */
157 void *errorFuncArg
; /* callback function user argument */
159 #ifdef LIBXML_SCHEMAS_ENABLED
160 /* Handling of RelaxNG validation */
161 xmlRelaxNGPtr rngSchemas
; /* The Relax NG schemas */
162 xmlRelaxNGValidCtxtPtr rngValidCtxt
;/* The Relax NG validation context */
163 int rngPreserveCtxt
; /* 1 if the context was provided by the user */
164 int rngValidErrors
;/* The number of errors detected */
165 xmlNodePtr rngFullNode
; /* the node if RNG not progressive */
166 /* Handling of Schemas validation */
167 xmlSchemaPtr xsdSchemas
; /* The Schemas schemas */
168 xmlSchemaValidCtxtPtr xsdValidCtxt
;/* The Schemas validation context */
169 int xsdPreserveCtxt
; /* 1 if the context was provided by the user */
170 int xsdValidErrors
;/* The number of errors detected */
171 xmlSchemaSAXPlugPtr xsdPlug
; /* the schemas plug in SAX pipeline */
173 #ifdef LIBXML_XINCLUDE_ENABLED
174 /* Handling of XInclude processing */
175 int xinclude
; /* is xinclude asked for */
176 const xmlChar
* xinclude_name
; /* the xinclude name from dict */
177 xmlXIncludeCtxtPtr xincctxt
; /* the xinclude context */
178 int in_xinclude
; /* counts for xinclude */
180 #ifdef LIBXML_PATTERN_ENABLED
181 int patternNr
; /* number of preserve patterns */
182 int patternMax
; /* max preserve patterns */
183 xmlPatternPtr
*patternTab
; /* array of preserve patterns */
185 int preserves
; /* level of preserves */
186 int parserFlags
; /* the set of options set */
187 /* Structured error handling */
188 xmlStructuredErrorFunc sErrorFunc
; /* callback function */
191 #define NODE_IS_EMPTY 0x1
192 #define NODE_IS_PRESERVED 0x2
193 #define NODE_IS_SPRESERVED 0x4
198 * Macro used to return an interned string
200 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
201 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
203 static int xmlTextReaderReadTree(xmlTextReaderPtr reader
);
204 static int xmlTextReaderNextTree(xmlTextReaderPtr reader
);
206 /************************************************************************
208 * Our own version of the freeing routines as we recycle nodes *
210 ************************************************************************/
215 * Free a string if it is not owned by the "dict" dictionary in the
218 #define DICT_FREE(str) \
219 if ((str) && ((!dict) || \
220 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
221 xmlFree((char *)(str));
223 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
);
224 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
);
227 * xmlTextReaderFreeProp:
228 * @reader: the xmlTextReaderPtr used
234 xmlTextReaderFreeProp(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
237 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
238 dict
= reader
->ctxt
->dict
;
241 if (cur
== NULL
) return;
243 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
244 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
246 if (cur
->children
!= NULL
)
247 xmlTextReaderFreeNodeList(reader
, cur
->children
);
249 DICT_FREE(cur
->name
);
250 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
251 (reader
->ctxt
->freeAttrsNr
< MAX_FREE_NODES
)) {
252 cur
->next
= reader
->ctxt
->freeAttrs
;
253 reader
->ctxt
->freeAttrs
= cur
;
254 reader
->ctxt
->freeAttrsNr
++;
261 * xmlTextReaderFreePropList:
262 * @reader: the xmlTextReaderPtr used
263 * @cur: the first property in the list
265 * Free a property and all its siblings, all the children are freed too.
268 xmlTextReaderFreePropList(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
271 while (cur
!= NULL
) {
273 xmlTextReaderFreeProp(reader
, cur
);
279 * xmlTextReaderFreeNodeList:
280 * @reader: the xmlTextReaderPtr used
281 * @cur: the first node in the list
283 * Free a node and all its siblings, this is a recursive behaviour, all
284 * the children are freed too.
287 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
293 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
294 dict
= reader
->ctxt
->dict
;
297 if (cur
== NULL
) return;
298 if (cur
->type
== XML_NAMESPACE_DECL
) {
299 xmlFreeNsList((xmlNsPtr
) cur
);
302 if ((cur
->type
== XML_DOCUMENT_NODE
) ||
303 (cur
->type
== XML_HTML_DOCUMENT_NODE
)) {
304 xmlFreeDoc((xmlDocPtr
) cur
);
308 while ((cur
->type
!= XML_DTD_NODE
) &&
309 (cur
->type
!= XML_ENTITY_REF_NODE
) &&
310 (cur
->children
!= NULL
) &&
311 (cur
->children
->parent
== cur
)) {
317 parent
= cur
->parent
;
319 /* unroll to speed up freeing the document */
320 if (cur
->type
!= XML_DTD_NODE
) {
322 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
323 xmlDeregisterNodeDefaultValue(cur
);
325 if (((cur
->type
== XML_ELEMENT_NODE
) ||
326 (cur
->type
== XML_XINCLUDE_START
) ||
327 (cur
->type
== XML_XINCLUDE_END
)) &&
328 (cur
->properties
!= NULL
))
329 xmlTextReaderFreePropList(reader
, cur
->properties
);
330 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
331 (cur
->type
!= XML_ELEMENT_NODE
) &&
332 (cur
->type
!= XML_XINCLUDE_START
) &&
333 (cur
->type
!= XML_XINCLUDE_END
) &&
334 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
335 DICT_FREE(cur
->content
);
337 if (((cur
->type
== XML_ELEMENT_NODE
) ||
338 (cur
->type
== XML_XINCLUDE_START
) ||
339 (cur
->type
== XML_XINCLUDE_END
)) &&
340 (cur
->nsDef
!= NULL
))
341 xmlFreeNsList(cur
->nsDef
);
344 * we don't free element names here they are interned now
346 if ((cur
->type
!= XML_TEXT_NODE
) &&
347 (cur
->type
!= XML_COMMENT_NODE
))
348 DICT_FREE(cur
->name
);
349 if (((cur
->type
== XML_ELEMENT_NODE
) ||
350 (cur
->type
== XML_TEXT_NODE
)) &&
351 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
352 (reader
->ctxt
->freeElemsNr
< MAX_FREE_NODES
)) {
353 cur
->next
= reader
->ctxt
->freeElems
;
354 reader
->ctxt
->freeElems
= cur
;
355 reader
->ctxt
->freeElemsNr
++;
364 if ((depth
== 0) || (parent
== NULL
))
368 cur
->children
= NULL
;
374 * xmlTextReaderFreeNode:
375 * @reader: the xmlTextReaderPtr used
378 * Free a node, this is a recursive behaviour, all the children are freed too.
379 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
382 xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
385 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
386 dict
= reader
->ctxt
->dict
;
389 if (cur
->type
== XML_DTD_NODE
) {
390 xmlFreeDtd((xmlDtdPtr
) cur
);
393 if (cur
->type
== XML_NAMESPACE_DECL
) {
394 xmlFreeNs((xmlNsPtr
) cur
);
397 if (cur
->type
== XML_ATTRIBUTE_NODE
) {
398 xmlTextReaderFreeProp(reader
, (xmlAttrPtr
) cur
);
402 if ((cur
->children
!= NULL
) &&
403 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
404 if (cur
->children
->parent
== cur
)
405 xmlTextReaderFreeNodeList(reader
, cur
->children
);
406 cur
->children
= NULL
;
409 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
410 xmlDeregisterNodeDefaultValue(cur
);
412 if (((cur
->type
== XML_ELEMENT_NODE
) ||
413 (cur
->type
== XML_XINCLUDE_START
) ||
414 (cur
->type
== XML_XINCLUDE_END
)) &&
415 (cur
->properties
!= NULL
))
416 xmlTextReaderFreePropList(reader
, cur
->properties
);
417 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
418 (cur
->type
!= XML_ELEMENT_NODE
) &&
419 (cur
->type
!= XML_XINCLUDE_START
) &&
420 (cur
->type
!= XML_XINCLUDE_END
) &&
421 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
422 DICT_FREE(cur
->content
);
424 if (((cur
->type
== XML_ELEMENT_NODE
) ||
425 (cur
->type
== XML_XINCLUDE_START
) ||
426 (cur
->type
== XML_XINCLUDE_END
)) &&
427 (cur
->nsDef
!= NULL
))
428 xmlFreeNsList(cur
->nsDef
);
431 * we don't free names here they are interned now
433 if ((cur
->type
!= XML_TEXT_NODE
) &&
434 (cur
->type
!= XML_COMMENT_NODE
))
435 DICT_FREE(cur
->name
);
437 if (((cur
->type
== XML_ELEMENT_NODE
) ||
438 (cur
->type
== XML_TEXT_NODE
)) &&
439 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
440 (reader
->ctxt
->freeElemsNr
< MAX_FREE_NODES
)) {
441 cur
->next
= reader
->ctxt
->freeElems
;
442 reader
->ctxt
->freeElems
= cur
;
443 reader
->ctxt
->freeElemsNr
++;
450 * xmlTextReaderFreeDoc:
451 * @reader: the xmlTextReaderPtr used
452 * @cur: pointer to the document
454 * Free up all the structures used by a document, tree included.
457 xmlTextReaderFreeDoc(xmlTextReaderPtr reader
, xmlDocPtr cur
) {
458 xmlDtdPtr extSubset
, intSubset
;
460 if (cur
== NULL
) return;
462 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
463 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
466 * Do this before freeing the children list to avoid ID lookups
468 if (cur
->ids
!= NULL
) xmlFreeIDTable((xmlIDTablePtr
) cur
->ids
);
470 if (cur
->refs
!= NULL
) xmlFreeRefTable((xmlRefTablePtr
) cur
->refs
);
472 extSubset
= cur
->extSubset
;
473 intSubset
= cur
->intSubset
;
474 if (intSubset
== extSubset
)
476 if (extSubset
!= NULL
) {
477 xmlUnlinkNode((xmlNodePtr
) cur
->extSubset
);
478 cur
->extSubset
= NULL
;
479 xmlFreeDtd(extSubset
);
481 if (intSubset
!= NULL
) {
482 xmlUnlinkNode((xmlNodePtr
) cur
->intSubset
);
483 cur
->intSubset
= NULL
;
484 xmlFreeDtd(intSubset
);
487 if (cur
->children
!= NULL
) xmlTextReaderFreeNodeList(reader
, cur
->children
);
489 if (cur
->version
!= NULL
) xmlFree((char *) cur
->version
);
490 if (cur
->name
!= NULL
) xmlFree((char *) cur
->name
);
491 if (cur
->encoding
!= NULL
) xmlFree((char *) cur
->encoding
);
492 if (cur
->oldNs
!= NULL
) xmlFreeNsList(cur
->oldNs
);
493 if (cur
->URL
!= NULL
) xmlFree((char *) cur
->URL
);
494 if (cur
->dict
!= NULL
) xmlDictFree(cur
->dict
);
499 /************************************************************************
501 * The reader core parser *
503 ************************************************************************/
506 xmlTextReaderDebug(xmlTextReaderPtr reader
) {
507 if ((reader
== NULL
) || (reader
->ctxt
== NULL
)) {
508 fprintf(stderr
, "xmlTextReader NULL\n");
511 fprintf(stderr
, "xmlTextReader: state %d depth %d ",
512 reader
->state
, reader
->depth
);
513 if (reader
->node
== NULL
) {
514 fprintf(stderr
, "node = NULL\n");
516 fprintf(stderr
, "node %s\n", reader
->node
->name
);
518 fprintf(stderr
, " input: base %d, cur %d, depth %d: ",
519 reader
->base
, reader
->cur
, reader
->ctxt
->nodeNr
);
520 if (reader
->input
->buffer
== NULL
) {
521 fprintf(stderr
, "buffer is NULL\n");
523 #ifdef LIBXML_DEBUG_ENABLED
524 xmlDebugDumpString(stderr
,
525 &reader
->input
->buffer
->content
[reader
->cur
]);
527 fprintf(stderr
, "\n");
533 * xmlTextReaderEntPush:
534 * @reader: the xmlTextReaderPtr used
535 * @value: the entity reference node
537 * Pushes a new entity reference node on top of the entities stack
539 * Returns 0 in case of error, the index in the stack otherwise
542 xmlTextReaderEntPush(xmlTextReaderPtr reader
, xmlNodePtr value
)
544 if (reader
->entMax
<= 0) {
546 reader
->entTab
= (xmlNodePtr
*) xmlMalloc(reader
->entMax
*
547 sizeof(reader
->entTab
[0]));
548 if (reader
->entTab
== NULL
) {
549 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
553 if (reader
->entNr
>= reader
->entMax
) {
556 (xmlNodePtr
*) xmlRealloc(reader
->entTab
,
558 sizeof(reader
->entTab
[0]));
559 if (reader
->entTab
== NULL
) {
560 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
564 reader
->entTab
[reader
->entNr
] = value
;
566 return (reader
->entNr
++);
570 * xmlTextReaderEntPop:
571 * @reader: the xmlTextReaderPtr used
573 * Pops the top element entity from the entities stack
575 * Returns the entity just removed
578 xmlTextReaderEntPop(xmlTextReaderPtr reader
)
582 if (reader
->entNr
<= 0)
585 if (reader
->entNr
> 0)
586 reader
->ent
= reader
->entTab
[reader
->entNr
- 1];
589 ret
= reader
->entTab
[reader
->entNr
];
590 reader
->entTab
[reader
->entNr
] = NULL
;
595 * xmlTextReaderStartElement:
596 * @ctx: the user data (XML parser context)
597 * @fullname: The element name, including namespace prefix
598 * @atts: An array of name/value attributes pairs, NULL terminated
600 * called when an opening tag has been processed.
603 xmlTextReaderStartElement(void *ctx
, const xmlChar
*fullname
,
604 const xmlChar
**atts
) {
605 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
606 xmlTextReaderPtr reader
= ctxt
->_private
;
608 #ifdef DEBUG_CALLBACKS
609 printf("xmlTextReaderStartElement(%s)\n", fullname
);
611 if ((reader
!= NULL
) && (reader
->startElement
!= NULL
)) {
612 reader
->startElement(ctx
, fullname
, atts
);
613 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
614 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
615 (ctxt
->input
->cur
[1] == '>'))
616 ctxt
->node
->extra
= NODE_IS_EMPTY
;
619 reader
->state
= XML_TEXTREADER_ELEMENT
;
623 * xmlTextReaderEndElement:
624 * @ctx: the user data (XML parser context)
625 * @fullname: The element name, including namespace prefix
627 * called when an ending tag has been processed.
630 xmlTextReaderEndElement(void *ctx
, const xmlChar
*fullname
) {
631 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
632 xmlTextReaderPtr reader
= ctxt
->_private
;
634 #ifdef DEBUG_CALLBACKS
635 printf("xmlTextReaderEndElement(%s)\n", fullname
);
637 if ((reader
!= NULL
) && (reader
->endElement
!= NULL
)) {
638 reader
->endElement(ctx
, fullname
);
643 * xmlTextReaderStartElementNs:
644 * @ctx: the user data (XML parser context)
645 * @localname: the local name of the element
646 * @prefix: the element namespace prefix if available
647 * @URI: the element namespace name if available
648 * @nb_namespaces: number of namespace definitions on that node
649 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
650 * @nb_attributes: the number of attributes on that node
651 * nb_defaulted: the number of defaulted attributes.
652 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
655 * called when an opening tag has been processed.
658 xmlTextReaderStartElementNs(void *ctx
,
659 const xmlChar
*localname
,
660 const xmlChar
*prefix
,
663 const xmlChar
**namespaces
,
666 const xmlChar
**attributes
)
668 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
669 xmlTextReaderPtr reader
= ctxt
->_private
;
671 #ifdef DEBUG_CALLBACKS
672 printf("xmlTextReaderStartElementNs(%s)\n", localname
);
674 if ((reader
!= NULL
) && (reader
->startElementNs
!= NULL
)) {
675 reader
->startElementNs(ctx
, localname
, prefix
, URI
, nb_namespaces
,
676 namespaces
, nb_attributes
, nb_defaulted
,
678 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
679 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
680 (ctxt
->input
->cur
[1] == '>'))
681 ctxt
->node
->extra
= NODE_IS_EMPTY
;
684 reader
->state
= XML_TEXTREADER_ELEMENT
;
688 * xmlTextReaderEndElementNs:
689 * @ctx: the user data (XML parser context)
690 * @localname: the local name of the element
691 * @prefix: the element namespace prefix if available
692 * @URI: the element namespace name if available
694 * called when an ending tag has been processed.
697 xmlTextReaderEndElementNs(void *ctx
,
698 const xmlChar
* localname
,
699 const xmlChar
* prefix
,
702 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
703 xmlTextReaderPtr reader
= ctxt
->_private
;
705 #ifdef DEBUG_CALLBACKS
706 printf("xmlTextReaderEndElementNs(%s)\n", localname
);
708 if ((reader
!= NULL
) && (reader
->endElementNs
!= NULL
)) {
709 reader
->endElementNs(ctx
, localname
, prefix
, URI
);
715 * xmlTextReaderCharacters:
716 * @ctx: the user data (XML parser context)
717 * @ch: a xmlChar string
718 * @len: the number of xmlChar
720 * receiving some chars from the parser.
723 xmlTextReaderCharacters(void *ctx
, const xmlChar
*ch
, int len
)
725 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
726 xmlTextReaderPtr reader
= ctxt
->_private
;
728 #ifdef DEBUG_CALLBACKS
729 printf("xmlTextReaderCharacters()\n");
731 if ((reader
!= NULL
) && (reader
->characters
!= NULL
)) {
732 reader
->characters(ctx
, ch
, len
);
737 * xmlTextReaderCDataBlock:
738 * @ctx: the user data (XML parser context)
739 * @value: The pcdata content
740 * @len: the block length
742 * called when a pcdata block has been parsed
745 xmlTextReaderCDataBlock(void *ctx
, const xmlChar
*ch
, int len
)
747 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
748 xmlTextReaderPtr reader
= ctxt
->_private
;
750 #ifdef DEBUG_CALLBACKS
751 printf("xmlTextReaderCDataBlock()\n");
753 if ((reader
!= NULL
) && (reader
->cdataBlock
!= NULL
)) {
754 reader
->cdataBlock(ctx
, ch
, len
);
759 * xmlTextReaderPushData:
760 * @reader: the xmlTextReaderPtr used
762 * Push data down the progressive parser until a significant callback
765 * Returns -1 in case of failure, 0 otherwise
768 xmlTextReaderPushData(xmlTextReaderPtr reader
) {
771 xmlTextReaderState oldstate
;
774 if ((reader
->input
== NULL
) || (reader
->input
->buffer
== NULL
))
777 oldstate
= reader
->state
;
778 reader
->state
= XML_TEXTREADER_NONE
;
779 inbuf
= reader
->input
->buffer
;
780 alloc
= xmlBufGetAllocationScheme(inbuf
);
782 while (reader
->state
== XML_TEXTREADER_NONE
) {
783 if (xmlBufUse(inbuf
) < reader
->cur
+ CHUNK_SIZE
) {
785 * Refill the buffer unless we are at the end of the stream
787 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
788 val
= xmlParserInputBufferRead(reader
->input
, 4096);
790 (alloc
== XML_BUFFER_ALLOC_IMMUTABLE
)) {
791 if (xmlBufUse(inbuf
) == reader
->cur
) {
792 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
793 reader
->state
= oldstate
;
795 } else if (val
< 0) {
796 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
797 reader
->state
= oldstate
;
798 if ((oldstate
!= XML_TEXTREADER_START
) ||
799 (reader
->ctxt
->myDoc
!= NULL
))
801 } else if (val
== 0) {
802 /* mark the end of the stream and process the remains */
803 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
811 * parse by block of CHUNK_SIZE bytes, various tests show that
812 * it's the best tradeoff at least on a 1.2GH Duron
814 if (xmlBufUse(inbuf
) >= reader
->cur
+ CHUNK_SIZE
) {
815 val
= xmlParseChunk(reader
->ctxt
,
816 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
818 reader
->cur
+= CHUNK_SIZE
;
820 reader
->ctxt
->wellFormed
= 0;
821 if (reader
->ctxt
->wellFormed
== 0)
824 s
= xmlBufUse(inbuf
) - reader
->cur
;
825 val
= xmlParseChunk(reader
->ctxt
,
826 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
830 reader
->ctxt
->wellFormed
= 0;
836 * Discard the consumed input when needed and possible
838 if (reader
->mode
== XML_TEXTREADER_MODE_INTERACTIVE
) {
839 if (alloc
!= XML_BUFFER_ALLOC_IMMUTABLE
) {
840 if ((reader
->cur
>= 4096) &&
841 (xmlBufUse(inbuf
) - reader
->cur
<= CHUNK_SIZE
)) {
842 val
= xmlBufShrink(inbuf
, reader
->cur
);
851 * At the end of the stream signal that the work is done to the Push
854 else if (reader
->mode
== XML_TEXTREADER_MODE_EOF
) {
855 if (reader
->state
!= XML_TEXTREADER_DONE
) {
856 s
= xmlBufUse(inbuf
) - reader
->cur
;
857 val
= xmlParseChunk(reader
->ctxt
,
858 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
860 reader
->cur
= xmlBufUse(inbuf
);
861 reader
->state
= XML_TEXTREADER_DONE
;
863 if (reader
->ctxt
->wellFormed
)
864 reader
->ctxt
->wellFormed
= 0;
870 reader
->state
= oldstate
;
871 if (reader
->ctxt
->wellFormed
== 0) {
872 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
879 #ifdef LIBXML_REGEXP_ENABLED
881 * xmlTextReaderValidatePush:
882 * @reader: the xmlTextReaderPtr used
884 * Push the current node for validation
887 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
) {
888 xmlNodePtr node
= reader
->node
;
890 #ifdef LIBXML_VALID_ENABLED
891 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
892 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
893 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
894 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
895 reader
->ctxt
->myDoc
, node
, node
->name
);
897 /* TODO use the BuildQName interface */
900 qname
= xmlStrdup(node
->ns
->prefix
);
901 qname
= xmlStrcat(qname
, BAD_CAST
":");
902 qname
= xmlStrcat(qname
, node
->name
);
903 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
904 reader
->ctxt
->myDoc
, node
, qname
);
909 #endif /* LIBXML_VALID_ENABLED */
910 #ifdef LIBXML_SCHEMAS_ENABLED
911 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
912 (reader
->rngValidCtxt
!= NULL
)) {
915 if (reader
->rngFullNode
!= NULL
) return;
916 ret
= xmlRelaxNGValidatePushElement(reader
->rngValidCtxt
,
921 * this element requires a full tree
923 node
= xmlTextReaderExpand(reader
);
927 ret
= xmlRelaxNGValidateFullElement(reader
->rngValidCtxt
,
930 reader
->rngFullNode
= node
;
934 reader
->rngValidErrors
++;
940 * xmlTextReaderValidateCData:
941 * @reader: the xmlTextReaderPtr used
942 * @data: pointer to the CData
943 * @len: length of the CData block in bytes.
945 * Push some CData for validation
948 xmlTextReaderValidateCData(xmlTextReaderPtr reader
,
949 const xmlChar
*data
, int len
) {
950 #ifdef LIBXML_VALID_ENABLED
951 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
952 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
953 reader
->ctxt
->valid
&= xmlValidatePushCData(&reader
->ctxt
->vctxt
,
956 #endif /* LIBXML_VALID_ENABLED */
957 #ifdef LIBXML_SCHEMAS_ENABLED
958 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
959 (reader
->rngValidCtxt
!= NULL
)) {
962 if (reader
->rngFullNode
!= NULL
) return;
963 ret
= xmlRelaxNGValidatePushCData(reader
->rngValidCtxt
, data
, len
);
965 reader
->rngValidErrors
++;
971 * xmlTextReaderValidatePop:
972 * @reader: the xmlTextReaderPtr used
974 * Pop the current node from validation
977 xmlTextReaderValidatePop(xmlTextReaderPtr reader
) {
978 xmlNodePtr node
= reader
->node
;
980 #ifdef LIBXML_VALID_ENABLED
981 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
982 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
983 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
984 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
985 reader
->ctxt
->myDoc
, node
, node
->name
);
987 /* TODO use the BuildQName interface */
990 qname
= xmlStrdup(node
->ns
->prefix
);
991 qname
= xmlStrcat(qname
, BAD_CAST
":");
992 qname
= xmlStrcat(qname
, node
->name
);
993 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
994 reader
->ctxt
->myDoc
, node
, qname
);
999 #endif /* LIBXML_VALID_ENABLED */
1000 #ifdef LIBXML_SCHEMAS_ENABLED
1001 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1002 (reader
->rngValidCtxt
!= NULL
)) {
1005 if (reader
->rngFullNode
!= NULL
) {
1006 if (node
== reader
->rngFullNode
)
1007 reader
->rngFullNode
= NULL
;
1010 ret
= xmlRelaxNGValidatePopElement(reader
->rngValidCtxt
,
1011 reader
->ctxt
->myDoc
,
1014 reader
->rngValidErrors
++;
1020 * xmlTextReaderValidateEntity:
1021 * @reader: the xmlTextReaderPtr used
1023 * Handle the validation when an entity reference is encountered and
1024 * entity substitution is not activated. As a result the parser interface
1025 * must walk through the entity and do the validation calls
1028 xmlTextReaderValidateEntity(xmlTextReaderPtr reader
) {
1029 xmlNodePtr oldnode
= reader
->node
;
1030 xmlNodePtr node
= reader
->node
;
1033 if (node
->type
== XML_ENTITY_REF_NODE
) {
1034 if ((node
->children
!= NULL
) &&
1035 (node
->children
->type
== XML_ENTITY_DECL
) &&
1036 (node
->children
->children
!= NULL
)) {
1037 xmlTextReaderEntPush(reader
, node
);
1038 node
= node
->children
->children
;
1042 * The error has probably been raised already.
1044 if (node
== oldnode
)
1048 #ifdef LIBXML_REGEXP_ENABLED
1049 } else if (node
->type
== XML_ELEMENT_NODE
) {
1050 reader
->node
= node
;
1051 xmlTextReaderValidatePush(reader
);
1052 } else if ((node
->type
== XML_TEXT_NODE
) ||
1053 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1054 xmlTextReaderValidateCData(reader
, node
->content
,
1055 xmlStrlen(node
->content
));
1062 if (node
->children
!= NULL
) {
1063 node
= node
->children
;
1065 } else if (node
->type
== XML_ELEMENT_NODE
) {
1066 xmlTextReaderValidatePop(reader
);
1069 if (node
->next
!= NULL
) {
1074 node
= node
->parent
;
1075 if (node
->type
== XML_ELEMENT_NODE
) {
1077 if (reader
->entNr
== 0) {
1078 while ((tmp
= node
->last
) != NULL
) {
1079 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1081 xmlTextReaderFreeNode(reader
, tmp
);
1086 reader
->node
= node
;
1087 xmlTextReaderValidatePop(reader
);
1089 if ((node
->type
== XML_ENTITY_DECL
) &&
1090 (reader
->ent
!= NULL
) && (reader
->ent
->children
== node
)) {
1091 node
= xmlTextReaderEntPop(reader
);
1093 if (node
== oldnode
)
1095 if (node
->next
!= NULL
) {
1099 } while ((node
!= NULL
) && (node
!= oldnode
));
1100 } while ((node
!= NULL
) && (node
!= oldnode
));
1101 reader
->node
= oldnode
;
1103 #endif /* LIBXML_REGEXP_ENABLED */
1107 * xmlTextReaderGetSuccessor:
1108 * @cur: the current node
1110 * Get the successor of a node if available.
1112 * Returns the successor node or NULL
1115 xmlTextReaderGetSuccessor(xmlNodePtr cur
) {
1116 if (cur
== NULL
) return(NULL
) ; /* ERROR */
1117 if (cur
->next
!= NULL
) return(cur
->next
) ;
1120 if (cur
== NULL
) break;
1121 if (cur
->next
!= NULL
) return(cur
->next
);
1122 } while (cur
!= NULL
);
1127 * xmlTextReaderDoExpand:
1128 * @reader: the xmlTextReaderPtr used
1130 * Makes sure that the current node is fully read as well as all its
1131 * descendant. It means the full DOM subtree must be available at the
1134 * Returns 1 if the node was expanded successfully, 0 if there is no more
1135 * nodes to read, or -1 in case of error
1138 xmlTextReaderDoExpand(xmlTextReaderPtr reader
) {
1141 if ((reader
== NULL
) || (reader
->node
== NULL
) || (reader
->ctxt
== NULL
))
1144 if (reader
->ctxt
->instate
== XML_PARSER_EOF
) return(1);
1146 if (xmlTextReaderGetSuccessor(reader
->node
) != NULL
)
1148 if (reader
->ctxt
->nodeNr
< reader
->depth
)
1150 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1152 val
= xmlTextReaderPushData(reader
);
1154 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1157 } while(reader
->mode
!= XML_TEXTREADER_MODE_EOF
);
1162 * xmlTextReaderCollectSiblings:
1163 * @node: the first child
1165 * Traverse depth-first through all sibling nodes and their children
1166 * nodes and concatenate their content. This is an auxiliary function
1167 * to xmlTextReaderReadString.
1169 * Returns a string containing the content, or NULL in case of error.
1172 xmlTextReaderCollectSiblings(xmlNodePtr node
)
1174 xmlBufferPtr buffer
;
1177 if ((node
== NULL
) || (node
->type
== XML_NAMESPACE_DECL
))
1180 buffer
= xmlBufferCreate();
1183 xmlBufferSetAllocationScheme(buffer
, XML_BUFFER_ALLOC_DOUBLEIT
);
1185 for ( ; node
!= NULL
; node
= node
->next
) {
1186 switch (node
->type
) {
1188 case XML_CDATA_SECTION_NODE
:
1189 xmlBufferCat(buffer
, node
->content
);
1191 case XML_ELEMENT_NODE
: {
1194 tmp
= xmlTextReaderCollectSiblings(node
->children
);
1195 xmlBufferCat(buffer
, tmp
);
1203 ret
= buffer
->content
;
1204 buffer
->content
= NULL
;
1205 xmlBufferFree(buffer
);
1210 * xmlTextReaderRead:
1211 * @reader: the xmlTextReaderPtr used
1213 * Moves the position of the current instance to the next node in
1214 * the stream, exposing its properties.
1216 * Returns 1 if the node was read successfully, 0 if there is no more
1217 * nodes to read, or -1 in case of error
1220 xmlTextReaderRead(xmlTextReaderPtr reader
) {
1221 int val
, olddepth
= 0;
1222 xmlTextReaderState oldstate
= XML_TEXTREADER_START
;
1223 xmlNodePtr oldnode
= NULL
;
1228 reader
->curnode
= NULL
;
1229 if (reader
->doc
!= NULL
)
1230 return(xmlTextReaderReadTree(reader
));
1231 if (reader
->ctxt
== NULL
)
1235 fprintf(stderr
, "\nREAD ");
1238 if (reader
->mode
== XML_TEXTREADER_MODE_INITIAL
) {
1239 reader
->mode
= XML_TEXTREADER_MODE_INTERACTIVE
;
1244 val
= xmlTextReaderPushData(reader
);
1246 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1247 reader
->state
= XML_TEXTREADER_ERROR
;
1250 } while ((reader
->ctxt
->node
== NULL
) &&
1251 ((reader
->mode
!= XML_TEXTREADER_MODE_EOF
) &&
1252 (reader
->state
!= XML_TEXTREADER_DONE
)));
1253 if (reader
->ctxt
->node
== NULL
) {
1254 if (reader
->ctxt
->myDoc
!= NULL
) {
1255 reader
->node
= reader
->ctxt
->myDoc
->children
;
1257 if (reader
->node
== NULL
){
1258 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1259 reader
->state
= XML_TEXTREADER_ERROR
;
1262 reader
->state
= XML_TEXTREADER_ELEMENT
;
1264 if (reader
->ctxt
->myDoc
!= NULL
) {
1265 reader
->node
= reader
->ctxt
->myDoc
->children
;
1267 if (reader
->node
== NULL
)
1268 reader
->node
= reader
->ctxt
->nodeTab
[0];
1269 reader
->state
= XML_TEXTREADER_ELEMENT
;
1272 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
1275 oldstate
= reader
->state
;
1276 olddepth
= reader
->ctxt
->nodeNr
;
1277 oldnode
= reader
->node
;
1280 if (reader
->node
== NULL
) {
1281 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1288 * If we are not backtracking on ancestors or examined nodes,
1289 * that the parser didn't finished or that we aren't at the end
1290 * of stream, continue processing.
1292 while ((reader
->node
!= NULL
) && (reader
->node
->next
== NULL
) &&
1293 (reader
->ctxt
->nodeNr
== olddepth
) &&
1294 ((oldstate
== XML_TEXTREADER_BACKTRACK
) ||
1295 (reader
->node
->children
== NULL
) ||
1296 (reader
->node
->type
== XML_ENTITY_REF_NODE
) ||
1297 ((reader
->node
->children
!= NULL
) &&
1298 (reader
->node
->children
->type
== XML_TEXT_NODE
) &&
1299 (reader
->node
->children
->next
== NULL
)) ||
1300 (reader
->node
->type
== XML_DTD_NODE
) ||
1301 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1302 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) &&
1303 ((reader
->ctxt
->node
== NULL
) ||
1304 (reader
->ctxt
->node
== reader
->node
) ||
1305 (reader
->ctxt
->node
== reader
->node
->parent
)) &&
1306 (reader
->ctxt
->instate
!= XML_PARSER_EOF
)) {
1307 val
= xmlTextReaderPushData(reader
);
1309 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1310 reader
->state
= XML_TEXTREADER_ERROR
;
1313 if (reader
->node
== NULL
)
1316 if (oldstate
!= XML_TEXTREADER_BACKTRACK
) {
1317 if ((reader
->node
->children
!= NULL
) &&
1318 (reader
->node
->type
!= XML_ENTITY_REF_NODE
) &&
1319 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1320 (reader
->node
->type
!= XML_DTD_NODE
)) {
1321 reader
->node
= reader
->node
->children
;
1323 reader
->state
= XML_TEXTREADER_ELEMENT
;
1327 if (reader
->node
->next
!= NULL
) {
1328 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1329 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1330 (reader
->node
->children
== NULL
) &&
1331 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)
1332 #ifdef LIBXML_XINCLUDE_ENABLED
1333 && (reader
->in_xinclude
<= 0)
1336 reader
->state
= XML_TEXTREADER_END
;
1339 #ifdef LIBXML_REGEXP_ENABLED
1340 if ((reader
->validate
) &&
1341 (reader
->node
->type
== XML_ELEMENT_NODE
))
1342 xmlTextReaderValidatePop(reader
);
1343 #endif /* LIBXML_REGEXP_ENABLED */
1344 if ((reader
->preserves
> 0) &&
1345 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1346 reader
->preserves
--;
1347 reader
->node
= reader
->node
->next
;
1348 reader
->state
= XML_TEXTREADER_ELEMENT
;
1351 * Cleanup of the old node
1353 if ((reader
->preserves
== 0) &&
1354 #ifdef LIBXML_XINCLUDE_ENABLED
1355 (reader
->in_xinclude
== 0) &&
1357 (reader
->entNr
== 0) &&
1358 (reader
->node
->prev
!= NULL
) &&
1359 (reader
->node
->prev
->type
!= XML_DTD_NODE
)) {
1360 xmlNodePtr tmp
= reader
->node
->prev
;
1361 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1365 xmlTextReaderFreeNode(reader
, tmp
);
1371 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1372 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1373 (reader
->node
->children
== NULL
) &&
1374 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)) {;
1375 reader
->state
= XML_TEXTREADER_END
;
1378 #ifdef LIBXML_REGEXP_ENABLED
1379 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
->type
== XML_ELEMENT_NODE
))
1380 xmlTextReaderValidatePop(reader
);
1381 #endif /* LIBXML_REGEXP_ENABLED */
1382 if ((reader
->preserves
> 0) &&
1383 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1384 reader
->preserves
--;
1385 reader
->node
= reader
->node
->parent
;
1386 if ((reader
->node
== NULL
) ||
1387 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1388 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) {
1389 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
1390 val
= xmlParseChunk(reader
->ctxt
, "", 0, 1);
1391 reader
->state
= XML_TEXTREADER_DONE
;
1395 reader
->node
= NULL
;
1399 * Cleanup of the old node
1401 if ((oldnode
!= NULL
) && (reader
->preserves
== 0) &&
1402 #ifdef LIBXML_XINCLUDE_ENABLED
1403 (reader
->in_xinclude
== 0) &&
1405 (reader
->entNr
== 0) &&
1406 (oldnode
->type
!= XML_DTD_NODE
) &&
1407 ((oldnode
->extra
& NODE_IS_PRESERVED
) == 0)) {
1408 xmlUnlinkNode(oldnode
);
1409 xmlTextReaderFreeNode(reader
, oldnode
);
1414 if ((reader
->preserves
== 0) &&
1415 #ifdef LIBXML_XINCLUDE_ENABLED
1416 (reader
->in_xinclude
== 0) &&
1418 (reader
->entNr
== 0) &&
1419 (reader
->node
->last
!= NULL
) &&
1420 ((reader
->node
->last
->extra
& NODE_IS_PRESERVED
) == 0)) {
1421 xmlNodePtr tmp
= reader
->node
->last
;
1423 xmlTextReaderFreeNode(reader
, tmp
);
1426 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1432 * If we are in the middle of a piece of CDATA make sure it's finished
1434 if ((reader
->node
!= NULL
) &&
1435 (reader
->node
->next
== NULL
) &&
1436 ((reader
->node
->type
== XML_TEXT_NODE
) ||
1437 (reader
->node
->type
== XML_CDATA_SECTION_NODE
))) {
1438 if (xmlTextReaderExpand(reader
) == NULL
)
1442 #ifdef LIBXML_XINCLUDE_ENABLED
1444 * Handle XInclude if asked for
1446 if ((reader
->xinclude
) && (reader
->in_xinclude
== 0) &&
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
));
1458 * expand that node and process it
1460 if (xmlTextReaderExpand(reader
) == NULL
)
1462 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1464 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1465 reader
->in_xinclude
++;
1468 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1469 reader
->in_xinclude
--;
1474 * Handle entities enter and exit when in entity replacement mode
1476 if ((reader
->node
!= NULL
) &&
1477 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1478 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1479 if ((reader
->node
->children
!= NULL
) &&
1480 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1481 (reader
->node
->children
->children
!= NULL
)) {
1482 xmlTextReaderEntPush(reader
, reader
->node
);
1483 reader
->node
= reader
->node
->children
->children
;
1485 #ifdef LIBXML_REGEXP_ENABLED
1486 } else if ((reader
->node
!= NULL
) &&
1487 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1488 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1489 xmlTextReaderValidateEntity(reader
);
1490 #endif /* LIBXML_REGEXP_ENABLED */
1492 if ((reader
->node
!= NULL
) &&
1493 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1494 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1495 reader
->node
= xmlTextReaderEntPop(reader
);
1499 #ifdef LIBXML_REGEXP_ENABLED
1500 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
!= NULL
)) {
1501 xmlNodePtr node
= reader
->node
;
1503 if ((node
->type
== XML_ELEMENT_NODE
) &&
1504 ((reader
->state
!= XML_TEXTREADER_END
) &&
1505 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1506 xmlTextReaderValidatePush(reader
);
1507 } else if ((node
->type
== XML_TEXT_NODE
) ||
1508 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1509 xmlTextReaderValidateCData(reader
, node
->content
,
1510 xmlStrlen(node
->content
));
1513 #endif /* LIBXML_REGEXP_ENABLED */
1514 #ifdef LIBXML_PATTERN_ENABLED
1515 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1516 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1518 for (i
= 0;i
< reader
->patternNr
;i
++) {
1519 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1520 xmlTextReaderPreserve(reader
);
1525 #endif /* LIBXML_PATTERN_ENABLED */
1526 #ifdef LIBXML_SCHEMAS_ENABLED
1527 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1528 (reader
->xsdValidErrors
== 0) &&
1529 (reader
->xsdValidCtxt
!= NULL
)) {
1530 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1532 #endif /* LIBXML_PATTERN_ENABLED */
1535 reader
->state
= XML_TEXTREADER_DONE
;
1540 * xmlTextReaderReadState:
1541 * @reader: the xmlTextReaderPtr used
1543 * Gets the read state of the reader.
1545 * Returns the state value, or -1 in case of error
1548 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1551 return(reader
->mode
);
1555 * xmlTextReaderExpand:
1556 * @reader: the xmlTextReaderPtr used
1558 * Reads the contents of the current node and the full subtree. It then makes
1559 * the subtree available until the next xmlTextReaderRead() call
1561 * Returns a node pointer valid until the next xmlTextReaderRead() call
1562 * or NULL in case of error.
1565 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1566 if ((reader
== NULL
) || (reader
->node
== NULL
))
1568 if (reader
->doc
!= NULL
)
1569 return(reader
->node
);
1570 if (reader
->ctxt
== NULL
)
1572 if (xmlTextReaderDoExpand(reader
) < 0)
1574 return(reader
->node
);
1578 * xmlTextReaderNext:
1579 * @reader: the xmlTextReaderPtr used
1581 * Skip to the node following the current one in document order while
1582 * avoiding the subtree if any.
1584 * Returns 1 if the node was read successfully, 0 if there is no more
1585 * nodes to read, or -1 in case of error
1588 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1594 if (reader
->doc
!= NULL
)
1595 return(xmlTextReaderNextTree(reader
));
1597 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1598 return(xmlTextReaderRead(reader
));
1599 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1600 return(xmlTextReaderRead(reader
));
1601 if (cur
->extra
& NODE_IS_EMPTY
)
1602 return(xmlTextReaderRead(reader
));
1604 ret
= xmlTextReaderRead(reader
);
1607 } while (reader
->node
!= cur
);
1608 return(xmlTextReaderRead(reader
));
1611 #ifdef LIBXML_WRITER_ENABLED
1613 * xmlTextReaderReadInnerXml:
1614 * @reader: the xmlTextReaderPtr used
1616 * Reads the contents of the current node, including child nodes and markup.
1618 * Returns a string containing the XML content, or NULL if the current node
1619 * is neither an element nor attribute, or has no child nodes. The
1620 * string must be deallocated by the caller.
1623 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1626 xmlNodePtr node
, cur_node
;
1627 xmlBufferPtr buff
, buff2
;
1630 if (xmlTextReaderExpand(reader
) == NULL
) {
1633 doc
= reader
->node
->doc
;
1634 buff
= xmlBufferCreate();
1637 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1638 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1639 cur_node
= cur_node
->next
) {
1640 /* XXX: Why is the node copied? */
1641 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1642 /* XXX: Why do we need a second buffer? */
1643 buff2
= xmlBufferCreate();
1644 xmlBufferSetAllocationScheme(buff2
, XML_BUFFER_ALLOC_DOUBLEIT
);
1645 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1647 xmlBufferFree(buff2
);
1648 xmlBufferFree(buff
);
1651 xmlBufferCat(buff
, buff2
->content
);
1653 xmlBufferFree(buff2
);
1655 resbuf
= buff
->content
;
1656 buff
->content
= NULL
;
1658 xmlBufferFree(buff
);
1663 #ifdef LIBXML_WRITER_ENABLED
1665 * xmlTextReaderReadOuterXml:
1666 * @reader: the xmlTextReaderPtr used
1668 * Reads the contents of the current node, including child nodes and markup.
1670 * Returns a string containing the node and any XML content, or NULL if the
1671 * current node cannot be serialized. The string must be deallocated
1675 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1682 if (xmlTextReaderExpand(reader
) == NULL
) {
1685 node
= reader
->node
;
1687 /* XXX: Why is the node copied? */
1688 if (node
->type
== XML_DTD_NODE
) {
1689 node
= (xmlNodePtr
) xmlCopyDtd((xmlDtdPtr
) node
);
1691 node
= xmlDocCopyNode(node
, doc
, 1);
1693 buff
= xmlBufferCreate();
1694 xmlBufferSetAllocationScheme(buff
, XML_BUFFER_ALLOC_DOUBLEIT
);
1695 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1697 xmlBufferFree(buff
);
1701 resbuf
= buff
->content
;
1702 buff
->content
= NULL
;
1705 xmlBufferFree(buff
);
1711 * xmlTextReaderReadString:
1712 * @reader: the xmlTextReaderPtr used
1714 * Reads the contents of an element or a text node as a string.
1716 * Returns a string containing the contents of the Element or Text node,
1717 * or NULL if the reader is positioned on any other type of node.
1718 * The string must be deallocated by the caller.
1721 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1725 if ((reader
== NULL
) || (reader
->node
== NULL
))
1728 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1729 switch (node
->type
) {
1731 if (node
->content
!= NULL
)
1732 return(xmlStrdup(node
->content
));
1734 case XML_ELEMENT_NODE
:
1735 if (xmlTextReaderDoExpand(reader
) != -1) {
1736 return xmlTextReaderCollectSiblings(node
->children
);
1739 case XML_ATTRIBUTE_NODE
:
1750 * xmlTextReaderReadBase64:
1751 * @reader: the xmlTextReaderPtr used
1752 * @array: a byte array to store the content.
1753 * @offset: the zero-based index into array where the method should
1755 * @len: the number of bytes to write.
1757 * Reads and decodes the Base64 encoded contents of an element and
1758 * stores the result in a byte buffer.
1760 * Returns the number of bytes written to array, or zero if the current
1761 * instance is not positioned on an element or -1 in case of error.
1764 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1765 unsigned char *array ATTRIBUTE_UNUSED
,
1766 int offset ATTRIBUTE_UNUSED
,
1767 int len ATTRIBUTE_UNUSED
) {
1768 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1770 if (reader
->ctxt
->wellFormed
!= 1)
1773 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1780 * xmlTextReaderReadBinHex:
1781 * @reader: the xmlTextReaderPtr used
1782 * @array: a byte array to store the content.
1783 * @offset: the zero-based index into array where the method should
1785 * @len: the number of bytes to write.
1787 * Reads and decodes the BinHex encoded contents of an element and
1788 * stores the result in a byte buffer.
1790 * Returns the number of bytes written to array, or zero if the current
1791 * instance is not positioned on an element or -1 in case of error.
1794 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1795 unsigned char *array ATTRIBUTE_UNUSED
,
1796 int offset ATTRIBUTE_UNUSED
,
1797 int len ATTRIBUTE_UNUSED
) {
1798 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1800 if (reader
->ctxt
->wellFormed
!= 1)
1803 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1810 /************************************************************************
1812 * Operating on a preparsed tree *
1814 ************************************************************************/
1816 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1821 if (reader
->state
== XML_TEXTREADER_END
)
1824 if (reader
->node
== NULL
) {
1825 if (reader
->doc
->children
== NULL
) {
1826 reader
->state
= XML_TEXTREADER_END
;
1830 reader
->node
= reader
->doc
->children
;
1831 reader
->state
= XML_TEXTREADER_START
;
1835 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1836 /* Here removed traversal to child, because we want to skip the subtree,
1837 replace with traversal to sibling to skip subtree */
1838 if (reader
->node
->next
!= 0) {
1839 /* Move to sibling if present,skipping sub-tree */
1840 reader
->node
= reader
->node
->next
;
1841 reader
->state
= XML_TEXTREADER_START
;
1845 /* if reader->node->next is NULL mean no subtree for current node,
1846 so need to move to sibling of parent node if present */
1847 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1848 /* This will move to parent if present */
1849 xmlTextReaderRead(reader
);
1852 if (reader
->node
->next
!= 0) {
1853 reader
->node
= reader
->node
->next
;
1854 reader
->state
= XML_TEXTREADER_START
;
1858 if (reader
->node
->parent
!= 0) {
1859 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1860 reader
->state
= XML_TEXTREADER_END
;
1864 reader
->node
= reader
->node
->parent
;
1866 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1867 /* Repeat process to move to sibling of parent node if present */
1868 xmlTextReaderNextTree(reader
);
1871 reader
->state
= XML_TEXTREADER_END
;
1877 * xmlTextReaderReadTree:
1878 * @reader: the xmlTextReaderPtr used
1880 * Moves the position of the current instance to the next node in
1881 * the stream, exposing its properties.
1883 * Returns 1 if the node was read successfully, 0 if there is no more
1884 * nodes to read, or -1 in case of error
1887 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1888 if (reader
->state
== XML_TEXTREADER_END
)
1892 if (reader
->node
== NULL
) {
1893 if (reader
->doc
->children
== NULL
) {
1894 reader
->state
= XML_TEXTREADER_END
;
1898 reader
->node
= reader
->doc
->children
;
1899 reader
->state
= XML_TEXTREADER_START
;
1903 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1904 (reader
->node
->type
!= XML_DTD_NODE
) &&
1905 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1906 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1907 if (reader
->node
->children
!= NULL
) {
1908 reader
->node
= reader
->node
->children
;
1910 reader
->state
= XML_TEXTREADER_START
;
1914 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1915 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1920 if (reader
->node
->next
!= NULL
) {
1921 reader
->node
= reader
->node
->next
;
1922 reader
->state
= XML_TEXTREADER_START
;
1926 if (reader
->node
->parent
!= NULL
) {
1927 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
1928 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
1929 reader
->state
= XML_TEXTREADER_END
;
1933 reader
->node
= reader
->node
->parent
;
1935 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1939 reader
->state
= XML_TEXTREADER_END
;
1942 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
1943 (reader
->node
->type
== XML_XINCLUDE_END
))
1950 * xmlTextReaderNextSibling:
1951 * @reader: the xmlTextReaderPtr used
1953 * Skip to the node following the current one in document order while
1954 * avoiding the subtree if any.
1955 * Currently implemented only for Readers built on a document
1957 * Returns 1 if the node was read successfully, 0 if there is no more
1958 * nodes to read, or -1 in case of error
1961 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
1964 if (reader
->doc
== NULL
) {
1969 if (reader
->state
== XML_TEXTREADER_END
)
1972 if (reader
->node
== NULL
)
1973 return(xmlTextReaderNextTree(reader
));
1975 if (reader
->node
->next
!= NULL
) {
1976 reader
->node
= reader
->node
->next
;
1977 reader
->state
= XML_TEXTREADER_START
;
1984 /************************************************************************
1986 * Constructor and destructors *
1988 ************************************************************************/
1991 * @input: the xmlParserInputBufferPtr used to read data
1992 * @URI: the URI information for the source if available
1994 * Create an xmlTextReader structure fed with @input
1996 * Returns the new xmlTextReaderPtr or NULL in case of error
1999 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2000 xmlTextReaderPtr ret
;
2004 ret
= xmlMalloc(sizeof(xmlTextReader
));
2006 xmlGenericError(xmlGenericErrorContext
,
2007 "xmlNewTextReader : malloc failed\n");
2010 memset(ret
, 0, sizeof(xmlTextReader
));
2016 ret
->buffer
= xmlBufCreateSize(100);
2017 if (ret
->buffer
== NULL
) {
2019 xmlGenericError(xmlGenericErrorContext
,
2020 "xmlNewTextReader : malloc failed\n");
2023 /* no operation on a reader should require a huge buffer */
2024 xmlBufSetAllocationScheme(ret
->buffer
,
2025 XML_BUFFER_ALLOC_DOUBLEIT
);
2026 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2027 if (ret
->sax
== NULL
) {
2028 xmlBufFree(ret
->buffer
);
2030 xmlGenericError(xmlGenericErrorContext
,
2031 "xmlNewTextReader : malloc failed\n");
2034 xmlSAXVersion(ret
->sax
, 2);
2035 ret
->startElement
= ret
->sax
->startElement
;
2036 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2037 ret
->endElement
= ret
->sax
->endElement
;
2038 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2039 #ifdef LIBXML_SAX1_ENABLED
2040 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2041 #endif /* LIBXML_SAX1_ENABLED */
2042 ret
->startElementNs
= ret
->sax
->startElementNs
;
2043 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2044 ret
->endElementNs
= ret
->sax
->endElementNs
;
2045 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2046 #ifdef LIBXML_SAX1_ENABLED
2048 ret
->startElementNs
= NULL
;
2049 ret
->endElementNs
= NULL
;
2051 #endif /* LIBXML_SAX1_ENABLED */
2052 ret
->characters
= ret
->sax
->characters
;
2053 ret
->sax
->characters
= xmlTextReaderCharacters
;
2054 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2055 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2056 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2058 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2060 ret
->curnode
= NULL
;
2061 if (xmlBufUse(ret
->input
->buffer
) < 4) {
2062 xmlParserInputBufferRead(input
, 4);
2064 if (xmlBufUse(ret
->input
->buffer
) >= 4) {
2065 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2066 (const char *) xmlBufContent(ret
->input
->buffer
),
2071 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2076 if (ret
->ctxt
== NULL
) {
2077 xmlGenericError(xmlGenericErrorContext
,
2078 "xmlNewTextReader : malloc failed\n");
2079 xmlBufFree(ret
->buffer
);
2084 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2085 ret
->ctxt
->_private
= ret
;
2086 ret
->ctxt
->linenumbers
= 1;
2087 ret
->ctxt
->dictNames
= 1;
2088 ret
->allocs
= XML_TEXTREADER_CTXT
;
2090 * use the parser dictionary to allocate all elements and attributes names
2092 ret
->ctxt
->docdict
= 1;
2093 ret
->dict
= ret
->ctxt
->dict
;
2094 #ifdef LIBXML_XINCLUDE_ENABLED
2097 #ifdef LIBXML_PATTERN_ENABLED
2098 ret
->patternMax
= 0;
2099 ret
->patternTab
= NULL
;
2105 * xmlNewTextReaderFilename:
2106 * @URI: the URI of the resource to process
2108 * Create an xmlTextReader structure fed with the resource at @URI
2110 * Returns the new xmlTextReaderPtr or NULL in case of error
2113 xmlNewTextReaderFilename(const char *URI
) {
2114 xmlParserInputBufferPtr input
;
2115 xmlTextReaderPtr ret
;
2116 char *directory
= NULL
;
2118 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2121 ret
= xmlNewTextReader(input
, URI
);
2123 xmlFreeParserInputBuffer(input
);
2126 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2127 if (ret
->ctxt
->directory
== NULL
)
2128 directory
= xmlParserGetDirectory(URI
);
2129 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2130 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2131 if (directory
!= NULL
)
2137 * xmlFreeTextReader:
2138 * @reader: the xmlTextReaderPtr
2140 * Deallocate all the resources associated to the reader
2143 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2146 #ifdef LIBXML_SCHEMAS_ENABLED
2147 if (reader
->rngSchemas
!= NULL
) {
2148 xmlRelaxNGFree(reader
->rngSchemas
);
2149 reader
->rngSchemas
= NULL
;
2151 if (reader
->rngValidCtxt
!= NULL
) {
2152 if (! reader
->rngPreserveCtxt
)
2153 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2154 reader
->rngValidCtxt
= NULL
;
2156 if (reader
->xsdPlug
!= NULL
) {
2157 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2158 reader
->xsdPlug
= NULL
;
2160 if (reader
->xsdValidCtxt
!= NULL
) {
2161 if (! reader
->xsdPreserveCtxt
)
2162 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2163 reader
->xsdValidCtxt
= NULL
;
2165 if (reader
->xsdSchemas
!= NULL
) {
2166 xmlSchemaFree(reader
->xsdSchemas
);
2167 reader
->xsdSchemas
= NULL
;
2170 #ifdef LIBXML_XINCLUDE_ENABLED
2171 if (reader
->xincctxt
!= NULL
)
2172 xmlXIncludeFreeContext(reader
->xincctxt
);
2174 #ifdef LIBXML_PATTERN_ENABLED
2175 if (reader
->patternTab
!= NULL
) {
2177 for (i
= 0;i
< reader
->patternNr
;i
++) {
2178 if (reader
->patternTab
[i
] != NULL
)
2179 xmlFreePattern(reader
->patternTab
[i
]);
2181 xmlFree(reader
->patternTab
);
2184 if (reader
->mode
!= XML_TEXTREADER_MODE_CLOSED
)
2185 xmlTextReaderClose(reader
);
2186 if (reader
->ctxt
!= NULL
) {
2187 if (reader
->dict
== reader
->ctxt
->dict
)
2188 reader
->dict
= NULL
;
2189 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2190 xmlFreeParserCtxt(reader
->ctxt
);
2192 if (reader
->sax
!= NULL
)
2193 xmlFree(reader
->sax
);
2194 if (reader
->buffer
!= NULL
)
2195 xmlBufFree(reader
->buffer
);
2196 if (reader
->entTab
!= NULL
)
2197 xmlFree(reader
->entTab
);
2198 if (reader
->dict
!= NULL
)
2199 xmlDictFree(reader
->dict
);
2203 /************************************************************************
2205 * Methods for XmlTextReader *
2207 ************************************************************************/
2209 * xmlTextReaderClose:
2210 * @reader: the xmlTextReaderPtr used
2212 * This method releases any resources allocated by the current instance
2213 * changes the state to Closed and close any underlying input.
2215 * Returns 0 or -1 in case of error
2218 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2221 reader
->node
= NULL
;
2222 reader
->curnode
= NULL
;
2223 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2224 if (reader
->faketext
!= NULL
) {
2225 xmlFreeNode(reader
->faketext
);
2226 reader
->faketext
= NULL
;
2228 if (reader
->ctxt
!= NULL
) {
2229 #ifdef LIBXML_VALID_ENABLED
2230 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2231 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2232 #ifdef LIBXML_REGEXP_ENABLED
2233 while (reader
->ctxt
->vctxt
.vstateNr
> 0)
2234 xmlValidatePopElement(&reader
->ctxt
->vctxt
, NULL
, NULL
, NULL
);
2235 #endif /* LIBXML_REGEXP_ENABLED */
2236 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2237 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2238 reader
->ctxt
->vctxt
.vstateMax
= 0;
2240 #endif /* LIBXML_VALID_ENABLED */
2241 xmlStopParser(reader
->ctxt
);
2242 if (reader
->ctxt
->myDoc
!= NULL
) {
2243 if (reader
->preserve
== 0)
2244 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2245 reader
->ctxt
->myDoc
= NULL
;
2248 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2249 xmlFreeParserInputBuffer(reader
->input
);
2250 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2256 * xmlTextReaderGetAttributeNo:
2257 * @reader: the xmlTextReaderPtr used
2258 * @no: the zero-based index of the attribute relative to the containing element
2260 * Provides the value of the attribute with the specified index relative
2261 * to the containing element.
2263 * Returns a string containing the value of the specified attribute, or NULL
2264 * in case of error. The string must be deallocated by the caller.
2267 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2275 if (reader
->node
== NULL
)
2277 if (reader
->curnode
!= NULL
)
2279 /* TODO: handle the xmlDecl */
2280 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2283 ns
= reader
->node
->nsDef
;
2284 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2288 return(xmlStrdup(ns
->href
));
2290 cur
= reader
->node
->properties
;
2298 /* TODO walk the DTD if present */
2300 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2301 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2306 * xmlTextReaderGetAttribute:
2307 * @reader: the xmlTextReaderPtr used
2308 * @name: the qualified name of the attribute.
2310 * Provides the value of the attribute with the specified qualified name.
2312 * Returns a string containing the value of the specified attribute, or NULL
2313 * in case of error. The string must be deallocated by the caller.
2316 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2317 xmlChar
*prefix
= NULL
;
2320 xmlChar
*ret
= NULL
;
2322 if ((reader
== NULL
) || (name
== NULL
))
2324 if (reader
->node
== NULL
)
2326 if (reader
->curnode
!= NULL
)
2329 /* TODO: handle the xmlDecl */
2330 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2333 localname
= xmlSplitQName2(name
, &prefix
);
2334 if (localname
== NULL
) {
2336 * Namespace default decl
2338 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2339 ns
= reader
->node
->nsDef
;
2340 while (ns
!= NULL
) {
2341 if (ns
->prefix
== NULL
) {
2342 return(xmlStrdup(ns
->href
));
2348 return(xmlGetNoNsProp(reader
->node
, name
));
2352 * Namespace default decl
2354 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2355 ns
= reader
->node
->nsDef
;
2356 while (ns
!= NULL
) {
2357 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2358 ret
= xmlStrdup(ns
->href
);
2364 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2366 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2377 * xmlTextReaderGetAttributeNs:
2378 * @reader: the xmlTextReaderPtr used
2379 * @localName: the local name of the attribute.
2380 * @namespaceURI: the namespace URI of the attribute.
2382 * Provides the value of the specified attribute
2384 * Returns a string containing the value of the specified attribute, or NULL
2385 * in case of error. The string must be deallocated by the caller.
2388 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2389 const xmlChar
*namespaceURI
) {
2390 xmlChar
*prefix
= NULL
;
2393 if ((reader
== NULL
) || (localName
== NULL
))
2395 if (reader
->node
== NULL
)
2397 if (reader
->curnode
!= NULL
)
2400 /* TODO: handle the xmlDecl */
2401 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2404 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2405 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2406 prefix
= BAD_CAST localName
;
2408 ns
= reader
->node
->nsDef
;
2409 while (ns
!= NULL
) {
2410 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2411 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2412 return xmlStrdup(ns
->href
);
2419 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2423 * xmlTextReaderGetRemainder:
2424 * @reader: the xmlTextReaderPtr used
2426 * Method to get the remainder of the buffered XML. this method stops the
2427 * parser, set its state to End Of File and return the input stream with
2428 * what is left that the parser did not use.
2430 * The implementation is not good, the parser certainly progressed past
2431 * what's left in reader->input, and there is an allocation problem. Best
2432 * would be to rewrite it differently.
2434 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2437 xmlParserInputBufferPtr
2438 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2439 xmlParserInputBufferPtr ret
= NULL
;
2443 if (reader
->node
== NULL
)
2446 reader
->node
= NULL
;
2447 reader
->curnode
= NULL
;
2448 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2449 if (reader
->ctxt
!= NULL
) {
2450 xmlStopParser(reader
->ctxt
);
2451 if (reader
->ctxt
->myDoc
!= NULL
) {
2452 if (reader
->preserve
== 0)
2453 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2454 reader
->ctxt
->myDoc
= NULL
;
2457 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2458 ret
= reader
->input
;
2459 reader
->input
= NULL
;
2460 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2463 * Hum, one may need to duplicate the data structure because
2464 * without reference counting the input may be freed twice:
2465 * - by the layer which allocated it.
2466 * - by the layer to which would have been returned to.
2475 * xmlTextReaderLookupNamespace:
2476 * @reader: the xmlTextReaderPtr used
2477 * @prefix: the prefix whose namespace URI is to be resolved. To return
2478 * the default namespace, specify NULL
2480 * Resolves a namespace prefix in the scope of the current element.
2482 * Returns a string containing the namespace URI to which the prefix maps
2483 * or NULL in case of error. The string must be deallocated by the caller.
2486 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2491 if (reader
->node
== NULL
)
2494 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2497 return(xmlStrdup(ns
->href
));
2501 * xmlTextReaderMoveToAttributeNo:
2502 * @reader: the xmlTextReaderPtr used
2503 * @no: the zero-based index of the attribute relative to the containing
2506 * Moves the position of the current instance to the attribute with
2507 * the specified index relative to the containing element.
2509 * Returns 1 in case of success, -1 in case of error, 0 if not found
2512 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2519 if (reader
->node
== NULL
)
2521 /* TODO: handle the xmlDecl */
2522 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2525 reader
->curnode
= NULL
;
2527 ns
= reader
->node
->nsDef
;
2528 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2532 reader
->curnode
= (xmlNodePtr
) ns
;
2536 cur
= reader
->node
->properties
;
2544 /* TODO walk the DTD if present */
2546 reader
->curnode
= (xmlNodePtr
) cur
;
2551 * xmlTextReaderMoveToAttribute:
2552 * @reader: the xmlTextReaderPtr used
2553 * @name: the qualified name of the attribute.
2555 * Moves the position of the current instance to the attribute with
2556 * the specified qualified name.
2558 * Returns 1 in case of success, -1 in case of error, 0 if not found
2561 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2562 xmlChar
*prefix
= NULL
;
2567 if ((reader
== NULL
) || (name
== NULL
))
2569 if (reader
->node
== NULL
)
2572 /* TODO: handle the xmlDecl */
2573 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2576 localname
= xmlSplitQName2(name
, &prefix
);
2577 if (localname
== NULL
) {
2579 * Namespace default decl
2581 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2582 ns
= reader
->node
->nsDef
;
2583 while (ns
!= NULL
) {
2584 if (ns
->prefix
== NULL
) {
2585 reader
->curnode
= (xmlNodePtr
) ns
;
2593 prop
= reader
->node
->properties
;
2594 while (prop
!= NULL
) {
2597 * - same attribute names
2598 * - and the attribute carrying that namespace
2600 if ((xmlStrEqual(prop
->name
, name
)) &&
2601 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2602 reader
->curnode
= (xmlNodePtr
) prop
;
2611 * Namespace default decl
2613 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2614 ns
= reader
->node
->nsDef
;
2615 while (ns
!= NULL
) {
2616 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2617 reader
->curnode
= (xmlNodePtr
) ns
;
2624 prop
= reader
->node
->properties
;
2625 while (prop
!= NULL
) {
2628 * - same attribute names
2629 * - and the attribute carrying that namespace
2631 if ((xmlStrEqual(prop
->name
, localname
)) &&
2632 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2633 reader
->curnode
= (xmlNodePtr
) prop
;
2639 if (localname
!= NULL
)
2646 if (localname
!= NULL
)
2654 * xmlTextReaderMoveToAttributeNs:
2655 * @reader: the xmlTextReaderPtr used
2656 * @localName: the local name of the attribute.
2657 * @namespaceURI: the namespace URI of the attribute.
2659 * Moves the position of the current instance to the attribute with the
2660 * specified local name and namespace URI.
2662 * Returns 1 in case of success, -1 in case of error, 0 if not found
2665 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2666 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2670 xmlChar
*prefix
= NULL
;
2672 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2674 if (reader
->node
== NULL
)
2676 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2678 node
= reader
->node
;
2680 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2681 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2682 prefix
= BAD_CAST localName
;
2684 ns
= reader
->node
->nsDef
;
2685 while (ns
!= NULL
) {
2686 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2687 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2688 reader
->curnode
= (xmlNodePtr
) ns
;
2696 prop
= node
->properties
;
2697 while (prop
!= NULL
) {
2700 * - same attribute names
2701 * - and the attribute carrying that namespace
2703 if (xmlStrEqual(prop
->name
, localName
) &&
2704 ((prop
->ns
!= NULL
) &&
2705 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2706 reader
->curnode
= (xmlNodePtr
) prop
;
2715 * xmlTextReaderMoveToFirstAttribute:
2716 * @reader: the xmlTextReaderPtr used
2718 * Moves the position of the current instance to the first attribute
2719 * associated with the current node.
2721 * Returns 1 in case of success, -1 in case of error, 0 if not found
2724 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2727 if (reader
->node
== NULL
)
2729 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2732 if (reader
->node
->nsDef
!= NULL
) {
2733 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2736 if (reader
->node
->properties
!= NULL
) {
2737 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2744 * xmlTextReaderMoveToNextAttribute:
2745 * @reader: the xmlTextReaderPtr used
2747 * Moves the position of the current instance to the next attribute
2748 * associated with the current node.
2750 * Returns 1 in case of success, -1 in case of error, 0 if not found
2753 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2756 if (reader
->node
== NULL
)
2758 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2760 if (reader
->curnode
== NULL
)
2761 return(xmlTextReaderMoveToFirstAttribute(reader
));
2763 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2764 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2765 if (ns
->next
!= NULL
) {
2766 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2769 if (reader
->node
->properties
!= NULL
) {
2770 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2774 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2775 (reader
->curnode
->next
!= NULL
)) {
2776 reader
->curnode
= reader
->curnode
->next
;
2783 * xmlTextReaderMoveToElement:
2784 * @reader: the xmlTextReaderPtr used
2786 * Moves the position of the current instance to the node that
2787 * contains the current Attribute node.
2789 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2792 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2795 if (reader
->node
== NULL
)
2797 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2799 if (reader
->curnode
!= NULL
) {
2800 reader
->curnode
= NULL
;
2807 * xmlTextReaderReadAttributeValue:
2808 * @reader: the xmlTextReaderPtr used
2810 * Parses an attribute value into one or more Text and EntityReference nodes.
2812 * Returns 1 in case of success, 0 if the reader was not positioned on an
2813 * attribute node or all the attribute values have been read, or -1
2817 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2820 if (reader
->node
== NULL
)
2822 if (reader
->curnode
== NULL
)
2824 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2825 if (reader
->curnode
->children
== NULL
)
2827 reader
->curnode
= reader
->curnode
->children
;
2828 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2829 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2831 if (reader
->faketext
== NULL
) {
2832 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2835 if ((reader
->faketext
->content
!= NULL
) &&
2836 (reader
->faketext
->content
!=
2837 (xmlChar
*) &(reader
->faketext
->properties
)))
2838 xmlFree(reader
->faketext
->content
);
2839 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2841 reader
->curnode
= reader
->faketext
;
2843 if (reader
->curnode
->next
== NULL
)
2845 reader
->curnode
= reader
->curnode
->next
;
2851 * xmlTextReaderConstEncoding:
2852 * @reader: the xmlTextReaderPtr used
2854 * Determine the encoding of the document being read.
2856 * Returns a string containing the encoding of the document or NULL in
2857 * case of error. The string is deallocated with the reader.
2860 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2861 xmlDocPtr doc
= NULL
;
2864 if (reader
->doc
!= NULL
)
2866 else if (reader
->ctxt
!= NULL
)
2867 doc
= reader
->ctxt
->myDoc
;
2871 if (doc
->encoding
== NULL
)
2874 return(CONSTSTR(doc
->encoding
));
2878 /************************************************************************
2880 * Access API to the current node *
2882 ************************************************************************/
2884 * xmlTextReaderAttributeCount:
2885 * @reader: the xmlTextReaderPtr used
2887 * Provides the number of attributes of the current node
2889 * Returns 0 i no attributes, -1 in case of error or the attribute count
2892 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2900 if (reader
->node
== NULL
)
2903 if (reader
->curnode
!= NULL
)
2904 node
= reader
->curnode
;
2906 node
= reader
->node
;
2908 if (node
->type
!= XML_ELEMENT_NODE
)
2910 if ((reader
->state
== XML_TEXTREADER_END
) ||
2911 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2914 attr
= node
->properties
;
2915 while (attr
!= NULL
) {
2920 while (ns
!= NULL
) {
2928 * xmlTextReaderNodeType:
2929 * @reader: the xmlTextReaderPtr used
2931 * Get the node type of the current node
2933 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2935 * Returns the xmlReaderTypes of the current node or -1 in case of error
2938 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
2943 if (reader
->node
== NULL
)
2944 return(XML_READER_TYPE_NONE
);
2945 if (reader
->curnode
!= NULL
)
2946 node
= reader
->curnode
;
2948 node
= reader
->node
;
2949 switch (node
->type
) {
2950 case XML_ELEMENT_NODE
:
2951 if ((reader
->state
== XML_TEXTREADER_END
) ||
2952 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2953 return(XML_READER_TYPE_END_ELEMENT
);
2954 return(XML_READER_TYPE_ELEMENT
);
2955 case XML_NAMESPACE_DECL
:
2956 case XML_ATTRIBUTE_NODE
:
2957 return(XML_READER_TYPE_ATTRIBUTE
);
2959 if (xmlIsBlankNode(reader
->node
)) {
2960 if (xmlNodeGetSpacePreserve(reader
->node
))
2961 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
2963 return(XML_READER_TYPE_WHITESPACE
);
2965 return(XML_READER_TYPE_TEXT
);
2967 case XML_CDATA_SECTION_NODE
:
2968 return(XML_READER_TYPE_CDATA
);
2969 case XML_ENTITY_REF_NODE
:
2970 return(XML_READER_TYPE_ENTITY_REFERENCE
);
2971 case XML_ENTITY_NODE
:
2972 return(XML_READER_TYPE_ENTITY
);
2974 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
2975 case XML_COMMENT_NODE
:
2976 return(XML_READER_TYPE_COMMENT
);
2977 case XML_DOCUMENT_NODE
:
2978 case XML_HTML_DOCUMENT_NODE
:
2979 return(XML_READER_TYPE_DOCUMENT
);
2980 case XML_DOCUMENT_FRAG_NODE
:
2981 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
2982 case XML_NOTATION_NODE
:
2983 return(XML_READER_TYPE_NOTATION
);
2984 case XML_DOCUMENT_TYPE_NODE
:
2986 return(XML_READER_TYPE_DOCUMENT_TYPE
);
2988 case XML_ELEMENT_DECL
:
2989 case XML_ATTRIBUTE_DECL
:
2990 case XML_ENTITY_DECL
:
2991 case XML_XINCLUDE_START
:
2992 case XML_XINCLUDE_END
:
2993 return(XML_READER_TYPE_NONE
);
2999 * xmlTextReaderIsEmptyElement:
3000 * @reader: the xmlTextReaderPtr used
3002 * Check if the current node is empty
3004 * Returns 1 if empty, 0 if not and -1 in case of error
3007 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3008 if ((reader
== NULL
) || (reader
->node
== NULL
))
3010 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3012 if (reader
->curnode
!= NULL
)
3014 if (reader
->node
->children
!= NULL
)
3016 if (reader
->state
== XML_TEXTREADER_END
)
3018 if (reader
->doc
!= NULL
)
3020 #ifdef LIBXML_XINCLUDE_ENABLED
3021 if (reader
->in_xinclude
> 0)
3024 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3028 * xmlTextReaderLocalName:
3029 * @reader: the xmlTextReaderPtr used
3031 * The local name of the node.
3033 * Returns the local name or NULL if not available,
3034 * if non NULL it need to be freed by the caller.
3037 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3039 if ((reader
== NULL
) || (reader
->node
== NULL
))
3041 if (reader
->curnode
!= NULL
)
3042 node
= reader
->curnode
;
3044 node
= reader
->node
;
3045 if (node
->type
== XML_NAMESPACE_DECL
) {
3046 xmlNsPtr ns
= (xmlNsPtr
) node
;
3047 if (ns
->prefix
== NULL
)
3048 return(xmlStrdup(BAD_CAST
"xmlns"));
3050 return(xmlStrdup(ns
->prefix
));
3052 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3053 (node
->type
!= XML_ATTRIBUTE_NODE
))
3054 return(xmlTextReaderName(reader
));
3055 return(xmlStrdup(node
->name
));
3059 * xmlTextReaderConstLocalName:
3060 * @reader: the xmlTextReaderPtr used
3062 * The local name of the node.
3064 * Returns the local name or NULL if not available, the
3065 * string will be deallocated with the reader.
3068 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3070 if ((reader
== NULL
) || (reader
->node
== NULL
))
3072 if (reader
->curnode
!= NULL
)
3073 node
= reader
->curnode
;
3075 node
= reader
->node
;
3076 if (node
->type
== XML_NAMESPACE_DECL
) {
3077 xmlNsPtr ns
= (xmlNsPtr
) node
;
3078 if (ns
->prefix
== NULL
)
3079 return(CONSTSTR(BAD_CAST
"xmlns"));
3083 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3084 (node
->type
!= XML_ATTRIBUTE_NODE
))
3085 return(xmlTextReaderConstName(reader
));
3090 * xmlTextReaderName:
3091 * @reader: the xmlTextReaderPtr used
3093 * The qualified name of the node, equal to Prefix :LocalName.
3095 * Returns the local name or NULL if not available,
3096 * if non NULL it need to be freed by the caller.
3099 xmlTextReaderName(xmlTextReaderPtr reader
) {
3103 if ((reader
== NULL
) || (reader
->node
== NULL
))
3105 if (reader
->curnode
!= NULL
)
3106 node
= reader
->curnode
;
3108 node
= reader
->node
;
3109 switch (node
->type
) {
3110 case XML_ELEMENT_NODE
:
3111 case XML_ATTRIBUTE_NODE
:
3112 if ((node
->ns
== NULL
) ||
3113 (node
->ns
->prefix
== NULL
))
3114 return(xmlStrdup(node
->name
));
3116 ret
= xmlStrdup(node
->ns
->prefix
);
3117 ret
= xmlStrcat(ret
, BAD_CAST
":");
3118 ret
= xmlStrcat(ret
, node
->name
);
3121 return(xmlStrdup(BAD_CAST
"#text"));
3122 case XML_CDATA_SECTION_NODE
:
3123 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3124 case XML_ENTITY_NODE
:
3125 case XML_ENTITY_REF_NODE
:
3126 return(xmlStrdup(node
->name
));
3128 return(xmlStrdup(node
->name
));
3129 case XML_COMMENT_NODE
:
3130 return(xmlStrdup(BAD_CAST
"#comment"));
3131 case XML_DOCUMENT_NODE
:
3132 case XML_HTML_DOCUMENT_NODE
:
3133 return(xmlStrdup(BAD_CAST
"#document"));
3134 case XML_DOCUMENT_FRAG_NODE
:
3135 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3136 case XML_NOTATION_NODE
:
3137 return(xmlStrdup(node
->name
));
3138 case XML_DOCUMENT_TYPE_NODE
:
3140 return(xmlStrdup(node
->name
));
3141 case XML_NAMESPACE_DECL
: {
3142 xmlNsPtr ns
= (xmlNsPtr
) node
;
3144 ret
= xmlStrdup(BAD_CAST
"xmlns");
3145 if (ns
->prefix
== NULL
)
3147 ret
= xmlStrcat(ret
, BAD_CAST
":");
3148 ret
= xmlStrcat(ret
, ns
->prefix
);
3152 case XML_ELEMENT_DECL
:
3153 case XML_ATTRIBUTE_DECL
:
3154 case XML_ENTITY_DECL
:
3155 case XML_XINCLUDE_START
:
3156 case XML_XINCLUDE_END
:
3163 * xmlTextReaderConstName:
3164 * @reader: the xmlTextReaderPtr used
3166 * The qualified name of the node, equal to Prefix :LocalName.
3168 * Returns the local name or NULL if not available, the string is
3169 * deallocated with the reader.
3172 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3175 if ((reader
== NULL
) || (reader
->node
== NULL
))
3177 if (reader
->curnode
!= NULL
)
3178 node
= reader
->curnode
;
3180 node
= reader
->node
;
3181 switch (node
->type
) {
3182 case XML_ELEMENT_NODE
:
3183 case XML_ATTRIBUTE_NODE
:
3184 if ((node
->ns
== NULL
) ||
3185 (node
->ns
->prefix
== NULL
))
3187 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3189 return(CONSTSTR(BAD_CAST
"#text"));
3190 case XML_CDATA_SECTION_NODE
:
3191 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3192 case XML_ENTITY_NODE
:
3193 case XML_ENTITY_REF_NODE
:
3194 return(CONSTSTR(node
->name
));
3196 return(CONSTSTR(node
->name
));
3197 case XML_COMMENT_NODE
:
3198 return(CONSTSTR(BAD_CAST
"#comment"));
3199 case XML_DOCUMENT_NODE
:
3200 case XML_HTML_DOCUMENT_NODE
:
3201 return(CONSTSTR(BAD_CAST
"#document"));
3202 case XML_DOCUMENT_FRAG_NODE
:
3203 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3204 case XML_NOTATION_NODE
:
3205 return(CONSTSTR(node
->name
));
3206 case XML_DOCUMENT_TYPE_NODE
:
3208 return(CONSTSTR(node
->name
));
3209 case XML_NAMESPACE_DECL
: {
3210 xmlNsPtr ns
= (xmlNsPtr
) node
;
3212 if (ns
->prefix
== NULL
)
3213 return(CONSTSTR(BAD_CAST
"xmlns"));
3214 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3217 case XML_ELEMENT_DECL
:
3218 case XML_ATTRIBUTE_DECL
:
3219 case XML_ENTITY_DECL
:
3220 case XML_XINCLUDE_START
:
3221 case XML_XINCLUDE_END
:
3228 * xmlTextReaderPrefix:
3229 * @reader: the xmlTextReaderPtr used
3231 * A shorthand reference to the namespace associated with the node.
3233 * Returns the prefix or NULL if not available,
3234 * if non NULL it need to be freed by the caller.
3237 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3239 if ((reader
== NULL
) || (reader
->node
== NULL
))
3241 if (reader
->curnode
!= NULL
)
3242 node
= reader
->curnode
;
3244 node
= reader
->node
;
3245 if (node
->type
== XML_NAMESPACE_DECL
) {
3246 xmlNsPtr ns
= (xmlNsPtr
) node
;
3247 if (ns
->prefix
== NULL
)
3249 return(xmlStrdup(BAD_CAST
"xmlns"));
3251 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3252 (node
->type
!= XML_ATTRIBUTE_NODE
))
3254 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3255 return(xmlStrdup(node
->ns
->prefix
));
3260 * xmlTextReaderConstPrefix:
3261 * @reader: the xmlTextReaderPtr used
3263 * A shorthand reference to the namespace associated with the node.
3265 * Returns the prefix or NULL if not available, the string is deallocated
3269 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3271 if ((reader
== NULL
) || (reader
->node
== NULL
))
3273 if (reader
->curnode
!= NULL
)
3274 node
= reader
->curnode
;
3276 node
= reader
->node
;
3277 if (node
->type
== XML_NAMESPACE_DECL
) {
3278 xmlNsPtr ns
= (xmlNsPtr
) node
;
3279 if (ns
->prefix
== NULL
)
3281 return(CONSTSTR(BAD_CAST
"xmlns"));
3283 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3284 (node
->type
!= XML_ATTRIBUTE_NODE
))
3286 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3287 return(CONSTSTR(node
->ns
->prefix
));
3292 * xmlTextReaderNamespaceUri:
3293 * @reader: the xmlTextReaderPtr used
3295 * The URI defining the namespace associated with the node.
3297 * Returns the namespace URI or NULL if not available,
3298 * if non NULL it need to be freed by the caller.
3301 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3303 if ((reader
== NULL
) || (reader
->node
== NULL
))
3305 if (reader
->curnode
!= NULL
)
3306 node
= reader
->curnode
;
3308 node
= reader
->node
;
3309 if (node
->type
== XML_NAMESPACE_DECL
)
3310 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3311 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3312 (node
->type
!= XML_ATTRIBUTE_NODE
))
3314 if (node
->ns
!= NULL
)
3315 return(xmlStrdup(node
->ns
->href
));
3320 * xmlTextReaderConstNamespaceUri:
3321 * @reader: the xmlTextReaderPtr used
3323 * The URI defining the namespace associated with the node.
3325 * Returns the namespace URI or NULL if not available, the string
3326 * will be deallocated with the reader
3329 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3331 if ((reader
== NULL
) || (reader
->node
== NULL
))
3333 if (reader
->curnode
!= NULL
)
3334 node
= reader
->curnode
;
3336 node
= reader
->node
;
3337 if (node
->type
== XML_NAMESPACE_DECL
)
3338 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3339 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3340 (node
->type
!= XML_ATTRIBUTE_NODE
))
3342 if (node
->ns
!= NULL
)
3343 return(CONSTSTR(node
->ns
->href
));
3348 * xmlTextReaderBaseUri:
3349 * @reader: the xmlTextReaderPtr used
3351 * The base URI of the node.
3353 * Returns the base URI or NULL if not available,
3354 * if non NULL it need to be freed by the caller.
3357 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3358 if ((reader
== NULL
) || (reader
->node
== NULL
))
3360 return(xmlNodeGetBase(NULL
, reader
->node
));
3364 * xmlTextReaderConstBaseUri:
3365 * @reader: the xmlTextReaderPtr used
3367 * The base URI of the node.
3369 * Returns the base URI or NULL if not available, the string
3370 * will be deallocated with the reader
3373 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3377 if ((reader
== NULL
) || (reader
->node
== NULL
))
3379 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3382 ret
= CONSTSTR(tmp
);
3388 * xmlTextReaderDepth:
3389 * @reader: the xmlTextReaderPtr used
3391 * The depth of the node in the tree.
3393 * Returns the depth or -1 in case of error
3396 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3399 if (reader
->node
== NULL
)
3402 if (reader
->curnode
!= NULL
) {
3403 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3404 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3405 return(reader
->depth
+ 1);
3406 return(reader
->depth
+ 2);
3408 return(reader
->depth
);
3412 * xmlTextReaderHasAttributes:
3413 * @reader: the xmlTextReaderPtr used
3415 * Whether the node has attributes.
3417 * Returns 1 if true, 0 if false, and -1 in case or error
3420 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3424 if (reader
->node
== NULL
)
3426 if (reader
->curnode
!= NULL
)
3427 node
= reader
->curnode
;
3429 node
= reader
->node
;
3431 if ((node
->type
== XML_ELEMENT_NODE
) &&
3432 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3434 /* TODO: handle the xmlDecl */
3439 * xmlTextReaderHasValue:
3440 * @reader: the xmlTextReaderPtr used
3442 * Whether the node can have a text value.
3444 * Returns 1 if true, 0 if false, and -1 in case or error
3447 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3451 if (reader
->node
== NULL
)
3453 if (reader
->curnode
!= NULL
)
3454 node
= reader
->curnode
;
3456 node
= reader
->node
;
3458 switch (node
->type
) {
3459 case XML_ATTRIBUTE_NODE
:
3461 case XML_CDATA_SECTION_NODE
:
3463 case XML_COMMENT_NODE
:
3464 case XML_NAMESPACE_DECL
:
3473 * xmlTextReaderValue:
3474 * @reader: the xmlTextReaderPtr used
3476 * Provides the text value of the node if present
3478 * Returns the string or NULL if not available. The result must be deallocated
3482 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3486 if (reader
->node
== NULL
)
3488 if (reader
->curnode
!= NULL
)
3489 node
= reader
->curnode
;
3491 node
= reader
->node
;
3493 switch (node
->type
) {
3494 case XML_NAMESPACE_DECL
:
3495 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3496 case XML_ATTRIBUTE_NODE
:{
3497 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3499 if (attr
->parent
!= NULL
)
3500 return (xmlNodeListGetString
3501 (attr
->parent
->doc
, attr
->children
, 1));
3503 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3507 case XML_CDATA_SECTION_NODE
:
3509 case XML_COMMENT_NODE
:
3510 if (node
->content
!= NULL
)
3511 return (xmlStrdup(node
->content
));
3519 * xmlTextReaderConstValue:
3520 * @reader: the xmlTextReaderPtr used
3522 * Provides the text value of the node if present
3524 * Returns the string or NULL if not available. The result will be
3525 * deallocated on the next Read() operation.
3528 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3532 if (reader
->node
== NULL
)
3534 if (reader
->curnode
!= NULL
)
3535 node
= reader
->curnode
;
3537 node
= reader
->node
;
3539 switch (node
->type
) {
3540 case XML_NAMESPACE_DECL
:
3541 return(((xmlNsPtr
) node
)->href
);
3542 case XML_ATTRIBUTE_NODE
:{
3543 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3546 if ((attr
->children
!= NULL
) &&
3547 (attr
->children
->type
== XML_TEXT_NODE
) &&
3548 (attr
->children
->next
== NULL
))
3549 return(attr
->children
->content
);
3551 if (reader
->buffer
== NULL
) {
3552 reader
->buffer
= xmlBufCreateSize(100);
3553 if (reader
->buffer
== NULL
) {
3554 xmlGenericError(xmlGenericErrorContext
,
3555 "xmlTextReaderSetup : malloc failed\n");
3558 xmlBufSetAllocationScheme(reader
->buffer
,
3559 XML_BUFFER_ALLOC_DOUBLEIT
);
3561 xmlBufEmpty(reader
->buffer
);
3562 xmlBufGetNodeContent(reader
->buffer
, node
);
3563 ret
= xmlBufContent(reader
->buffer
);
3565 /* error on the buffer best to reallocate */
3566 xmlBufFree(reader
->buffer
);
3567 reader
->buffer
= xmlBufCreateSize(100);
3568 xmlBufSetAllocationScheme(reader
->buffer
,
3569 XML_BUFFER_ALLOC_DOUBLEIT
);
3577 case XML_CDATA_SECTION_NODE
:
3579 case XML_COMMENT_NODE
:
3580 return(node
->content
);
3588 * xmlTextReaderIsDefault:
3589 * @reader: the xmlTextReaderPtr used
3591 * Whether an Attribute node was generated from the default value
3592 * defined in the DTD or schema.
3594 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3597 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3604 * xmlTextReaderQuoteChar:
3605 * @reader: the xmlTextReaderPtr used
3607 * The quotation mark character used to enclose the value of an attribute.
3609 * Returns " or ' and -1 in case of error
3612 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3615 /* TODO maybe lookup the attribute value for " first */
3620 * xmlTextReaderXmlLang:
3621 * @reader: the xmlTextReaderPtr used
3623 * The xml:lang scope within which the node resides.
3625 * Returns the xml:lang value or NULL if none exists.,
3626 * if non NULL it need to be freed by the caller.
3629 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3632 if (reader
->node
== NULL
)
3634 return(xmlNodeGetLang(reader
->node
));
3638 * xmlTextReaderConstXmlLang:
3639 * @reader: the xmlTextReaderPtr used
3641 * The xml:lang scope within which the node resides.
3643 * Returns the xml:lang value or NULL if none exists.
3646 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3652 if (reader
->node
== NULL
)
3654 tmp
= xmlNodeGetLang(reader
->node
);
3657 ret
= CONSTSTR(tmp
);
3663 * xmlTextReaderConstString:
3664 * @reader: the xmlTextReaderPtr used
3665 * @str: the string to intern.
3667 * Get an interned string from the reader, allows for example to
3668 * speedup string name comparisons
3670 * Returns an interned copy of the string or NULL in case of error. The
3671 * string will be deallocated with the reader.
3674 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3677 return(CONSTSTR(str
));
3681 * xmlTextReaderNormalization:
3682 * @reader: the xmlTextReaderPtr used
3684 * The value indicating whether to normalize white space and attribute values.
3685 * Since attribute value and end of line normalizations are a MUST in the XML
3686 * specification only the value true is accepted. The broken behaviour of
3687 * accepting out of range character entities like � is of course not
3690 * Returns 1 or -1 in case of error.
3693 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3699 /************************************************************************
3701 * Extensions to the base APIs *
3703 ************************************************************************/
3706 * xmlTextReaderSetParserProp:
3707 * @reader: the xmlTextReaderPtr used
3708 * @prop: the xmlParserProperties to set
3709 * @value: usually 0 or 1 to (de)activate it
3711 * Change the parser processing behaviour by changing some of its internal
3712 * properties. Note that some properties can only be changed before any
3713 * read has been done.
3715 * Returns 0 if the call was successful, or -1 in case of error
3718 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3719 xmlParserProperties p
= (xmlParserProperties
) prop
;
3720 xmlParserCtxtPtr ctxt
;
3722 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3724 ctxt
= reader
->ctxt
;
3727 case XML_PARSER_LOADDTD
:
3729 if (ctxt
->loadsubset
== 0) {
3730 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3732 ctxt
->loadsubset
= XML_DETECT_IDS
;
3735 ctxt
->loadsubset
= 0;
3738 case XML_PARSER_DEFAULTATTRS
:
3740 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3742 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3743 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3746 case XML_PARSER_VALIDATE
:
3748 ctxt
->options
|= XML_PARSE_DTDVALID
;
3750 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3752 ctxt
->options
&= ~XML_PARSE_DTDVALID
;
3756 case XML_PARSER_SUBST_ENTITIES
:
3758 ctxt
->options
|= XML_PARSE_NOENT
;
3759 ctxt
->replaceEntities
= 1;
3761 ctxt
->options
&= ~XML_PARSE_NOENT
;
3762 ctxt
->replaceEntities
= 0;
3770 * xmlTextReaderGetParserProp:
3771 * @reader: the xmlTextReaderPtr used
3772 * @prop: the xmlParserProperties to get
3774 * Read the parser internal property.
3776 * Returns the value, usually 0 or 1, or -1 in case of error.
3779 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3780 xmlParserProperties p
= (xmlParserProperties
) prop
;
3781 xmlParserCtxtPtr ctxt
;
3783 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3785 ctxt
= reader
->ctxt
;
3788 case XML_PARSER_LOADDTD
:
3789 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3792 case XML_PARSER_DEFAULTATTRS
:
3793 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3796 case XML_PARSER_VALIDATE
:
3797 return(reader
->validate
);
3798 case XML_PARSER_SUBST_ENTITIES
:
3799 return(ctxt
->replaceEntities
);
3806 * xmlTextReaderGetParserLineNumber:
3807 * @reader: the user data (XML reader context)
3809 * Provide the line number of the current parsing point.
3811 * Returns an int or 0 if not available
3814 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3816 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3817 (reader
->ctxt
->input
== NULL
)) {
3820 return (reader
->ctxt
->input
->line
);
3824 * xmlTextReaderGetParserColumnNumber:
3825 * @reader: the user data (XML reader context)
3827 * Provide the column number of the current parsing point.
3829 * Returns an int or 0 if not available
3832 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3834 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3835 (reader
->ctxt
->input
== NULL
)) {
3838 return (reader
->ctxt
->input
->col
);
3842 * xmlTextReaderCurrentNode:
3843 * @reader: the xmlTextReaderPtr used
3845 * Hacking interface allowing to get the xmlNodePtr corresponding to the
3846 * current node being accessed by the xmlTextReader. This is dangerous
3847 * because the underlying node may be destroyed on the next Reads.
3849 * Returns the xmlNodePtr or NULL in case of error.
3852 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3856 if (reader
->curnode
!= NULL
)
3857 return(reader
->curnode
);
3858 return(reader
->node
);
3862 * xmlTextReaderPreserve:
3863 * @reader: the xmlTextReaderPtr used
3865 * This tells the XML Reader to preserve the current node.
3866 * The caller must also use xmlTextReaderCurrentDoc() to
3867 * keep an handle on the resulting document once parsing has finished
3869 * Returns the xmlNodePtr or NULL in case of error.
3872 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3873 xmlNodePtr cur
, parent
;
3878 if (reader
->curnode
!= NULL
)
3879 cur
= reader
->curnode
;
3885 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3886 cur
->extra
|= NODE_IS_PRESERVED
;
3887 cur
->extra
|= NODE_IS_SPRESERVED
;
3889 reader
->preserves
++;
3891 parent
= cur
->parent
;;
3892 while (parent
!= NULL
) {
3893 if (parent
->type
== XML_ELEMENT_NODE
)
3894 parent
->extra
|= NODE_IS_PRESERVED
;
3895 parent
= parent
->parent
;
3900 #ifdef LIBXML_PATTERN_ENABLED
3902 * xmlTextReaderPreservePattern:
3903 * @reader: the xmlTextReaderPtr used
3904 * @pattern: an XPath subset pattern
3905 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3907 * This tells the XML Reader to preserve all nodes matched by the
3908 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3909 * keep an handle on the resulting document once parsing has finished
3911 * Returns a non-negative number in case of success and -1 in case of error
3914 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3915 const xmlChar
**namespaces
)
3919 if ((reader
== NULL
) || (pattern
== NULL
))
3922 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
3926 if (reader
->patternMax
<= 0) {
3927 reader
->patternMax
= 4;
3928 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
3929 sizeof(reader
->patternTab
[0]));
3930 if (reader
->patternTab
== NULL
) {
3931 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
3935 if (reader
->patternNr
>= reader
->patternMax
) {
3937 reader
->patternMax
*= 2;
3938 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
3939 reader
->patternMax
*
3940 sizeof(reader
->patternTab
[0]));
3942 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
3943 reader
->patternMax
/= 2;
3946 reader
->patternTab
= tmp
;
3948 reader
->patternTab
[reader
->patternNr
] = comp
;
3949 return(reader
->patternNr
++);
3954 * xmlTextReaderCurrentDoc:
3955 * @reader: the xmlTextReaderPtr used
3957 * Hacking interface allowing to get the xmlDocPtr corresponding to the
3958 * current document being accessed by the xmlTextReader.
3959 * NOTE: as a result of this call, the reader will not destroy the
3960 * associated XML document and calling xmlFreeDoc() on the result
3961 * is needed once the reader parsing has finished.
3963 * Returns the xmlDocPtr or NULL in case of error.
3966 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
3969 if (reader
->doc
!= NULL
)
3970 return(reader
->doc
);
3971 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
3974 reader
->preserve
= 1;
3975 return(reader
->ctxt
->myDoc
);
3978 #ifdef LIBXML_SCHEMAS_ENABLED
3979 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
) LIBXML_ATTR_FORMAT(1,0);
3981 static void XMLCDECL
3982 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3984 static void XMLCDECL
3985 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3987 static void XMLCDECL
3988 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3990 static void XMLCDECL
3991 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
3993 static void XMLCDECL
3994 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
3996 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4003 str
= xmlTextReaderBuildMessage(msg
, ap
);
4004 if (!reader
->errorFunc
) {
4005 xmlTextReaderValidityError(ctx
, "%s", str
);
4007 reader
->errorFunc(reader
->errorFuncArg
, str
,
4008 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4009 NULL
/* locator */ );
4016 static void XMLCDECL
4017 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4019 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4026 str
= xmlTextReaderBuildMessage(msg
, ap
);
4027 if (!reader
->errorFunc
) {
4028 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4030 reader
->errorFunc(reader
->errorFuncArg
, str
,
4031 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4032 NULL
/* locator */ );
4040 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4043 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4045 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4047 if (reader
->sErrorFunc
) {
4048 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4050 xmlTextReaderStructuredError(reader
, error
);
4054 * xmlTextReaderRelaxNGSetSchema:
4055 * @reader: the xmlTextReaderPtr used
4056 * @schema: a precompiled RelaxNG schema
4058 * Use RelaxNG to validate the document as it is processed.
4059 * Activation is only possible before the first Read().
4060 * if @schema is NULL, then RelaxNG validation is deactivated.
4061 @ The @schema should not be freed until the reader is deallocated
4062 * or its use has been deactivated.
4064 * Returns 0 in case the RelaxNG validation could be (de)activated and
4065 * -1 in case of error.
4068 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4071 if (schema
== NULL
) {
4072 if (reader
->rngSchemas
!= NULL
) {
4073 xmlRelaxNGFree(reader
->rngSchemas
);
4074 reader
->rngSchemas
= NULL
;
4076 if (reader
->rngValidCtxt
!= NULL
) {
4077 if (! reader
->rngPreserveCtxt
)
4078 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4079 reader
->rngValidCtxt
= NULL
;
4081 reader
->rngPreserveCtxt
= 0;
4084 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4086 if (reader
->rngSchemas
!= NULL
) {
4087 xmlRelaxNGFree(reader
->rngSchemas
);
4088 reader
->rngSchemas
= NULL
;
4090 if (reader
->rngValidCtxt
!= NULL
) {
4091 if (! reader
->rngPreserveCtxt
)
4092 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4093 reader
->rngValidCtxt
= NULL
;
4095 reader
->rngPreserveCtxt
= 0;
4096 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4097 if (reader
->rngValidCtxt
== NULL
)
4099 if (reader
->errorFunc
!= NULL
) {
4100 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4101 xmlTextReaderValidityErrorRelay
,
4102 xmlTextReaderValidityWarningRelay
,
4105 if (reader
->sErrorFunc
!= NULL
) {
4106 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4107 xmlTextReaderValidityStructuredRelay
,
4110 reader
->rngValidErrors
= 0;
4111 reader
->rngFullNode
= NULL
;
4112 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4117 * xmlTextReaderLocator:
4118 * @ctx: the xmlTextReaderPtr used
4119 * @file: returned file information
4120 * @line: returned line information
4122 * Internal locator function for the readers
4124 * Returns 0 in case the Schema validation could be (de)activated and
4125 * -1 in case of error.
4128 xmlTextReaderLocator(void *ctx
, const char **file
, unsigned long *line
) {
4129 xmlTextReaderPtr reader
;
4131 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
4139 reader
= (xmlTextReaderPtr
) ctx
;
4140 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->input
!= NULL
)) {
4142 *file
= reader
->ctxt
->input
->filename
;
4144 *line
= reader
->ctxt
->input
->line
;
4147 if (reader
->node
!= NULL
) {
4152 res
= xmlGetLineNo(reader
->node
);
4154 *line
= (unsigned long) res
;
4159 xmlDocPtr doc
= reader
->node
->doc
;
4160 if ((doc
!= NULL
) && (doc
->URL
!= NULL
))
4161 *file
= (const char *) doc
->URL
;
4171 * xmlTextReaderSetSchema:
4172 * @reader: the xmlTextReaderPtr used
4173 * @schema: a precompiled Schema schema
4175 * Use XSD Schema to validate the document as it is processed.
4176 * Activation is only possible before the first Read().
4177 * if @schema is NULL, then Schema validation is deactivated.
4178 * The @schema should not be freed until the reader is deallocated
4179 * or its use has been deactivated.
4181 * Returns 0 in case the Schema validation could be (de)activated and
4182 * -1 in case of error.
4185 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4188 if (schema
== NULL
) {
4189 if (reader
->xsdPlug
!= NULL
) {
4190 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4191 reader
->xsdPlug
= NULL
;
4193 if (reader
->xsdValidCtxt
!= NULL
) {
4194 if (! reader
->xsdPreserveCtxt
)
4195 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4196 reader
->xsdValidCtxt
= NULL
;
4198 reader
->xsdPreserveCtxt
= 0;
4199 if (reader
->xsdSchemas
!= NULL
) {
4200 xmlSchemaFree(reader
->xsdSchemas
);
4201 reader
->xsdSchemas
= NULL
;
4205 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4207 if (reader
->xsdPlug
!= NULL
) {
4208 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4209 reader
->xsdPlug
= NULL
;
4211 if (reader
->xsdValidCtxt
!= NULL
) {
4212 if (! reader
->xsdPreserveCtxt
)
4213 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4214 reader
->xsdValidCtxt
= NULL
;
4216 reader
->xsdPreserveCtxt
= 0;
4217 if (reader
->xsdSchemas
!= NULL
) {
4218 xmlSchemaFree(reader
->xsdSchemas
);
4219 reader
->xsdSchemas
= NULL
;
4221 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4222 if (reader
->xsdValidCtxt
== NULL
) {
4223 xmlSchemaFree(reader
->xsdSchemas
);
4224 reader
->xsdSchemas
= NULL
;
4227 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4228 &(reader
->ctxt
->sax
),
4229 &(reader
->ctxt
->userData
));
4230 if (reader
->xsdPlug
== NULL
) {
4231 xmlSchemaFree(reader
->xsdSchemas
);
4232 reader
->xsdSchemas
= NULL
;
4233 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4234 reader
->xsdValidCtxt
= NULL
;
4237 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4238 xmlTextReaderLocator
,
4241 if (reader
->errorFunc
!= NULL
) {
4242 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4243 xmlTextReaderValidityErrorRelay
,
4244 xmlTextReaderValidityWarningRelay
,
4247 if (reader
->sErrorFunc
!= NULL
) {
4248 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4249 xmlTextReaderValidityStructuredRelay
,
4252 reader
->xsdValidErrors
= 0;
4253 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4258 * xmlTextReaderRelaxNGValidateInternal:
4259 * @reader: the xmlTextReaderPtr used
4260 * @rng: the path to a RelaxNG schema or NULL
4261 * @ctxt: the RelaxNG schema validation context or NULL
4262 * @options: options (not yet used)
4264 * Use RelaxNG to validate the document as it is processed.
4265 * Activation is only possible before the first Read().
4266 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
4268 * Returns 0 in case the RelaxNG validation could be (de)activated and
4269 * -1 in case of error.
4272 xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader
,
4274 xmlRelaxNGValidCtxtPtr ctxt
,
4275 int options ATTRIBUTE_UNUSED
)
4280 if ((rng
!= NULL
) && (ctxt
!= NULL
))
4283 if (((rng
!= NULL
) || (ctxt
!= NULL
)) &&
4284 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4285 (reader
->ctxt
== NULL
)))
4288 /* Cleanup previous validation stuff. */
4289 if (reader
->rngValidCtxt
!= NULL
) {
4290 if ( !reader
->rngPreserveCtxt
)
4291 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4292 reader
->rngValidCtxt
= NULL
;
4294 reader
->rngPreserveCtxt
= 0;
4295 if (reader
->rngSchemas
!= NULL
) {
4296 xmlRelaxNGFree(reader
->rngSchemas
);
4297 reader
->rngSchemas
= NULL
;
4300 if ((rng
== NULL
) && (ctxt
== NULL
)) {
4301 /* We just want to deactivate the validation, so get out. */
4307 xmlRelaxNGParserCtxtPtr pctxt
;
4308 /* Parse the schema and create validation environment. */
4310 pctxt
= xmlRelaxNGNewParserCtxt(rng
);
4311 if (reader
->errorFunc
!= NULL
) {
4312 xmlRelaxNGSetParserErrors(pctxt
,
4313 xmlTextReaderValidityErrorRelay
,
4314 xmlTextReaderValidityWarningRelay
,
4317 if (reader
->sErrorFunc
!= NULL
) {
4318 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4319 xmlTextReaderValidityStructuredRelay
,
4322 reader
->rngSchemas
= xmlRelaxNGParse(pctxt
);
4323 xmlRelaxNGFreeParserCtxt(pctxt
);
4324 if (reader
->rngSchemas
== NULL
)
4326 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4327 if (reader
->rngValidCtxt
== NULL
) {
4328 xmlRelaxNGFree(reader
->rngSchemas
);
4329 reader
->rngSchemas
= NULL
;
4333 /* Use the given validation context. */
4334 reader
->rngValidCtxt
= ctxt
;
4335 reader
->rngPreserveCtxt
= 1;
4338 * Redirect the validation context's error channels to use
4339 * the reader channels.
4340 * TODO: In case the user provides the validation context we
4341 * could make this redirection optional.
4343 if (reader
->errorFunc
!= NULL
) {
4344 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4345 xmlTextReaderValidityErrorRelay
,
4346 xmlTextReaderValidityWarningRelay
,
4349 if (reader
->sErrorFunc
!= NULL
) {
4350 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4351 xmlTextReaderValidityStructuredRelay
,
4354 reader
->rngValidErrors
= 0;
4355 reader
->rngFullNode
= NULL
;
4356 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4361 * xmlTextReaderSchemaValidateInternal:
4362 * @reader: the xmlTextReaderPtr used
4363 * @xsd: the path to a W3C XSD schema or NULL
4364 * @ctxt: the XML Schema validation context or NULL
4365 * @options: options (not used yet)
4367 * Validate the document as it is processed using XML Schema.
4368 * Activation is only possible before the first Read().
4369 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4371 * Returns 0 in case the schemas validation could be (de)activated and
4372 * -1 in case of error.
4375 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4377 xmlSchemaValidCtxtPtr ctxt
,
4378 int options ATTRIBUTE_UNUSED
)
4383 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4386 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4387 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4388 (reader
->ctxt
== NULL
)))
4391 /* Cleanup previous validation stuff. */
4392 if (reader
->xsdPlug
!= NULL
) {
4393 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4394 reader
->xsdPlug
= NULL
;
4396 if (reader
->xsdValidCtxt
!= NULL
) {
4397 if (! reader
->xsdPreserveCtxt
)
4398 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4399 reader
->xsdValidCtxt
= NULL
;
4401 reader
->xsdPreserveCtxt
= 0;
4402 if (reader
->xsdSchemas
!= NULL
) {
4403 xmlSchemaFree(reader
->xsdSchemas
);
4404 reader
->xsdSchemas
= NULL
;
4407 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4408 /* We just want to deactivate the validation, so get out. */
4413 xmlSchemaParserCtxtPtr pctxt
;
4414 /* Parse the schema and create validation environment. */
4415 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4416 if (reader
->errorFunc
!= NULL
) {
4417 xmlSchemaSetParserErrors(pctxt
,
4418 xmlTextReaderValidityErrorRelay
,
4419 xmlTextReaderValidityWarningRelay
,
4422 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4423 xmlSchemaFreeParserCtxt(pctxt
);
4424 if (reader
->xsdSchemas
== NULL
)
4426 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4427 if (reader
->xsdValidCtxt
== NULL
) {
4428 xmlSchemaFree(reader
->xsdSchemas
);
4429 reader
->xsdSchemas
= NULL
;
4432 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4433 &(reader
->ctxt
->sax
),
4434 &(reader
->ctxt
->userData
));
4435 if (reader
->xsdPlug
== NULL
) {
4436 xmlSchemaFree(reader
->xsdSchemas
);
4437 reader
->xsdSchemas
= NULL
;
4438 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4439 reader
->xsdValidCtxt
= NULL
;
4443 /* Use the given validation context. */
4444 reader
->xsdValidCtxt
= ctxt
;
4445 reader
->xsdPreserveCtxt
= 1;
4446 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4447 &(reader
->ctxt
->sax
),
4448 &(reader
->ctxt
->userData
));
4449 if (reader
->xsdPlug
== NULL
) {
4450 reader
->xsdValidCtxt
= NULL
;
4451 reader
->xsdPreserveCtxt
= 0;
4455 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4456 xmlTextReaderLocator
,
4459 * Redirect the validation context's error channels to use
4460 * the reader channels.
4461 * TODO: In case the user provides the validation context we
4462 * could make this redirection optional.
4464 if (reader
->errorFunc
!= NULL
) {
4465 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4466 xmlTextReaderValidityErrorRelay
,
4467 xmlTextReaderValidityWarningRelay
,
4470 if (reader
->sErrorFunc
!= NULL
) {
4471 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4472 xmlTextReaderValidityStructuredRelay
,
4475 reader
->xsdValidErrors
= 0;
4476 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4481 * xmlTextReaderSchemaValidateCtxt:
4482 * @reader: the xmlTextReaderPtr used
4483 * @ctxt: the XML Schema validation context or NULL
4484 * @options: options (not used yet)
4486 * Use W3C XSD schema context to validate the document as it is processed.
4487 * Activation is only possible before the first Read().
4488 * If @ctxt is NULL, then XML Schema validation is deactivated.
4490 * Returns 0 in case the schemas validation could be (de)activated and
4491 * -1 in case of error.
4494 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4495 xmlSchemaValidCtxtPtr ctxt
,
4498 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4502 * xmlTextReaderSchemaValidate:
4503 * @reader: the xmlTextReaderPtr used
4504 * @xsd: the path to a W3C XSD schema or NULL
4506 * Use W3C XSD schema to validate the document as it is processed.
4507 * Activation is only possible before the first Read().
4508 * If @xsd is NULL, then XML Schema validation is deactivated.
4510 * Returns 0 in case the schemas validation could be (de)activated and
4511 * -1 in case of error.
4514 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4516 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4520 * xmlTextReaderRelaxNGValidateCtxt:
4521 * @reader: the xmlTextReaderPtr used
4522 * @ctxt: the RelaxNG schema validation context or NULL
4523 * @options: options (not used yet)
4525 * Use RelaxNG schema context to validate the document as it is processed.
4526 * Activation is only possible before the first Read().
4527 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
4529 * Returns 0 in case the schemas validation could be (de)activated and
4530 * -1 in case of error.
4533 xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader
,
4534 xmlRelaxNGValidCtxtPtr ctxt
,
4537 return(xmlTextReaderRelaxNGValidateInternal(reader
, NULL
, ctxt
, options
));
4541 * xmlTextReaderRelaxNGValidate:
4542 * @reader: the xmlTextReaderPtr used
4543 * @rng: the path to a RelaxNG schema or NULL
4545 * Use RelaxNG schema to validate the document as it is processed.
4546 * Activation is only possible before the first Read().
4547 * If @rng is NULL, then RelaxNG schema validation is deactivated.
4549 * Returns 0 in case the schemas validation could be (de)activated and
4550 * -1 in case of error.
4553 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
)
4555 return(xmlTextReaderRelaxNGValidateInternal(reader
, rng
, NULL
, 0));
4561 * xmlTextReaderIsNamespaceDecl:
4562 * @reader: the xmlTextReaderPtr used
4564 * Determine whether the current node is a namespace declaration
4565 * rather than a regular attribute.
4567 * Returns 1 if the current node is a namespace declaration, 0 if it
4568 * is a regular attribute or other type of node, or -1 in case of
4572 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4576 if (reader
->node
== NULL
)
4578 if (reader
->curnode
!= NULL
)
4579 node
= reader
->curnode
;
4581 node
= reader
->node
;
4583 if (XML_NAMESPACE_DECL
== node
->type
)
4590 * xmlTextReaderConstXmlVersion:
4591 * @reader: the xmlTextReaderPtr used
4593 * Determine the XML version of the document being read.
4595 * Returns a string containing the XML version of the document or NULL
4596 * in case of error. The string is deallocated with the reader.
4599 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4600 xmlDocPtr doc
= NULL
;
4603 if (reader
->doc
!= NULL
)
4605 else if (reader
->ctxt
!= NULL
)
4606 doc
= reader
->ctxt
->myDoc
;
4610 if (doc
->version
== NULL
)
4613 return(CONSTSTR(doc
->version
));
4617 * xmlTextReaderStandalone:
4618 * @reader: the xmlTextReaderPtr used
4620 * Determine the standalone status of the document being read.
4622 * Returns 1 if the document was declared to be standalone, 0 if it
4623 * was declared to be not standalone, or -1 if the document did not
4624 * specify its standalone status or in case of error.
4627 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4628 xmlDocPtr doc
= NULL
;
4631 if (reader
->doc
!= NULL
)
4633 else if (reader
->ctxt
!= NULL
)
4634 doc
= reader
->ctxt
->myDoc
;
4638 return(doc
->standalone
);
4641 /************************************************************************
4643 * Error Handling Extensions *
4645 ************************************************************************/
4647 /* helper to build a xmlMalloc'ed string from a format and va_list */
4649 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4658 chars
= vsnprintf(str
, size
, msg
, aq
);
4661 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4666 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4668 if (chars
< MAX_ERR_MSG_SIZE
)
4671 size
= MAX_ERR_MSG_SIZE
;
4672 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4673 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4685 * xmlTextReaderLocatorLineNumber:
4686 * @locator: the xmlTextReaderLocatorPtr used
4688 * Obtain the line number for the given locator.
4690 * Returns the line number or -1 in case of error.
4693 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4694 /* we know that locator is a xmlParserCtxtPtr */
4695 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4698 if (locator
== NULL
)
4700 if (ctx
->node
!= NULL
) {
4701 ret
= xmlGetLineNo(ctx
->node
);
4704 /* inspired from error.c */
4705 xmlParserInputPtr input
;
4707 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4708 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4709 if (input
!= NULL
) {
4721 * xmlTextReaderLocatorBaseURI:
4722 * @locator: the xmlTextReaderLocatorPtr used
4724 * Obtain the base URI for the given locator.
4726 * Returns the base URI or NULL in case of error,
4727 * if non NULL it need to be freed by the caller.
4730 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4731 /* we know that locator is a xmlParserCtxtPtr */
4732 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4733 xmlChar
*ret
= NULL
;
4735 if (locator
== NULL
)
4737 if (ctx
->node
!= NULL
) {
4738 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4741 /* inspired from error.c */
4742 xmlParserInputPtr input
;
4744 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4745 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4746 if (input
!= NULL
) {
4747 ret
= xmlStrdup(BAD_CAST input
->filename
);
4758 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4761 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4763 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4766 if (reader
->errorFunc
)
4767 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4768 (xmlTextReaderLocatorPtr
) ctx
);
4774 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4776 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4778 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4780 if (error
&& reader
->sErrorFunc
) {
4781 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4785 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4786 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4791 xmlTextReaderGenericError(ctxt
,
4792 XML_PARSER_SEVERITY_ERROR
,
4793 xmlTextReaderBuildMessage(msg
, ap
));
4798 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4799 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4804 xmlTextReaderGenericError(ctxt
,
4805 XML_PARSER_SEVERITY_WARNING
,
4806 xmlTextReaderBuildMessage(msg
, ap
));
4810 static void XMLCDECL
4811 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4815 int len
= xmlStrlen((const xmlChar
*) msg
);
4817 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4819 * some callbacks only report locator information:
4820 * skip them (mimicking behaviour in error.c)
4823 xmlTextReaderGenericError(ctxt
,
4824 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4825 xmlTextReaderBuildMessage(msg
, ap
));
4830 static void XMLCDECL
4831 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4835 int len
= xmlStrlen((const xmlChar
*) msg
);
4837 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4839 * some callbacks only report locator information:
4840 * skip them (mimicking behaviour in error.c)
4843 xmlTextReaderGenericError(ctxt
,
4844 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4845 xmlTextReaderBuildMessage(msg
, ap
));
4851 * xmlTextReaderSetErrorHandler:
4852 * @reader: the xmlTextReaderPtr used
4853 * @f: the callback function to call on error and warnings
4854 * @arg: a user argument to pass to the callback function
4856 * Register a callback function that will be called on error and warnings.
4858 * If @f is NULL, the default error and warning handlers are restored.
4861 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4862 xmlTextReaderErrorFunc f
, void *arg
)
4865 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4866 reader
->ctxt
->sax
->serror
= NULL
;
4867 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4868 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4869 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4870 reader
->errorFunc
= f
;
4871 reader
->sErrorFunc
= NULL
;
4872 reader
->errorFuncArg
= arg
;
4873 #ifdef LIBXML_SCHEMAS_ENABLED
4874 if (reader
->rngValidCtxt
) {
4875 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4876 xmlTextReaderValidityErrorRelay
,
4877 xmlTextReaderValidityWarningRelay
,
4879 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4882 if (reader
->xsdValidCtxt
) {
4883 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4884 xmlTextReaderValidityErrorRelay
,
4885 xmlTextReaderValidityWarningRelay
,
4887 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4892 /* restore defaults */
4893 reader
->ctxt
->sax
->error
= xmlParserError
;
4894 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4895 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4896 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4897 reader
->errorFunc
= NULL
;
4898 reader
->sErrorFunc
= NULL
;
4899 reader
->errorFuncArg
= NULL
;
4900 #ifdef LIBXML_SCHEMAS_ENABLED
4901 if (reader
->rngValidCtxt
) {
4902 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4904 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4907 if (reader
->xsdValidCtxt
) {
4908 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4910 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4918 * xmlTextReaderSetStructuredErrorHandler:
4919 * @reader: the xmlTextReaderPtr used
4920 * @f: the callback function to call on error and warnings
4921 * @arg: a user argument to pass to the callback function
4923 * Register a callback function that will be called on error and warnings.
4925 * If @f is NULL, the default error and warning handlers are restored.
4928 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
4929 xmlStructuredErrorFunc f
, void *arg
)
4932 reader
->ctxt
->sax
->error
= NULL
;
4933 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
4934 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4935 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4936 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4937 reader
->sErrorFunc
= f
;
4938 reader
->errorFunc
= NULL
;
4939 reader
->errorFuncArg
= arg
;
4940 #ifdef LIBXML_SCHEMAS_ENABLED
4941 if (reader
->rngValidCtxt
) {
4942 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4944 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4945 xmlTextReaderValidityStructuredRelay
,
4948 if (reader
->xsdValidCtxt
) {
4949 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4951 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4952 xmlTextReaderValidityStructuredRelay
,
4957 /* restore defaults */
4958 reader
->ctxt
->sax
->error
= xmlParserError
;
4959 reader
->ctxt
->sax
->serror
= NULL
;
4960 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4961 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4962 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4963 reader
->errorFunc
= NULL
;
4964 reader
->sErrorFunc
= NULL
;
4965 reader
->errorFuncArg
= NULL
;
4966 #ifdef LIBXML_SCHEMAS_ENABLED
4967 if (reader
->rngValidCtxt
) {
4968 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4970 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4973 if (reader
->xsdValidCtxt
) {
4974 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4976 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4984 * xmlTextReaderIsValid:
4985 * @reader: the xmlTextReaderPtr used
4987 * Retrieve the validity status from the parser context
4989 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
4992 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
4996 #ifdef LIBXML_SCHEMAS_ENABLED
4997 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
4998 return (reader
->rngValidErrors
== 0);
4999 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
5000 return (reader
->xsdValidErrors
== 0);
5002 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
5003 return (reader
->ctxt
->valid
);
5008 * xmlTextReaderGetErrorHandler:
5009 * @reader: the xmlTextReaderPtr used
5010 * @f: the callback function or NULL is no callback has been registered
5011 * @arg: a user argument
5013 * Retrieve the error callback function and user argument.
5016 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
5017 xmlTextReaderErrorFunc
* f
, void **arg
)
5020 *f
= reader
->errorFunc
;
5022 *arg
= reader
->errorFuncArg
;
5024 /************************************************************************
5026 * New set (2.6.0) of simpler and more flexible APIs *
5028 ************************************************************************/
5031 * xmlTextReaderSetup:
5032 * @reader: an XML reader
5033 * @input: xmlParserInputBufferPtr used to feed the reader, will
5034 * be destroyed with it.
5035 * @URL: the base URL to use for the document
5036 * @encoding: the document encoding, or NULL
5037 * @options: a combination of xmlParserOption
5039 * Setup an XML reader with new options
5041 * Returns 0 in case of success and -1 in case of error.
5044 xmlTextReaderSetup(xmlTextReaderPtr reader
,
5045 xmlParserInputBufferPtr input
, const char *URL
,
5046 const char *encoding
, int options
)
5048 if (reader
== NULL
) {
5050 xmlFreeParserInputBuffer(input
);
5055 * we force the generation of compact text nodes on the reader
5056 * since usr applications should never modify the tree
5058 options
|= XML_PARSE_COMPACT
;
5062 reader
->parserFlags
= options
;
5063 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
5064 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
5065 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
5066 xmlFreeParserInputBuffer(reader
->input
);
5067 reader
->input
= NULL
;
5068 reader
->allocs
-= XML_TEXTREADER_INPUT
;
5070 if (input
!= NULL
) {
5071 reader
->input
= input
;
5072 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5074 if (reader
->buffer
== NULL
)
5075 reader
->buffer
= xmlBufCreateSize(100);
5076 if (reader
->buffer
== NULL
) {
5077 xmlGenericError(xmlGenericErrorContext
,
5078 "xmlTextReaderSetup : malloc failed\n");
5081 /* no operation on a reader should require a huge buffer */
5082 xmlBufSetAllocationScheme(reader
->buffer
,
5083 XML_BUFFER_ALLOC_DOUBLEIT
);
5084 if (reader
->sax
== NULL
)
5085 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
5086 if (reader
->sax
== NULL
) {
5087 xmlGenericError(xmlGenericErrorContext
,
5088 "xmlTextReaderSetup : malloc failed\n");
5091 xmlSAXVersion(reader
->sax
, 2);
5092 reader
->startElement
= reader
->sax
->startElement
;
5093 reader
->sax
->startElement
= xmlTextReaderStartElement
;
5094 reader
->endElement
= reader
->sax
->endElement
;
5095 reader
->sax
->endElement
= xmlTextReaderEndElement
;
5096 #ifdef LIBXML_SAX1_ENABLED
5097 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
5098 #endif /* LIBXML_SAX1_ENABLED */
5099 reader
->startElementNs
= reader
->sax
->startElementNs
;
5100 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
5101 reader
->endElementNs
= reader
->sax
->endElementNs
;
5102 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
5103 #ifdef LIBXML_SAX1_ENABLED
5105 reader
->startElementNs
= NULL
;
5106 reader
->endElementNs
= NULL
;
5108 #endif /* LIBXML_SAX1_ENABLED */
5109 reader
->characters
= reader
->sax
->characters
;
5110 reader
->sax
->characters
= xmlTextReaderCharacters
;
5111 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
5112 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
5113 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
5115 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5116 reader
->node
= NULL
;
5117 reader
->curnode
= NULL
;
5118 if (input
!= NULL
) {
5119 if (xmlBufUse(reader
->input
->buffer
) < 4) {
5120 xmlParserInputBufferRead(input
, 4);
5122 if (reader
->ctxt
== NULL
) {
5123 if (xmlBufUse(reader
->input
->buffer
) >= 4) {
5124 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5125 (const char *) xmlBufContent(reader
->input
->buffer
),
5131 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5136 xmlParserInputPtr inputStream
;
5137 xmlParserInputBufferPtr buf
;
5138 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5140 xmlCtxtReset(reader
->ctxt
);
5141 buf
= xmlAllocParserInputBuffer(enc
);
5142 if (buf
== NULL
) return(-1);
5143 inputStream
= xmlNewInputStream(reader
->ctxt
);
5144 if (inputStream
== NULL
) {
5145 xmlFreeParserInputBuffer(buf
);
5150 inputStream
->filename
= NULL
;
5152 inputStream
->filename
= (char *)
5153 xmlCanonicPath((const xmlChar
*) URL
);
5154 inputStream
->buf
= buf
;
5155 xmlBufResetInput(buf
->buffer
, inputStream
);
5157 inputPush(reader
->ctxt
, inputStream
);
5160 if (reader
->ctxt
== NULL
) {
5161 xmlGenericError(xmlGenericErrorContext
,
5162 "xmlTextReaderSetup : malloc failed\n");
5166 if (reader
->dict
!= NULL
) {
5167 if (reader
->ctxt
->dict
!= NULL
) {
5168 if (reader
->dict
!= reader
->ctxt
->dict
) {
5169 xmlDictFree(reader
->dict
);
5170 reader
->dict
= reader
->ctxt
->dict
;
5173 reader
->ctxt
->dict
= reader
->dict
;
5176 if (reader
->ctxt
->dict
== NULL
)
5177 reader
->ctxt
->dict
= xmlDictCreate();
5178 reader
->dict
= reader
->ctxt
->dict
;
5180 reader
->ctxt
->_private
= reader
;
5181 reader
->ctxt
->linenumbers
= 1;
5182 reader
->ctxt
->dictNames
= 1;
5184 * use the parser dictionary to allocate all elements and attributes names
5186 reader
->ctxt
->docdict
= 1;
5187 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5189 #ifdef LIBXML_XINCLUDE_ENABLED
5190 if (reader
->xincctxt
!= NULL
) {
5191 xmlXIncludeFreeContext(reader
->xincctxt
);
5192 reader
->xincctxt
= NULL
;
5194 if (options
& XML_PARSE_XINCLUDE
) {
5195 reader
->xinclude
= 1;
5196 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5197 options
-= XML_PARSE_XINCLUDE
;
5199 reader
->xinclude
= 0;
5200 reader
->in_xinclude
= 0;
5202 #ifdef LIBXML_PATTERN_ENABLED
5203 if (reader
->patternTab
== NULL
) {
5204 reader
->patternNr
= 0;
5205 reader
->patternMax
= 0;
5207 while (reader
->patternNr
> 0) {
5208 reader
->patternNr
--;
5209 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5210 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5211 reader
->patternTab
[reader
->patternNr
] = NULL
;
5216 if (options
& XML_PARSE_DTDVALID
)
5217 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5219 xmlCtxtUseOptions(reader
->ctxt
, options
);
5220 if (encoding
!= NULL
) {
5221 xmlCharEncodingHandlerPtr hdlr
;
5223 hdlr
= xmlFindCharEncodingHandler(encoding
);
5225 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5227 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5228 (reader
->ctxt
->input
->filename
== NULL
))
5229 reader
->ctxt
->input
->filename
= (char *)
5230 xmlStrdup((const xmlChar
*) URL
);
5238 * xmlTextReaderByteConsumed:
5239 * @reader: an XML reader
5241 * This function provides the current index of the parser used
5242 * by the reader, relative to the start of the current entity.
5243 * This function actually just wraps a call to xmlBytesConsumed()
5244 * for the parser context associated with the reader.
5245 * See xmlBytesConsumed() for more information.
5247 * Returns the index in bytes from the beginning of the entity or -1
5248 * in case the index could not be computed.
5251 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5252 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5254 return(xmlByteConsumed(reader
->ctxt
));
5260 * @doc: a preparsed document
5262 * Create an xmltextReader for a preparsed document.
5264 * Returns the new reader or NULL in case of error.
5267 xmlReaderWalker(xmlDocPtr doc
)
5269 xmlTextReaderPtr ret
;
5274 ret
= xmlMalloc(sizeof(xmlTextReader
));
5276 xmlGenericError(xmlGenericErrorContext
,
5277 "xmlNewTextReader : malloc failed\n");
5280 memset(ret
, 0, sizeof(xmlTextReader
));
5283 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5285 ret
->curnode
= NULL
;
5288 ret
->allocs
= XML_TEXTREADER_CTXT
;
5290 ret
->state
= XML_TEXTREADER_START
;
5291 ret
->dict
= xmlDictCreate();
5297 * @cur: a pointer to a zero terminated string
5298 * @URL: the base URL to use for the document
5299 * @encoding: the document encoding, or NULL
5300 * @options: a combination of xmlParserOption
5302 * Create an xmltextReader for an XML in-memory document.
5303 * The parsing flags @options are a combination of xmlParserOption.
5305 * Returns the new reader or NULL in case of error.
5308 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5315 len
= xmlStrlen(cur
);
5317 return (xmlReaderForMemory
5318 ((const char *) cur
, len
, URL
, encoding
, options
));
5323 * @filename: a file or URL
5324 * @encoding: the document encoding, or NULL
5325 * @options: a combination of xmlParserOption
5327 * parse an XML file from the filesystem or the network.
5328 * The parsing flags @options are a combination of xmlParserOption.
5330 * Returns the new reader or NULL in case of error.
5333 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5335 xmlTextReaderPtr reader
;
5337 reader
= xmlNewTextReaderFilename(filename
);
5340 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5345 * xmlReaderForMemory:
5346 * @buffer: a pointer to a char array
5347 * @size: the size of the array
5348 * @URL: the base URL to use for the document
5349 * @encoding: the document encoding, or NULL
5350 * @options: a combination of xmlParserOption
5352 * Create an xmltextReader for an XML in-memory document.
5353 * The parsing flags @options are a combination of xmlParserOption.
5355 * Returns the new reader or NULL in case of error.
5358 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5359 const char *encoding
, int options
)
5361 xmlTextReaderPtr reader
;
5362 xmlParserInputBufferPtr buf
;
5364 buf
= xmlParserInputBufferCreateStatic(buffer
, size
,
5365 XML_CHAR_ENCODING_NONE
);
5369 reader
= xmlNewTextReader(buf
, URL
);
5370 if (reader
== NULL
) {
5371 xmlFreeParserInputBuffer(buf
);
5374 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5375 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5381 * @fd: an open file descriptor
5382 * @URL: the base URL to use for the document
5383 * @encoding: the document encoding, or NULL
5384 * @options: a combination of xmlParserOption
5386 * Create an xmltextReader for an XML from a file descriptor.
5387 * The parsing flags @options are a combination of xmlParserOption.
5388 * NOTE that the file descriptor will not be closed when the
5389 * reader is closed or reset.
5391 * Returns the new reader or NULL in case of error.
5394 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5396 xmlTextReaderPtr reader
;
5397 xmlParserInputBufferPtr input
;
5402 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5405 input
->closecallback
= NULL
;
5406 reader
= xmlNewTextReader(input
, URL
);
5407 if (reader
== NULL
) {
5408 xmlFreeParserInputBuffer(input
);
5411 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5412 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5418 * @ioread: an I/O read function
5419 * @ioclose: an I/O close function
5420 * @ioctx: an I/O handler
5421 * @URL: the base URL to use for the document
5422 * @encoding: the document encoding, or NULL
5423 * @options: a combination of xmlParserOption
5425 * Create an xmltextReader for an XML document from I/O functions and source.
5426 * The parsing flags @options are a combination of xmlParserOption.
5428 * Returns the new reader or NULL in case of error.
5431 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5432 void *ioctx
, const char *URL
, const char *encoding
,
5435 xmlTextReaderPtr reader
;
5436 xmlParserInputBufferPtr input
;
5441 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5442 XML_CHAR_ENCODING_NONE
);
5443 if (input
== NULL
) {
5444 if (ioclose
!= NULL
)
5448 reader
= xmlNewTextReader(input
, URL
);
5449 if (reader
== NULL
) {
5450 xmlFreeParserInputBuffer(input
);
5453 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5454 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5459 * xmlReaderNewWalker:
5460 * @reader: an XML reader
5461 * @doc: a preparsed document
5463 * Setup an xmltextReader to parse a preparsed XML document.
5464 * This reuses the existing @reader xmlTextReader.
5466 * Returns 0 in case of success and -1 in case of error
5469 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5476 if (reader
->input
!= NULL
) {
5477 xmlFreeParserInputBuffer(reader
->input
);
5479 if (reader
->ctxt
!= NULL
) {
5480 xmlCtxtReset(reader
->ctxt
);
5484 reader
->input
= NULL
;
5485 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5486 reader
->node
= NULL
;
5487 reader
->curnode
= NULL
;
5490 reader
->allocs
= XML_TEXTREADER_CTXT
;
5492 reader
->state
= XML_TEXTREADER_START
;
5493 if (reader
->dict
== NULL
) {
5494 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5495 reader
->dict
= reader
->ctxt
->dict
;
5497 reader
->dict
= xmlDictCreate();
5504 * @reader: an XML reader
5505 * @cur: a pointer to a zero terminated string
5506 * @URL: the base URL to use for the document
5507 * @encoding: the document encoding, or NULL
5508 * @options: a combination of xmlParserOption
5510 * Setup an xmltextReader to parse an XML in-memory document.
5511 * The parsing flags @options are a combination of xmlParserOption.
5512 * This reuses the existing @reader xmlTextReader.
5514 * Returns 0 in case of success and -1 in case of error
5517 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5518 const char *URL
, const char *encoding
, int options
)
5528 len
= xmlStrlen(cur
);
5529 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5530 URL
, encoding
, options
));
5535 * @reader: an XML reader
5536 * @filename: a file or URL
5537 * @encoding: the document encoding, or NULL
5538 * @options: a combination of xmlParserOption
5540 * parse an XML file from the filesystem or the network.
5541 * The parsing flags @options are a combination of xmlParserOption.
5542 * This reuses the existing @reader xmlTextReader.
5544 * Returns 0 in case of success and -1 in case of error
5547 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5548 const char *encoding
, int options
)
5550 xmlParserInputBufferPtr input
;
5552 if (filename
== NULL
)
5558 xmlParserInputBufferCreateFilename(filename
,
5559 XML_CHAR_ENCODING_NONE
);
5562 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5566 * xmlReaderNewMemory:
5567 * @reader: an XML reader
5568 * @buffer: a pointer to a char array
5569 * @size: the size of the array
5570 * @URL: the base URL to use for the document
5571 * @encoding: the document encoding, or NULL
5572 * @options: a combination of xmlParserOption
5574 * Setup an xmltextReader to parse an XML in-memory document.
5575 * The parsing flags @options are a combination of xmlParserOption.
5576 * This reuses the existing @reader xmlTextReader.
5578 * Returns 0 in case of success and -1 in case of error
5581 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5582 const char *URL
, const char *encoding
, int options
)
5584 xmlParserInputBufferPtr input
;
5591 input
= xmlParserInputBufferCreateStatic(buffer
, size
,
5592 XML_CHAR_ENCODING_NONE
);
5593 if (input
== NULL
) {
5596 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5601 * @reader: an XML reader
5602 * @fd: an open file descriptor
5603 * @URL: the base URL to use for the document
5604 * @encoding: the document encoding, or NULL
5605 * @options: a combination of xmlParserOption
5607 * Setup an xmltextReader to parse an XML from a file descriptor.
5608 * NOTE that the file descriptor will not be closed when the
5609 * reader is closed or reset.
5610 * The parsing flags @options are a combination of xmlParserOption.
5611 * This reuses the existing @reader xmlTextReader.
5613 * Returns 0 in case of success and -1 in case of error
5616 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5617 const char *URL
, const char *encoding
, int options
)
5619 xmlParserInputBufferPtr input
;
5626 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5629 input
->closecallback
= NULL
;
5630 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5635 * @reader: an XML reader
5636 * @ioread: an I/O read function
5637 * @ioclose: an I/O close function
5638 * @ioctx: an I/O handler
5639 * @URL: the base URL to use for the document
5640 * @encoding: the document encoding, or NULL
5641 * @options: a combination of xmlParserOption
5643 * Setup an xmltextReader to parse an XML document from I/O functions
5645 * The parsing flags @options are a combination of xmlParserOption.
5646 * This reuses the existing @reader xmlTextReader.
5648 * Returns 0 in case of success and -1 in case of error
5651 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5652 xmlInputCloseCallback ioclose
, void *ioctx
,
5653 const char *URL
, const char *encoding
, int options
)
5655 xmlParserInputBufferPtr input
;
5662 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5663 XML_CHAR_ENCODING_NONE
);
5664 if (input
== NULL
) {
5665 if (ioclose
!= NULL
)
5669 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5672 /************************************************************************
5676 ************************************************************************/
5681 * @in: the input buffer
5682 * @inlen: the size of the input (in), the size read from it (out)
5683 * @to: the output buffer
5684 * @tolen: the size of the output (in), the size written to (out)
5686 * Base64 decoder, reads from @in and save in @to
5687 * TODO: tell jody when this is actually exported
5689 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5690 * 2 if there wasn't enough space on the output or -1 in case of error.
5693 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5694 unsigned char *to
, unsigned long *tolen
)
5696 unsigned long incur
; /* current index in in[] */
5698 unsigned long inblk
; /* last block index in in[] */
5700 unsigned long outcur
; /* current index in out[] */
5702 unsigned long inmax
; /* size of in[] */
5704 unsigned long outmax
; /* size of out[] */
5706 unsigned char cur
; /* the current value read from in[] */
5708 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5710 int nbintmp
; /* number of byte in intmp[] */
5712 int is_ignore
; /* cur should be ignored */
5714 int is_end
= 0; /* the end of the base64 was found */
5720 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5735 if ((cur
>= 'A') && (cur
<= 'Z'))
5737 else if ((cur
>= 'a') && (cur
<= 'z'))
5738 cur
= cur
- 'a' + 26;
5739 else if ((cur
>= '0') && (cur
<= '9'))
5740 cur
= cur
- '0' + 52;
5741 else if (cur
== '+')
5743 else if (cur
== '/')
5745 else if (cur
== '.')
5747 else if (cur
== '=') /*no op , end of the base64 stream */
5763 if ((nbintmp
== 1) || (nbintmp
== 2))
5770 intmp
[nbintmp
++] = cur
;
5772 * if intmp is full, push the 4byte sequence as a 3 byte
5777 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5779 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5780 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5781 if (outcur
+ 3 >= outmax
) {
5786 for (i
= 0; i
< nbouttmp
; i
++)
5787 to
[outcur
++] = outtmp
[i
];
5804 * Test routine for the xmlBase64Decode function
5808 main(int argc
, char **argv
)
5810 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5818 unsigned long inlen
= strlen(input
);
5820 unsigned long outlen
= 100;
5824 unsigned long cons
, tmp
, tmp2
, prod
;
5829 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5832 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5833 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5841 while (cons
< inlen
) {
5843 tmp2
= inlen
- cons
;
5845 printf("%ld %ld\n", cons
, prod
);
5846 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5849 printf("%ld %ld\n", cons
, prod
);
5851 output2
[outlen
] = 0;
5852 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5860 while (cons
< inlen
) {
5862 tmp2
= inlen
- cons
;
5866 printf("%ld %ld\n", cons
, prod
);
5867 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5870 printf("%ld %ld\n", cons
, prod
);
5872 output3
[outlen
] = 0;
5873 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5879 #endif /* NOT_USED_YET */
5881 #endif /* LIBXML_READER_ENABLED */