2 * xmlreader.c: implements the xmlTextReader streaming node API
5 * XmlTextReader.Normalization Property won't be supported, since
6 * it makes the parser non compliant to the XML recommendation
8 * See Copyright for the status of this software.
15 * - XML Schemas validation
20 #ifdef LIBXML_READER_ENABLED
21 #include <string.h> /* for memset() only ! */
31 #include <libxml/xmlmemory.h>
32 #include <libxml/xmlIO.h>
33 #include <libxml/xmlreader.h>
34 #include <libxml/parserInternals.h>
35 #ifdef LIBXML_SCHEMAS_ENABLED
36 #include <libxml/relaxng.h>
37 #include <libxml/xmlschemas.h>
39 #include <libxml/uri.h>
40 #ifdef LIBXML_XINCLUDE_ENABLED
41 #include <libxml/xinclude.h>
43 #ifdef LIBXML_PATTERN_ENABLED
44 #include <libxml/pattern.h>
49 #define MAX_ERR_MSG_SIZE 64000
52 * The following VA_COPY was coded following an example in
53 * the Samba project. It may not be sufficient for some
54 * esoteric implementations of va_list (i.e. it may need
55 * something involving a memcpy) but (hopefully) will be
56 * sufficient for libxml2.
60 #define VA_COPY(dest, src) va_copy(dest, src)
63 #define VA_COPY(dest,src) __va_copy(dest, src)
65 #define VA_COPY(dest,src) (dest) = (src)
70 /* #define DEBUG_CALLBACKS */
71 /* #define DEBUG_READER */
76 * macro to flag unimplemented blocks
79 xmlGenericError(xmlGenericErrorContext, \
80 "Unimplemented block at %s:%d\n", \
84 #define DUMP_READER xmlTextReaderDebug(reader);
89 #define CHUNK_SIZE 512
90 /************************************************************************
92 * The parser: maps the Text Reader API on top of the existing *
93 * parsing routines building a tree *
95 ************************************************************************/
97 #define XML_TEXTREADER_INPUT 1
98 #define XML_TEXTREADER_CTXT 2
101 XML_TEXTREADER_NONE
= -1,
102 XML_TEXTREADER_START
= 0,
103 XML_TEXTREADER_ELEMENT
= 1,
104 XML_TEXTREADER_END
= 2,
105 XML_TEXTREADER_EMPTY
= 3,
106 XML_TEXTREADER_BACKTRACK
= 4,
107 XML_TEXTREADER_DONE
= 5,
108 XML_TEXTREADER_ERROR
= 6
109 } xmlTextReaderState
;
112 XML_TEXTREADER_NOT_VALIDATE
= 0,
113 XML_TEXTREADER_VALIDATE_DTD
= 1,
114 XML_TEXTREADER_VALIDATE_RNG
= 2,
115 XML_TEXTREADER_VALIDATE_XSD
= 4
116 } xmlTextReaderValidate
;
118 struct _xmlTextReader
{
119 int mode
; /* the parsing mode */
120 xmlDocPtr doc
; /* when walking an existing doc */
121 xmlTextReaderValidate validate
;/* is there any validation */
122 int allocs
; /* what structure were deallocated */
123 xmlTextReaderState state
;
124 xmlParserCtxtPtr ctxt
; /* the parser context */
125 xmlSAXHandlerPtr sax
; /* the parser SAX callbacks */
126 xmlParserInputBufferPtr input
; /* the input */
127 startElementSAXFunc startElement
;/* initial SAX callbacks */
128 endElementSAXFunc endElement
; /* idem */
129 startElementNsSAX2Func startElementNs
;/* idem */
130 endElementNsSAX2Func endElementNs
; /* idem */
131 charactersSAXFunc characters
;
132 cdataBlockSAXFunc cdataBlock
;
133 unsigned int base
; /* base of the segment in the input */
134 unsigned int cur
; /* current position in the input */
135 xmlNodePtr node
; /* current node */
136 xmlNodePtr curnode
;/* current attribute node */
137 int depth
; /* depth of the current node */
138 xmlNodePtr faketext
;/* fake xmlNs chld */
139 int preserve
;/* preserve the resulting document */
140 xmlBufPtr buffer
; /* used to return const xmlChar * */
141 xmlDictPtr dict
; /* the context dictionnary */
143 /* entity stack when traversing entities content */
144 xmlNodePtr ent
; /* Current Entity Ref Node */
145 int entNr
; /* Depth of the entities stack */
146 int entMax
; /* Max depth of the entities stack */
147 xmlNodePtr
*entTab
; /* array of entities */
150 xmlTextReaderErrorFunc errorFunc
; /* callback function */
151 void *errorFuncArg
; /* callback function user argument */
153 #ifdef LIBXML_SCHEMAS_ENABLED
154 /* Handling of RelaxNG validation */
155 xmlRelaxNGPtr rngSchemas
; /* The Relax NG schemas */
156 xmlRelaxNGValidCtxtPtr rngValidCtxt
;/* The Relax NG validation context */
157 int rngPreserveCtxt
; /* 1 if the context was provided by the user */
158 int rngValidErrors
;/* The number of errors detected */
159 xmlNodePtr rngFullNode
; /* the node if RNG not progressive */
160 /* Handling of Schemas validation */
161 xmlSchemaPtr xsdSchemas
; /* The Schemas schemas */
162 xmlSchemaValidCtxtPtr xsdValidCtxt
;/* The Schemas validation context */
163 int xsdPreserveCtxt
; /* 1 if the context was provided by the user */
164 int xsdValidErrors
;/* The number of errors detected */
165 xmlSchemaSAXPlugPtr xsdPlug
; /* the schemas plug in SAX pipeline */
167 #ifdef LIBXML_XINCLUDE_ENABLED
168 /* Handling of XInclude processing */
169 int xinclude
; /* is xinclude asked for */
170 const xmlChar
* xinclude_name
; /* the xinclude name from dict */
171 xmlXIncludeCtxtPtr xincctxt
; /* the xinclude context */
172 int in_xinclude
; /* counts for xinclude */
174 #ifdef LIBXML_PATTERN_ENABLED
175 int patternNr
; /* number of preserve patterns */
176 int patternMax
; /* max preserve patterns */
177 xmlPatternPtr
*patternTab
; /* array of preserve patterns */
179 int preserves
; /* level of preserves */
180 int parserFlags
; /* the set of options set */
181 /* Structured error handling */
182 xmlStructuredErrorFunc sErrorFunc
; /* callback function */
185 #define NODE_IS_EMPTY 0x1
186 #define NODE_IS_PRESERVED 0x2
187 #define NODE_IS_SPRESERVED 0x4
192 * Macro used to return an interned string
194 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
195 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
197 static int xmlTextReaderReadTree(xmlTextReaderPtr reader
);
198 static int xmlTextReaderNextTree(xmlTextReaderPtr reader
);
200 /************************************************************************
202 * Our own version of the freeing routines as we recycle nodes *
204 ************************************************************************/
209 * Free a string if it is not owned by the "dict" dictionnary in the
212 #define DICT_FREE(str) \
213 if ((str) && ((!dict) || \
214 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
215 xmlFree((char *)(str));
217 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
);
218 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
);
224 * Deallocate the memory used by an id definition
227 xmlFreeID(xmlIDPtr id
) {
228 xmlDictPtr dict
= NULL
;
230 if (id
== NULL
) return;
233 dict
= id
->doc
->dict
;
235 if (id
->value
!= NULL
)
241 * xmlTextReaderRemoveID:
243 * @attr: the attribute
245 * Remove the given attribute from the ID table maintained internally.
247 * Returns -1 if the lookup failed and 0 otherwise
250 xmlTextReaderRemoveID(xmlDocPtr doc
, xmlAttrPtr attr
) {
255 if (doc
== NULL
) return(-1);
256 if (attr
== NULL
) return(-1);
257 table
= (xmlIDTablePtr
) doc
->ids
;
261 ID
= xmlNodeListGetString(doc
, attr
->children
, 1);
264 id
= xmlHashLookup(table
, ID
);
266 if (id
== NULL
|| id
->attr
!= attr
) {
269 id
->name
= attr
->name
;
275 * xmlTextReaderFreeProp:
276 * @reader: the xmlTextReaderPtr used
282 xmlTextReaderFreeProp(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
285 dict
= reader
->ctxt
->dict
;
286 if (cur
== NULL
) return;
288 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
289 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
291 /* Check for ID removal -> leading to invalid references ! */
292 if ((cur
->parent
!= NULL
) && (cur
->parent
->doc
!= NULL
) &&
293 ((cur
->parent
->doc
->intSubset
!= NULL
) ||
294 (cur
->parent
->doc
->extSubset
!= NULL
))) {
295 if (xmlIsID(cur
->parent
->doc
, cur
->parent
, cur
))
296 xmlTextReaderRemoveID(cur
->parent
->doc
, cur
);
298 if (cur
->children
!= NULL
)
299 xmlTextReaderFreeNodeList(reader
, cur
->children
);
301 DICT_FREE(cur
->name
);
302 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
303 (reader
->ctxt
->freeAttrsNr
< 100)) {
304 cur
->next
= reader
->ctxt
->freeAttrs
;
305 reader
->ctxt
->freeAttrs
= cur
;
306 reader
->ctxt
->freeAttrsNr
++;
313 * xmlTextReaderFreePropList:
314 * @reader: the xmlTextReaderPtr used
315 * @cur: the first property in the list
317 * Free a property and all its siblings, all the children are freed too.
320 xmlTextReaderFreePropList(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
322 if (cur
== NULL
) return;
323 while (cur
!= NULL
) {
325 xmlTextReaderFreeProp(reader
, cur
);
331 * xmlTextReaderFreeNodeList:
332 * @reader: the xmlTextReaderPtr used
333 * @cur: the first node in the list
335 * Free a node and all its siblings, this is a recursive behaviour, all
336 * the children are freed too.
339 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
343 dict
= reader
->ctxt
->dict
;
344 if (cur
== NULL
) return;
345 if (cur
->type
== XML_NAMESPACE_DECL
) {
346 xmlFreeNsList((xmlNsPtr
) cur
);
349 if ((cur
->type
== XML_DOCUMENT_NODE
) ||
350 (cur
->type
== XML_HTML_DOCUMENT_NODE
)) {
351 xmlFreeDoc((xmlDocPtr
) cur
);
354 while (cur
!= NULL
) {
356 /* unroll to speed up freeing the document */
357 if (cur
->type
!= XML_DTD_NODE
) {
359 if ((cur
->children
!= NULL
) &&
360 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
361 if (cur
->children
->parent
== cur
)
362 xmlTextReaderFreeNodeList(reader
, cur
->children
);
363 cur
->children
= NULL
;
366 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
367 xmlDeregisterNodeDefaultValue(cur
);
369 if (((cur
->type
== XML_ELEMENT_NODE
) ||
370 (cur
->type
== XML_XINCLUDE_START
) ||
371 (cur
->type
== XML_XINCLUDE_END
)) &&
372 (cur
->properties
!= NULL
))
373 xmlTextReaderFreePropList(reader
, cur
->properties
);
374 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
375 (cur
->type
!= XML_ELEMENT_NODE
) &&
376 (cur
->type
!= XML_XINCLUDE_START
) &&
377 (cur
->type
!= XML_XINCLUDE_END
) &&
378 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
379 DICT_FREE(cur
->content
);
381 if (((cur
->type
== XML_ELEMENT_NODE
) ||
382 (cur
->type
== XML_XINCLUDE_START
) ||
383 (cur
->type
== XML_XINCLUDE_END
)) &&
384 (cur
->nsDef
!= NULL
))
385 xmlFreeNsList(cur
->nsDef
);
388 * we don't free element names here they are interned now
390 if ((cur
->type
!= XML_TEXT_NODE
) &&
391 (cur
->type
!= XML_COMMENT_NODE
))
392 DICT_FREE(cur
->name
);
393 if (((cur
->type
== XML_ELEMENT_NODE
) ||
394 (cur
->type
== XML_TEXT_NODE
)) &&
395 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
396 (reader
->ctxt
->freeElemsNr
< 100)) {
397 cur
->next
= reader
->ctxt
->freeElems
;
398 reader
->ctxt
->freeElems
= cur
;
399 reader
->ctxt
->freeElemsNr
++;
409 * xmlTextReaderFreeNode:
410 * @reader: the xmlTextReaderPtr used
413 * Free a node, this is a recursive behaviour, all the children are freed too.
414 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
417 xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
420 dict
= reader
->ctxt
->dict
;
421 if (cur
->type
== XML_DTD_NODE
) {
422 xmlFreeDtd((xmlDtdPtr
) cur
);
425 if (cur
->type
== XML_NAMESPACE_DECL
) {
426 xmlFreeNs((xmlNsPtr
) cur
);
429 if (cur
->type
== XML_ATTRIBUTE_NODE
) {
430 xmlTextReaderFreeProp(reader
, (xmlAttrPtr
) cur
);
434 if ((cur
->children
!= NULL
) &&
435 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
436 if (cur
->children
->parent
== cur
)
437 xmlTextReaderFreeNodeList(reader
, cur
->children
);
438 cur
->children
= NULL
;
441 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
442 xmlDeregisterNodeDefaultValue(cur
);
444 if (((cur
->type
== XML_ELEMENT_NODE
) ||
445 (cur
->type
== XML_XINCLUDE_START
) ||
446 (cur
->type
== XML_XINCLUDE_END
)) &&
447 (cur
->properties
!= NULL
))
448 xmlTextReaderFreePropList(reader
, cur
->properties
);
449 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
450 (cur
->type
!= XML_ELEMENT_NODE
) &&
451 (cur
->type
!= XML_XINCLUDE_START
) &&
452 (cur
->type
!= XML_XINCLUDE_END
) &&
453 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
454 DICT_FREE(cur
->content
);
456 if (((cur
->type
== XML_ELEMENT_NODE
) ||
457 (cur
->type
== XML_XINCLUDE_START
) ||
458 (cur
->type
== XML_XINCLUDE_END
)) &&
459 (cur
->nsDef
!= NULL
))
460 xmlFreeNsList(cur
->nsDef
);
463 * we don't free names here they are interned now
465 if ((cur
->type
!= XML_TEXT_NODE
) &&
466 (cur
->type
!= XML_COMMENT_NODE
))
467 DICT_FREE(cur
->name
);
469 if (((cur
->type
== XML_ELEMENT_NODE
) ||
470 (cur
->type
== XML_TEXT_NODE
)) &&
471 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
472 (reader
->ctxt
->freeElemsNr
< 100)) {
473 cur
->next
= reader
->ctxt
->freeElems
;
474 reader
->ctxt
->freeElems
= cur
;
475 reader
->ctxt
->freeElemsNr
++;
482 * xmlTextReaderFreeIDTable:
483 * @table: An id table
485 * Deallocate the memory used by an ID hash table.
488 xmlTextReaderFreeIDTable(xmlIDTablePtr table
) {
489 xmlHashFree(table
, (xmlHashDeallocator
) xmlFreeID
);
493 * xmlTextReaderFreeDoc:
494 * @reader: the xmlTextReaderPtr used
495 * @cur: pointer to the document
497 * Free up all the structures used by a document, tree included.
500 xmlTextReaderFreeDoc(xmlTextReaderPtr reader
, xmlDocPtr cur
) {
501 xmlDtdPtr extSubset
, intSubset
;
503 if (cur
== NULL
) return;
505 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
506 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
509 * Do this before freeing the children list to avoid ID lookups
511 if (cur
->ids
!= NULL
) xmlTextReaderFreeIDTable((xmlIDTablePtr
) cur
->ids
);
513 if (cur
->refs
!= NULL
) xmlFreeRefTable((xmlRefTablePtr
) cur
->refs
);
515 extSubset
= cur
->extSubset
;
516 intSubset
= cur
->intSubset
;
517 if (intSubset
== extSubset
)
519 if (extSubset
!= NULL
) {
520 xmlUnlinkNode((xmlNodePtr
) cur
->extSubset
);
521 cur
->extSubset
= NULL
;
522 xmlFreeDtd(extSubset
);
524 if (intSubset
!= NULL
) {
525 xmlUnlinkNode((xmlNodePtr
) cur
->intSubset
);
526 cur
->intSubset
= NULL
;
527 xmlFreeDtd(intSubset
);
530 if (cur
->children
!= NULL
) xmlTextReaderFreeNodeList(reader
, cur
->children
);
532 if (cur
->version
!= NULL
) xmlFree((char *) cur
->version
);
533 if (cur
->name
!= NULL
) xmlFree((char *) cur
->name
);
534 if (cur
->encoding
!= NULL
) xmlFree((char *) cur
->encoding
);
535 if (cur
->oldNs
!= NULL
) xmlFreeNsList(cur
->oldNs
);
536 if (cur
->URL
!= NULL
) xmlFree((char *) cur
->URL
);
537 if (cur
->dict
!= NULL
) xmlDictFree(cur
->dict
);
542 /************************************************************************
544 * The reader core parser *
546 ************************************************************************/
549 xmlTextReaderDebug(xmlTextReaderPtr reader
) {
550 if ((reader
== NULL
) || (reader
->ctxt
== NULL
)) {
551 fprintf(stderr
, "xmlTextReader NULL\n");
554 fprintf(stderr
, "xmlTextReader: state %d depth %d ",
555 reader
->state
, reader
->depth
);
556 if (reader
->node
== NULL
) {
557 fprintf(stderr
, "node = NULL\n");
559 fprintf(stderr
, "node %s\n", reader
->node
->name
);
561 fprintf(stderr
, " input: base %d, cur %d, depth %d: ",
562 reader
->base
, reader
->cur
, reader
->ctxt
->nodeNr
);
563 if (reader
->input
->buffer
== NULL
) {
564 fprintf(stderr
, "buffer is NULL\n");
566 #ifdef LIBXML_DEBUG_ENABLED
567 xmlDebugDumpString(stderr
,
568 &reader
->input
->buffer
->content
[reader
->cur
]);
570 fprintf(stderr
, "\n");
576 * xmlTextReaderEntPush:
577 * @reader: the xmlTextReaderPtr used
578 * @value: the entity reference node
580 * Pushes a new entity reference node on top of the entities stack
582 * Returns 0 in case of error, the index in the stack otherwise
585 xmlTextReaderEntPush(xmlTextReaderPtr reader
, xmlNodePtr value
)
587 if (reader
->entMax
<= 0) {
589 reader
->entTab
= (xmlNodePtr
*) xmlMalloc(reader
->entMax
*
590 sizeof(reader
->entTab
[0]));
591 if (reader
->entTab
== NULL
) {
592 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
596 if (reader
->entNr
>= reader
->entMax
) {
599 (xmlNodePtr
*) xmlRealloc(reader
->entTab
,
601 sizeof(reader
->entTab
[0]));
602 if (reader
->entTab
== NULL
) {
603 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
607 reader
->entTab
[reader
->entNr
] = value
;
609 return (reader
->entNr
++);
613 * xmlTextReaderEntPop:
614 * @reader: the xmlTextReaderPtr used
616 * Pops the top element entity from the entities stack
618 * Returns the entity just removed
621 xmlTextReaderEntPop(xmlTextReaderPtr reader
)
625 if (reader
->entNr
<= 0)
628 if (reader
->entNr
> 0)
629 reader
->ent
= reader
->entTab
[reader
->entNr
- 1];
632 ret
= reader
->entTab
[reader
->entNr
];
633 reader
->entTab
[reader
->entNr
] = NULL
;
638 * xmlTextReaderStartElement:
639 * @ctx: the user data (XML parser context)
640 * @fullname: The element name, including namespace prefix
641 * @atts: An array of name/value attributes pairs, NULL terminated
643 * called when an opening tag has been processed.
646 xmlTextReaderStartElement(void *ctx
, const xmlChar
*fullname
,
647 const xmlChar
**atts
) {
648 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
649 xmlTextReaderPtr reader
= ctxt
->_private
;
651 #ifdef DEBUG_CALLBACKS
652 printf("xmlTextReaderStartElement(%s)\n", fullname
);
654 if ((reader
!= NULL
) && (reader
->startElement
!= NULL
)) {
655 reader
->startElement(ctx
, fullname
, atts
);
656 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
657 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
658 (ctxt
->input
->cur
[1] == '>'))
659 ctxt
->node
->extra
= NODE_IS_EMPTY
;
662 reader
->state
= XML_TEXTREADER_ELEMENT
;
666 * xmlTextReaderEndElement:
667 * @ctx: the user data (XML parser context)
668 * @fullname: The element name, including namespace prefix
670 * called when an ending tag has been processed.
673 xmlTextReaderEndElement(void *ctx
, const xmlChar
*fullname
) {
674 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
675 xmlTextReaderPtr reader
= ctxt
->_private
;
677 #ifdef DEBUG_CALLBACKS
678 printf("xmlTextReaderEndElement(%s)\n", fullname
);
680 if ((reader
!= NULL
) && (reader
->endElement
!= NULL
)) {
681 reader
->endElement(ctx
, fullname
);
686 * xmlTextReaderStartElementNs:
687 * @ctx: the user data (XML parser context)
688 * @localname: the local name of the element
689 * @prefix: the element namespace prefix if available
690 * @URI: the element namespace name if available
691 * @nb_namespaces: number of namespace definitions on that node
692 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
693 * @nb_attributes: the number of attributes on that node
694 * nb_defaulted: the number of defaulted attributes.
695 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
698 * called when an opening tag has been processed.
701 xmlTextReaderStartElementNs(void *ctx
,
702 const xmlChar
*localname
,
703 const xmlChar
*prefix
,
706 const xmlChar
**namespaces
,
709 const xmlChar
**attributes
)
711 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
712 xmlTextReaderPtr reader
= ctxt
->_private
;
714 #ifdef DEBUG_CALLBACKS
715 printf("xmlTextReaderStartElementNs(%s)\n", localname
);
717 if ((reader
!= NULL
) && (reader
->startElementNs
!= NULL
)) {
718 reader
->startElementNs(ctx
, localname
, prefix
, URI
, nb_namespaces
,
719 namespaces
, nb_attributes
, nb_defaulted
,
721 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
722 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
723 (ctxt
->input
->cur
[1] == '>'))
724 ctxt
->node
->extra
= NODE_IS_EMPTY
;
727 reader
->state
= XML_TEXTREADER_ELEMENT
;
731 * xmlTextReaderEndElementNs:
732 * @ctx: the user data (XML parser context)
733 * @localname: the local name of the element
734 * @prefix: the element namespace prefix if available
735 * @URI: the element namespace name if available
737 * called when an ending tag has been processed.
740 xmlTextReaderEndElementNs(void *ctx
,
741 const xmlChar
* localname
,
742 const xmlChar
* prefix
,
745 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
746 xmlTextReaderPtr reader
= ctxt
->_private
;
748 #ifdef DEBUG_CALLBACKS
749 printf("xmlTextReaderEndElementNs(%s)\n", localname
);
751 if ((reader
!= NULL
) && (reader
->endElementNs
!= NULL
)) {
752 reader
->endElementNs(ctx
, localname
, prefix
, URI
);
758 * xmlTextReaderCharacters:
759 * @ctx: the user data (XML parser context)
760 * @ch: a xmlChar string
761 * @len: the number of xmlChar
763 * receiving some chars from the parser.
766 xmlTextReaderCharacters(void *ctx
, const xmlChar
*ch
, int len
)
768 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
769 xmlTextReaderPtr reader
= ctxt
->_private
;
771 #ifdef DEBUG_CALLBACKS
772 printf("xmlTextReaderCharacters()\n");
774 if ((reader
!= NULL
) && (reader
->characters
!= NULL
)) {
775 reader
->characters(ctx
, ch
, len
);
780 * xmlTextReaderCDataBlock:
781 * @ctx: the user data (XML parser context)
782 * @value: The pcdata content
783 * @len: the block length
785 * called when a pcdata block has been parsed
788 xmlTextReaderCDataBlock(void *ctx
, const xmlChar
*ch
, int len
)
790 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
791 xmlTextReaderPtr reader
= ctxt
->_private
;
793 #ifdef DEBUG_CALLBACKS
794 printf("xmlTextReaderCDataBlock()\n");
796 if ((reader
!= NULL
) && (reader
->cdataBlock
!= NULL
)) {
797 reader
->cdataBlock(ctx
, ch
, len
);
802 * xmlTextReaderPushData:
803 * @reader: the xmlTextReaderPtr used
805 * Push data down the progressive parser until a significant callback
808 * Returns -1 in case of failure, 0 otherwise
811 xmlTextReaderPushData(xmlTextReaderPtr reader
) {
814 xmlTextReaderState oldstate
;
817 if ((reader
->input
== NULL
) || (reader
->input
->buffer
== NULL
))
820 oldstate
= reader
->state
;
821 reader
->state
= XML_TEXTREADER_NONE
;
822 inbuf
= reader
->input
->buffer
;
823 alloc
= xmlBufGetAllocationScheme(inbuf
);
825 while (reader
->state
== XML_TEXTREADER_NONE
) {
826 if (xmlBufUse(inbuf
) < reader
->cur
+ CHUNK_SIZE
) {
828 * Refill the buffer unless we are at the end of the stream
830 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
831 val
= xmlParserInputBufferRead(reader
->input
, 4096);
833 (alloc
== XML_BUFFER_ALLOC_IMMUTABLE
)) {
834 if (xmlBufUse(inbuf
) == reader
->cur
) {
835 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
836 reader
->state
= oldstate
;
838 } else if (val
< 0) {
839 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
840 reader
->state
= oldstate
;
841 if ((oldstate
!= XML_TEXTREADER_START
) ||
842 (reader
->ctxt
->myDoc
!= NULL
))
844 } else if (val
== 0) {
845 /* mark the end of the stream and process the remains */
846 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
854 * parse by block of CHUNK_SIZE bytes, various tests show that
855 * it's the best tradeoff at least on a 1.2GH Duron
857 if (xmlBufUse(inbuf
) >= reader
->cur
+ CHUNK_SIZE
) {
858 val
= xmlParseChunk(reader
->ctxt
,
859 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
861 reader
->cur
+= CHUNK_SIZE
;
863 reader
->ctxt
->wellFormed
= 0;
864 if (reader
->ctxt
->wellFormed
== 0)
867 s
= xmlBufUse(inbuf
) - reader
->cur
;
868 val
= xmlParseChunk(reader
->ctxt
,
869 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
873 reader
->ctxt
->wellFormed
= 0;
879 * Discard the consumed input when needed and possible
881 if (reader
->mode
== XML_TEXTREADER_MODE_INTERACTIVE
) {
882 if (alloc
!= XML_BUFFER_ALLOC_IMMUTABLE
) {
883 if ((reader
->cur
>= 4096) &&
884 (xmlBufUse(inbuf
) - reader
->cur
<= CHUNK_SIZE
)) {
885 val
= xmlBufShrink(inbuf
, reader
->cur
);
894 * At the end of the stream signal that the work is done to the Push
897 else if (reader
->mode
== XML_TEXTREADER_MODE_EOF
) {
898 if (reader
->state
!= XML_TEXTREADER_DONE
) {
899 s
= xmlBufUse(inbuf
) - reader
->cur
;
900 val
= xmlParseChunk(reader
->ctxt
,
901 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
903 reader
->cur
= xmlBufUse(inbuf
);
904 reader
->state
= XML_TEXTREADER_DONE
;
906 if (reader
->ctxt
->wellFormed
)
907 reader
->ctxt
->wellFormed
= 0;
913 reader
->state
= oldstate
;
914 if (reader
->ctxt
->wellFormed
== 0) {
915 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
922 #ifdef LIBXML_REGEXP_ENABLED
924 * xmlTextReaderValidatePush:
925 * @reader: the xmlTextReaderPtr used
927 * Push the current node for validation
930 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
) {
931 xmlNodePtr node
= reader
->node
;
933 #ifdef LIBXML_VALID_ENABLED
934 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
935 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
936 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
937 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
938 reader
->ctxt
->myDoc
, node
, node
->name
);
940 /* TODO use the BuildQName interface */
943 qname
= xmlStrdup(node
->ns
->prefix
);
944 qname
= xmlStrcat(qname
, BAD_CAST
":");
945 qname
= xmlStrcat(qname
, node
->name
);
946 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
947 reader
->ctxt
->myDoc
, node
, qname
);
952 #endif /* LIBXML_VALID_ENABLED */
953 #ifdef LIBXML_SCHEMAS_ENABLED
954 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
955 (reader
->rngValidCtxt
!= NULL
)) {
958 if (reader
->rngFullNode
!= NULL
) return;
959 ret
= xmlRelaxNGValidatePushElement(reader
->rngValidCtxt
,
964 * this element requires a full tree
966 node
= xmlTextReaderExpand(reader
);
968 printf("Expand failed !\n");
971 ret
= xmlRelaxNGValidateFullElement(reader
->rngValidCtxt
,
974 reader
->rngFullNode
= node
;
978 reader
->rngValidErrors
++;
984 * xmlTextReaderValidateCData:
985 * @reader: the xmlTextReaderPtr used
986 * @data: pointer to the CData
987 * @len: length of the CData block in bytes.
989 * Push some CData for validation
992 xmlTextReaderValidateCData(xmlTextReaderPtr reader
,
993 const xmlChar
*data
, int len
) {
994 #ifdef LIBXML_VALID_ENABLED
995 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
996 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
997 reader
->ctxt
->valid
&= xmlValidatePushCData(&reader
->ctxt
->vctxt
,
1000 #endif /* LIBXML_VALID_ENABLED */
1001 #ifdef LIBXML_SCHEMAS_ENABLED
1002 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1003 (reader
->rngValidCtxt
!= NULL
)) {
1006 if (reader
->rngFullNode
!= NULL
) return;
1007 ret
= xmlRelaxNGValidatePushCData(reader
->rngValidCtxt
, data
, len
);
1009 reader
->rngValidErrors
++;
1015 * xmlTextReaderValidatePop:
1016 * @reader: the xmlTextReaderPtr used
1018 * Pop the current node from validation
1021 xmlTextReaderValidatePop(xmlTextReaderPtr reader
) {
1022 xmlNodePtr node
= reader
->node
;
1024 #ifdef LIBXML_VALID_ENABLED
1025 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
1026 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
1027 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
1028 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1029 reader
->ctxt
->myDoc
, node
, node
->name
);
1031 /* TODO use the BuildQName interface */
1034 qname
= xmlStrdup(node
->ns
->prefix
);
1035 qname
= xmlStrcat(qname
, BAD_CAST
":");
1036 qname
= xmlStrcat(qname
, node
->name
);
1037 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1038 reader
->ctxt
->myDoc
, node
, qname
);
1043 #endif /* LIBXML_VALID_ENABLED */
1044 #ifdef LIBXML_SCHEMAS_ENABLED
1045 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1046 (reader
->rngValidCtxt
!= NULL
)) {
1049 if (reader
->rngFullNode
!= NULL
) {
1050 if (node
== reader
->rngFullNode
)
1051 reader
->rngFullNode
= NULL
;
1054 ret
= xmlRelaxNGValidatePopElement(reader
->rngValidCtxt
,
1055 reader
->ctxt
->myDoc
,
1058 reader
->rngValidErrors
++;
1064 * xmlTextReaderValidateEntity:
1065 * @reader: the xmlTextReaderPtr used
1067 * Handle the validation when an entity reference is encountered and
1068 * entity substitution is not activated. As a result the parser interface
1069 * must walk through the entity and do the validation calls
1072 xmlTextReaderValidateEntity(xmlTextReaderPtr reader
) {
1073 xmlNodePtr oldnode
= reader
->node
;
1074 xmlNodePtr node
= reader
->node
;
1075 xmlParserCtxtPtr ctxt
= reader
->ctxt
;
1078 if (node
->type
== XML_ENTITY_REF_NODE
) {
1080 * Case where the underlying tree is not availble, lookup the entity
1083 if ((node
->children
== NULL
) && (ctxt
->sax
!= NULL
) &&
1084 (ctxt
->sax
->getEntity
!= NULL
)) {
1085 node
->children
= (xmlNodePtr
)
1086 ctxt
->sax
->getEntity(ctxt
, node
->name
);
1089 if ((node
->children
!= NULL
) &&
1090 (node
->children
->type
== XML_ENTITY_DECL
) &&
1091 (node
->children
->children
!= NULL
)) {
1092 xmlTextReaderEntPush(reader
, node
);
1093 node
= node
->children
->children
;
1097 * The error has probably be raised already.
1099 if (node
== oldnode
)
1103 #ifdef LIBXML_REGEXP_ENABLED
1104 } else if (node
->type
== XML_ELEMENT_NODE
) {
1105 reader
->node
= node
;
1106 xmlTextReaderValidatePush(reader
);
1107 } else if ((node
->type
== XML_TEXT_NODE
) ||
1108 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1109 xmlTextReaderValidateCData(reader
, node
->content
,
1110 xmlStrlen(node
->content
));
1117 if (node
->children
!= NULL
) {
1118 node
= node
->children
;
1120 } else if (node
->type
== XML_ELEMENT_NODE
) {
1121 xmlTextReaderValidatePop(reader
);
1123 if (node
->next
!= NULL
) {
1128 node
= node
->parent
;
1129 if (node
->type
== XML_ELEMENT_NODE
) {
1131 if (reader
->entNr
== 0) {
1132 while ((tmp
= node
->last
) != NULL
) {
1133 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1135 xmlTextReaderFreeNode(reader
, tmp
);
1140 reader
->node
= node
;
1141 xmlTextReaderValidatePop(reader
);
1143 if ((node
->type
== XML_ENTITY_DECL
) &&
1144 (reader
->ent
!= NULL
) && (reader
->ent
->children
== node
)) {
1145 node
= xmlTextReaderEntPop(reader
);
1147 if (node
== oldnode
)
1149 if (node
->next
!= NULL
) {
1153 } while ((node
!= NULL
) && (node
!= oldnode
));
1154 } while ((node
!= NULL
) && (node
!= oldnode
));
1155 reader
->node
= oldnode
;
1157 #endif /* LIBXML_REGEXP_ENABLED */
1161 * xmlTextReaderGetSuccessor:
1162 * @cur: the current node
1164 * Get the successor of a node if available.
1166 * Returns the successor node or NULL
1169 xmlTextReaderGetSuccessor(xmlNodePtr cur
) {
1170 if (cur
== NULL
) return(NULL
) ; /* ERROR */
1171 if (cur
->next
!= NULL
) return(cur
->next
) ;
1174 if (cur
== NULL
) break;
1175 if (cur
->next
!= NULL
) return(cur
->next
);
1176 } while (cur
!= NULL
);
1181 * xmlTextReaderDoExpand:
1182 * @reader: the xmlTextReaderPtr used
1184 * Makes sure that the current node is fully read as well as all its
1185 * descendant. It means the full DOM subtree must be available at the
1188 * Returns 1 if the node was expanded successfully, 0 if there is no more
1189 * nodes to read, or -1 in case of error
1192 xmlTextReaderDoExpand(xmlTextReaderPtr reader
) {
1195 if ((reader
== NULL
) || (reader
->node
== NULL
) || (reader
->ctxt
== NULL
))
1198 if (reader
->ctxt
->instate
== XML_PARSER_EOF
) return(1);
1200 if (xmlTextReaderGetSuccessor(reader
->node
) != NULL
)
1202 if (reader
->ctxt
->nodeNr
< reader
->depth
)
1204 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1206 val
= xmlTextReaderPushData(reader
);
1208 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1211 } while(reader
->mode
!= XML_TEXTREADER_MODE_EOF
);
1216 * xmlTextReaderCollectSiblings:
1217 * @node: the first child
1219 * Traverse depth-first through all sibling nodes and their children
1220 * nodes and concatenate their content. This is an auxiliary function
1221 * to xmlTextReaderReadString.
1223 * Returns a string containing the content, or NULL in case of error.
1226 xmlTextReaderCollectSiblings(xmlNodePtr node
)
1228 xmlBufferPtr buffer
;
1231 if ((node
== NULL
) || (node
->type
== XML_NAMESPACE_DECL
))
1234 buffer
= xmlBufferCreate();
1238 for ( ; node
!= NULL
; node
= node
->next
) {
1239 switch (node
->type
) {
1241 case XML_CDATA_SECTION_NODE
:
1242 xmlBufferCat(buffer
, node
->content
);
1244 case XML_ELEMENT_NODE
: {
1247 tmp
= xmlTextReaderCollectSiblings(node
->children
);
1248 xmlBufferCat(buffer
, tmp
);
1256 ret
= buffer
->content
;
1257 buffer
->content
= NULL
;
1258 xmlBufferFree(buffer
);
1263 * xmlTextReaderRead:
1264 * @reader: the xmlTextReaderPtr used
1266 * Moves the position of the current instance to the next node in
1267 * the stream, exposing its properties.
1269 * Returns 1 if the node was read successfully, 0 if there is no more
1270 * nodes to read, or -1 in case of error
1273 xmlTextReaderRead(xmlTextReaderPtr reader
) {
1274 int val
, olddepth
= 0;
1275 xmlTextReaderState oldstate
= XML_TEXTREADER_START
;
1276 xmlNodePtr oldnode
= NULL
;
1281 reader
->curnode
= NULL
;
1282 if (reader
->doc
!= NULL
)
1283 return(xmlTextReaderReadTree(reader
));
1284 if (reader
->ctxt
== NULL
)
1288 fprintf(stderr
, "\nREAD ");
1291 if (reader
->mode
== XML_TEXTREADER_MODE_INITIAL
) {
1292 reader
->mode
= XML_TEXTREADER_MODE_INTERACTIVE
;
1297 val
= xmlTextReaderPushData(reader
);
1299 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1300 reader
->state
= XML_TEXTREADER_ERROR
;
1303 } while ((reader
->ctxt
->node
== NULL
) &&
1304 ((reader
->mode
!= XML_TEXTREADER_MODE_EOF
) &&
1305 (reader
->state
!= XML_TEXTREADER_DONE
)));
1306 if (reader
->ctxt
->node
== NULL
) {
1307 if (reader
->ctxt
->myDoc
!= NULL
) {
1308 reader
->node
= reader
->ctxt
->myDoc
->children
;
1310 if (reader
->node
== NULL
){
1311 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1312 reader
->state
= XML_TEXTREADER_ERROR
;
1315 reader
->state
= XML_TEXTREADER_ELEMENT
;
1317 if (reader
->ctxt
->myDoc
!= NULL
) {
1318 reader
->node
= reader
->ctxt
->myDoc
->children
;
1320 if (reader
->node
== NULL
)
1321 reader
->node
= reader
->ctxt
->nodeTab
[0];
1322 reader
->state
= XML_TEXTREADER_ELEMENT
;
1325 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
1328 oldstate
= reader
->state
;
1329 olddepth
= reader
->ctxt
->nodeNr
;
1330 oldnode
= reader
->node
;
1333 if (reader
->node
== NULL
) {
1334 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1341 * If we are not backtracking on ancestors or examined nodes,
1342 * that the parser didn't finished or that we arent at the end
1343 * of stream, continue processing.
1345 while ((reader
->node
!= NULL
) && (reader
->node
->next
== NULL
) &&
1346 (reader
->ctxt
->nodeNr
== olddepth
) &&
1347 ((oldstate
== XML_TEXTREADER_BACKTRACK
) ||
1348 (reader
->node
->children
== NULL
) ||
1349 (reader
->node
->type
== XML_ENTITY_REF_NODE
) ||
1350 ((reader
->node
->children
!= NULL
) &&
1351 (reader
->node
->children
->type
== XML_TEXT_NODE
) &&
1352 (reader
->node
->children
->next
== NULL
)) ||
1353 (reader
->node
->type
== XML_DTD_NODE
) ||
1354 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1355 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) &&
1356 ((reader
->ctxt
->node
== NULL
) ||
1357 (reader
->ctxt
->node
== reader
->node
) ||
1358 (reader
->ctxt
->node
== reader
->node
->parent
)) &&
1359 (reader
->ctxt
->instate
!= XML_PARSER_EOF
)) {
1360 val
= xmlTextReaderPushData(reader
);
1362 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1363 reader
->state
= XML_TEXTREADER_ERROR
;
1366 if (reader
->node
== NULL
)
1369 if (oldstate
!= XML_TEXTREADER_BACKTRACK
) {
1370 if ((reader
->node
->children
!= NULL
) &&
1371 (reader
->node
->type
!= XML_ENTITY_REF_NODE
) &&
1372 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1373 (reader
->node
->type
!= XML_DTD_NODE
)) {
1374 reader
->node
= reader
->node
->children
;
1376 reader
->state
= XML_TEXTREADER_ELEMENT
;
1380 if (reader
->node
->next
!= NULL
) {
1381 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1382 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1383 (reader
->node
->children
== NULL
) &&
1384 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)
1385 #ifdef LIBXML_XINCLUDE_ENABLED
1386 && (reader
->in_xinclude
<= 0)
1389 reader
->state
= XML_TEXTREADER_END
;
1392 #ifdef LIBXML_REGEXP_ENABLED
1393 if ((reader
->validate
) &&
1394 (reader
->node
->type
== XML_ELEMENT_NODE
))
1395 xmlTextReaderValidatePop(reader
);
1396 #endif /* LIBXML_REGEXP_ENABLED */
1397 if ((reader
->preserves
> 0) &&
1398 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1399 reader
->preserves
--;
1400 reader
->node
= reader
->node
->next
;
1401 reader
->state
= XML_TEXTREADER_ELEMENT
;
1404 * Cleanup of the old node
1406 if ((reader
->preserves
== 0) &&
1407 #ifdef LIBXML_XINCLUDE_ENABLED
1408 (reader
->in_xinclude
== 0) &&
1410 (reader
->entNr
== 0) &&
1411 (reader
->node
->prev
!= NULL
) &&
1412 (reader
->node
->prev
->type
!= XML_DTD_NODE
)) {
1413 xmlNodePtr tmp
= reader
->node
->prev
;
1414 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1416 xmlTextReaderFreeNode(reader
, tmp
);
1422 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1423 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1424 (reader
->node
->children
== NULL
) &&
1425 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)) {;
1426 reader
->state
= XML_TEXTREADER_END
;
1429 #ifdef LIBXML_REGEXP_ENABLED
1430 if ((reader
->validate
) && (reader
->node
->type
== XML_ELEMENT_NODE
))
1431 xmlTextReaderValidatePop(reader
);
1432 #endif /* LIBXML_REGEXP_ENABLED */
1433 if ((reader
->preserves
> 0) &&
1434 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1435 reader
->preserves
--;
1436 reader
->node
= reader
->node
->parent
;
1437 if ((reader
->node
== NULL
) ||
1438 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1439 #ifdef LIBXML_DOCB_ENABLED
1440 (reader
->node
->type
== XML_DOCB_DOCUMENT_NODE
) ||
1442 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) {
1443 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
1444 val
= xmlParseChunk(reader
->ctxt
, "", 0, 1);
1445 reader
->state
= XML_TEXTREADER_DONE
;
1449 reader
->node
= NULL
;
1453 * Cleanup of the old node
1455 if ((oldnode
!= NULL
) && (reader
->preserves
== 0) &&
1456 #ifdef LIBXML_XINCLUDE_ENABLED
1457 (reader
->in_xinclude
== 0) &&
1459 (reader
->entNr
== 0) &&
1460 (oldnode
->type
!= XML_DTD_NODE
) &&
1461 ((oldnode
->extra
& NODE_IS_PRESERVED
) == 0)) {
1462 xmlUnlinkNode(oldnode
);
1463 xmlTextReaderFreeNode(reader
, oldnode
);
1468 if ((reader
->preserves
== 0) &&
1469 #ifdef LIBXML_XINCLUDE_ENABLED
1470 (reader
->in_xinclude
== 0) &&
1472 (reader
->entNr
== 0) &&
1473 (reader
->node
->last
!= NULL
) &&
1474 ((reader
->node
->last
->extra
& NODE_IS_PRESERVED
) == 0)) {
1475 xmlNodePtr tmp
= reader
->node
->last
;
1477 xmlTextReaderFreeNode(reader
, tmp
);
1480 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1486 * If we are in the middle of a piece of CDATA make sure it's finished
1488 if ((reader
->node
!= NULL
) &&
1489 (reader
->node
->next
== NULL
) &&
1490 ((reader
->node
->type
== XML_TEXT_NODE
) ||
1491 (reader
->node
->type
== XML_CDATA_SECTION_NODE
))) {
1492 if (xmlTextReaderExpand(reader
) == NULL
)
1496 #ifdef LIBXML_XINCLUDE_ENABLED
1498 * Handle XInclude if asked for
1500 if ((reader
->xinclude
) && (reader
->node
!= NULL
) &&
1501 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1502 (reader
->node
->ns
!= NULL
) &&
1503 ((xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_NS
)) ||
1504 (xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_OLD_NS
)))) {
1505 if (reader
->xincctxt
== NULL
) {
1506 reader
->xincctxt
= xmlXIncludeNewContext(reader
->ctxt
->myDoc
);
1507 xmlXIncludeSetFlags(reader
->xincctxt
,
1508 reader
->parserFlags
& (~XML_PARSE_NOXINCNODE
));
1511 * expand that node and process it
1513 if (xmlTextReaderExpand(reader
) == NULL
)
1515 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1517 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1518 reader
->in_xinclude
++;
1521 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1522 reader
->in_xinclude
--;
1527 * Handle entities enter and exit when in entity replacement mode
1529 if ((reader
->node
!= NULL
) &&
1530 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1531 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1533 * Case where the underlying tree is not availble, lookup the entity
1536 if ((reader
->node
->children
== NULL
) && (reader
->ctxt
->sax
!= NULL
) &&
1537 (reader
->ctxt
->sax
->getEntity
!= NULL
)) {
1538 reader
->node
->children
= (xmlNodePtr
)
1539 reader
->ctxt
->sax
->getEntity(reader
->ctxt
, reader
->node
->name
);
1542 if ((reader
->node
->children
!= NULL
) &&
1543 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1544 (reader
->node
->children
->children
!= NULL
)) {
1545 xmlTextReaderEntPush(reader
, reader
->node
);
1546 reader
->node
= reader
->node
->children
->children
;
1548 #ifdef LIBXML_REGEXP_ENABLED
1549 } else if ((reader
->node
!= NULL
) &&
1550 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1551 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1552 xmlTextReaderValidateEntity(reader
);
1553 #endif /* LIBXML_REGEXP_ENABLED */
1555 if ((reader
->node
!= NULL
) &&
1556 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1557 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1558 reader
->node
= xmlTextReaderEntPop(reader
);
1562 #ifdef LIBXML_REGEXP_ENABLED
1563 if ((reader
->validate
) && (reader
->node
!= NULL
)) {
1564 xmlNodePtr node
= reader
->node
;
1566 if ((node
->type
== XML_ELEMENT_NODE
) &&
1567 ((reader
->state
!= XML_TEXTREADER_END
) &&
1568 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1569 xmlTextReaderValidatePush(reader
);
1570 } else if ((node
->type
== XML_TEXT_NODE
) ||
1571 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1572 xmlTextReaderValidateCData(reader
, node
->content
,
1573 xmlStrlen(node
->content
));
1576 #endif /* LIBXML_REGEXP_ENABLED */
1577 #ifdef LIBXML_PATTERN_ENABLED
1578 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1579 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1581 for (i
= 0;i
< reader
->patternNr
;i
++) {
1582 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1583 xmlTextReaderPreserve(reader
);
1588 #endif /* LIBXML_PATTERN_ENABLED */
1589 #ifdef LIBXML_SCHEMAS_ENABLED
1590 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1591 (reader
->xsdValidErrors
== 0) &&
1592 (reader
->xsdValidCtxt
!= NULL
)) {
1593 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1595 #endif /* LIBXML_PATTERN_ENABLED */
1598 reader
->state
= XML_TEXTREADER_DONE
;
1603 * xmlTextReaderReadState:
1604 * @reader: the xmlTextReaderPtr used
1606 * Gets the read state of the reader.
1608 * Returns the state value, or -1 in case of error
1611 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1614 return(reader
->mode
);
1618 * xmlTextReaderExpand:
1619 * @reader: the xmlTextReaderPtr used
1621 * Reads the contents of the current node and the full subtree. It then makes
1622 * the subtree available until the next xmlTextReaderRead() call
1624 * Returns a node pointer valid until the next xmlTextReaderRead() call
1625 * or NULL in case of error.
1628 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1629 if ((reader
== NULL
) || (reader
->node
== NULL
))
1631 if (reader
->doc
!= NULL
)
1632 return(reader
->node
);
1633 if (reader
->ctxt
== NULL
)
1635 if (xmlTextReaderDoExpand(reader
) < 0)
1637 return(reader
->node
);
1641 * xmlTextReaderNext:
1642 * @reader: the xmlTextReaderPtr used
1644 * Skip to the node following the current one in document order while
1645 * avoiding the subtree if any.
1647 * Returns 1 if the node was read successfully, 0 if there is no more
1648 * nodes to read, or -1 in case of error
1651 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1657 if (reader
->doc
!= NULL
)
1658 return(xmlTextReaderNextTree(reader
));
1660 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1661 return(xmlTextReaderRead(reader
));
1662 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1663 return(xmlTextReaderRead(reader
));
1664 if (cur
->extra
& NODE_IS_EMPTY
)
1665 return(xmlTextReaderRead(reader
));
1667 ret
= xmlTextReaderRead(reader
);
1670 } while (reader
->node
!= cur
);
1671 return(xmlTextReaderRead(reader
));
1674 #ifdef LIBXML_WRITER_ENABLED
1676 * xmlTextReaderReadInnerXml:
1677 * @reader: the xmlTextReaderPtr used
1679 * Reads the contents of the current node, including child nodes and markup.
1681 * Returns a string containing the XML content, or NULL if the current node
1682 * is neither an element nor attribute, or has no child nodes. The
1683 * string must be deallocated by the caller.
1686 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1689 xmlNodePtr node
, cur_node
;
1690 xmlBufferPtr buff
, buff2
;
1693 if (xmlTextReaderExpand(reader
) == NULL
) {
1697 buff
= xmlBufferCreate();
1698 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1699 cur_node
= cur_node
->next
) {
1700 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1701 buff2
= xmlBufferCreate();
1702 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1704 xmlBufferFree(buff2
);
1705 xmlBufferFree(buff
);
1708 xmlBufferCat(buff
, buff2
->content
);
1710 xmlBufferFree(buff2
);
1712 resbuf
= buff
->content
;
1713 buff
->content
= NULL
;
1715 xmlBufferFree(buff
);
1720 #ifdef LIBXML_WRITER_ENABLED
1722 * xmlTextReaderReadOuterXml:
1723 * @reader: the xmlTextReaderPtr used
1725 * Reads the contents of the current node, including child nodes and markup.
1727 * Returns a string containing the node and any XML content, or NULL if the
1728 * current node cannot be serialized. The string must be deallocated
1732 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1739 node
= reader
->node
;
1741 if (xmlTextReaderExpand(reader
) == NULL
) {
1744 if (node
->type
== XML_DTD_NODE
) {
1745 node
= (xmlNodePtr
) xmlCopyDtd((xmlDtdPtr
) node
);
1747 node
= xmlDocCopyNode(node
, doc
, 1);
1749 buff
= xmlBufferCreate();
1750 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1752 xmlBufferFree(buff
);
1756 resbuf
= buff
->content
;
1757 buff
->content
= NULL
;
1760 xmlBufferFree(buff
);
1766 * xmlTextReaderReadString:
1767 * @reader: the xmlTextReaderPtr used
1769 * Reads the contents of an element or a text node as a string.
1771 * Returns a string containing the contents of the Element or Text node,
1772 * or NULL if the reader is positioned on any other type of node.
1773 * The string must be deallocated by the caller.
1776 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1780 if ((reader
== NULL
) || (reader
->node
== NULL
))
1783 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1784 switch (node
->type
) {
1786 if (node
->content
!= NULL
)
1787 return(xmlStrdup(node
->content
));
1789 case XML_ELEMENT_NODE
:
1790 if (xmlTextReaderDoExpand(reader
) != -1) {
1791 return xmlTextReaderCollectSiblings(node
->children
);
1793 case XML_ATTRIBUTE_NODE
:
1804 * xmlTextReaderReadBase64:
1805 * @reader: the xmlTextReaderPtr used
1806 * @array: a byte array to store the content.
1807 * @offset: the zero-based index into array where the method should
1809 * @len: the number of bytes to write.
1811 * Reads and decodes the Base64 encoded contents of an element and
1812 * stores the result in a byte buffer.
1814 * Returns the number of bytes written to array, or zero if the current
1815 * instance is not positioned on an element or -1 in case of error.
1818 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1819 unsigned char *array ATTRIBUTE_UNUSED
,
1820 int offset ATTRIBUTE_UNUSED
,
1821 int len ATTRIBUTE_UNUSED
) {
1822 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1824 if (reader
->ctxt
->wellFormed
!= 1)
1827 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1834 * xmlTextReaderReadBinHex:
1835 * @reader: the xmlTextReaderPtr used
1836 * @array: a byte array to store the content.
1837 * @offset: the zero-based index into array where the method should
1839 * @len: the number of bytes to write.
1841 * Reads and decodes the BinHex encoded contents of an element and
1842 * stores the result in a byte buffer.
1844 * Returns the number of bytes written to array, or zero if the current
1845 * instance is not positioned on an element or -1 in case of error.
1848 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1849 unsigned char *array ATTRIBUTE_UNUSED
,
1850 int offset ATTRIBUTE_UNUSED
,
1851 int len ATTRIBUTE_UNUSED
) {
1852 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1854 if (reader
->ctxt
->wellFormed
!= 1)
1857 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1864 /************************************************************************
1866 * Operating on a preparsed tree *
1868 ************************************************************************/
1870 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1875 if (reader
->state
== XML_TEXTREADER_END
)
1878 if (reader
->node
== NULL
) {
1879 if (reader
->doc
->children
== NULL
) {
1880 reader
->state
= XML_TEXTREADER_END
;
1884 reader
->node
= reader
->doc
->children
;
1885 reader
->state
= XML_TEXTREADER_START
;
1889 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1890 /* Here removed traversal to child, because we want to skip the subtree,
1891 replace with traversal to sibling to skip subtree */
1892 if (reader
->node
->next
!= 0) {
1893 /* Move to sibling if present,skipping sub-tree */
1894 reader
->node
= reader
->node
->next
;
1895 reader
->state
= XML_TEXTREADER_START
;
1899 /* if reader->node->next is NULL mean no subtree for current node,
1900 so need to move to sibling of parent node if present */
1901 if ((reader
->node
->type
== XML_ELEMENT_NODE
) ||
1902 (reader
->node
->type
== XML_ATTRIBUTE_NODE
)) {
1903 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1904 /* This will move to parent if present */
1905 xmlTextReaderRead(reader
);
1909 if (reader
->node
->next
!= 0) {
1910 reader
->node
= reader
->node
->next
;
1911 reader
->state
= XML_TEXTREADER_START
;
1915 if (reader
->node
->parent
!= 0) {
1916 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1917 reader
->state
= XML_TEXTREADER_END
;
1921 reader
->node
= reader
->node
->parent
;
1923 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1924 /* Repeat process to move to sibling of parent node if present */
1925 xmlTextReaderNextTree(reader
);
1928 reader
->state
= XML_TEXTREADER_END
;
1934 * xmlTextReaderReadTree:
1935 * @reader: the xmlTextReaderPtr used
1937 * Moves the position of the current instance to the next node in
1938 * the stream, exposing its properties.
1940 * Returns 1 if the node was read successfully, 0 if there is no more
1941 * nodes to read, or -1 in case of error
1944 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1945 if (reader
->state
== XML_TEXTREADER_END
)
1949 if (reader
->node
== NULL
) {
1950 if (reader
->doc
->children
== NULL
) {
1951 reader
->state
= XML_TEXTREADER_END
;
1955 reader
->node
= reader
->doc
->children
;
1956 reader
->state
= XML_TEXTREADER_START
;
1960 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1961 (reader
->node
->type
!= XML_DTD_NODE
) &&
1962 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1963 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1964 if (reader
->node
->children
!= NULL
) {
1965 reader
->node
= reader
->node
->children
;
1967 reader
->state
= XML_TEXTREADER_START
;
1971 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1972 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1977 if (reader
->node
->next
!= NULL
) {
1978 reader
->node
= reader
->node
->next
;
1979 reader
->state
= XML_TEXTREADER_START
;
1983 if (reader
->node
->parent
!= NULL
) {
1984 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
1985 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
1986 reader
->state
= XML_TEXTREADER_END
;
1990 reader
->node
= reader
->node
->parent
;
1992 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1996 reader
->state
= XML_TEXTREADER_END
;
1999 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
2000 (reader
->node
->type
== XML_XINCLUDE_END
))
2007 * xmlTextReaderNextSibling:
2008 * @reader: the xmlTextReaderPtr used
2010 * Skip to the node following the current one in document order while
2011 * avoiding the subtree if any.
2012 * Currently implemented only for Readers built on a document
2014 * Returns 1 if the node was read successfully, 0 if there is no more
2015 * nodes to read, or -1 in case of error
2018 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
2021 if (reader
->doc
== NULL
) {
2026 if (reader
->state
== XML_TEXTREADER_END
)
2029 if (reader
->node
== NULL
)
2030 return(xmlTextReaderNextTree(reader
));
2032 if (reader
->node
->next
!= NULL
) {
2033 reader
->node
= reader
->node
->next
;
2034 reader
->state
= XML_TEXTREADER_START
;
2041 /************************************************************************
2043 * Constructor and destructors *
2045 ************************************************************************/
2048 * @input: the xmlParserInputBufferPtr used to read data
2049 * @URI: the URI information for the source if available
2051 * Create an xmlTextReader structure fed with @input
2053 * Returns the new xmlTextReaderPtr or NULL in case of error
2056 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2057 xmlTextReaderPtr ret
;
2061 ret
= xmlMalloc(sizeof(xmlTextReader
));
2063 xmlGenericError(xmlGenericErrorContext
,
2064 "xmlNewTextReader : malloc failed\n");
2067 memset(ret
, 0, sizeof(xmlTextReader
));
2073 ret
->buffer
= xmlBufCreateSize(100);
2074 if (ret
->buffer
== NULL
) {
2076 xmlGenericError(xmlGenericErrorContext
,
2077 "xmlNewTextReader : malloc failed\n");
2080 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2081 if (ret
->sax
== NULL
) {
2082 xmlBufFree(ret
->buffer
);
2084 xmlGenericError(xmlGenericErrorContext
,
2085 "xmlNewTextReader : malloc failed\n");
2088 xmlSAXVersion(ret
->sax
, 2);
2089 ret
->startElement
= ret
->sax
->startElement
;
2090 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2091 ret
->endElement
= ret
->sax
->endElement
;
2092 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2093 #ifdef LIBXML_SAX1_ENABLED
2094 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2095 #endif /* LIBXML_SAX1_ENABLED */
2096 ret
->startElementNs
= ret
->sax
->startElementNs
;
2097 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2098 ret
->endElementNs
= ret
->sax
->endElementNs
;
2099 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2100 #ifdef LIBXML_SAX1_ENABLED
2102 ret
->startElementNs
= NULL
;
2103 ret
->endElementNs
= NULL
;
2105 #endif /* LIBXML_SAX1_ENABLED */
2106 ret
->characters
= ret
->sax
->characters
;
2107 ret
->sax
->characters
= xmlTextReaderCharacters
;
2108 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2109 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2110 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2112 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2114 ret
->curnode
= NULL
;
2115 if (xmlBufUse(ret
->input
->buffer
) < 4) {
2116 xmlParserInputBufferRead(input
, 4);
2118 if (xmlBufUse(ret
->input
->buffer
) >= 4) {
2119 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2120 (const char *) xmlBufContent(ret
->input
->buffer
),
2125 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2130 if (ret
->ctxt
== NULL
) {
2131 xmlGenericError(xmlGenericErrorContext
,
2132 "xmlNewTextReader : malloc failed\n");
2133 xmlBufFree(ret
->buffer
);
2138 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2139 ret
->ctxt
->_private
= ret
;
2140 ret
->ctxt
->linenumbers
= 1;
2141 ret
->ctxt
->dictNames
= 1;
2142 ret
->allocs
= XML_TEXTREADER_CTXT
;
2144 * use the parser dictionnary to allocate all elements and attributes names
2146 ret
->ctxt
->docdict
= 1;
2147 ret
->dict
= ret
->ctxt
->dict
;
2148 #ifdef LIBXML_XINCLUDE_ENABLED
2151 #ifdef LIBXML_PATTERN_ENABLED
2152 ret
->patternMax
= 0;
2153 ret
->patternTab
= NULL
;
2159 * xmlNewTextReaderFilename:
2160 * @URI: the URI of the resource to process
2162 * Create an xmlTextReader structure fed with the resource at @URI
2164 * Returns the new xmlTextReaderPtr or NULL in case of error
2167 xmlNewTextReaderFilename(const char *URI
) {
2168 xmlParserInputBufferPtr input
;
2169 xmlTextReaderPtr ret
;
2170 char *directory
= NULL
;
2172 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2175 ret
= xmlNewTextReader(input
, URI
);
2177 xmlFreeParserInputBuffer(input
);
2180 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2181 if (ret
->ctxt
->directory
== NULL
)
2182 directory
= xmlParserGetDirectory(URI
);
2183 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2184 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2185 if (directory
!= NULL
)
2191 * xmlFreeTextReader:
2192 * @reader: the xmlTextReaderPtr
2194 * Deallocate all the resources associated to the reader
2197 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2200 #ifdef LIBXML_SCHEMAS_ENABLED
2201 if (reader
->rngSchemas
!= NULL
) {
2202 xmlRelaxNGFree(reader
->rngSchemas
);
2203 reader
->rngSchemas
= NULL
;
2205 if (reader
->rngValidCtxt
!= NULL
) {
2206 if (! reader
->rngPreserveCtxt
)
2207 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2208 reader
->rngValidCtxt
= NULL
;
2210 if (reader
->xsdPlug
!= NULL
) {
2211 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2212 reader
->xsdPlug
= NULL
;
2214 if (reader
->xsdValidCtxt
!= NULL
) {
2215 if (! reader
->xsdPreserveCtxt
)
2216 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2217 reader
->xsdValidCtxt
= NULL
;
2219 if (reader
->xsdSchemas
!= NULL
) {
2220 xmlSchemaFree(reader
->xsdSchemas
);
2221 reader
->xsdSchemas
= NULL
;
2224 #ifdef LIBXML_XINCLUDE_ENABLED
2225 if (reader
->xincctxt
!= NULL
)
2226 xmlXIncludeFreeContext(reader
->xincctxt
);
2228 #ifdef LIBXML_PATTERN_ENABLED
2229 if (reader
->patternTab
!= NULL
) {
2231 for (i
= 0;i
< reader
->patternNr
;i
++) {
2232 if (reader
->patternTab
[i
] != NULL
)
2233 xmlFreePattern(reader
->patternTab
[i
]);
2235 xmlFree(reader
->patternTab
);
2238 if (reader
->faketext
!= NULL
) {
2239 xmlFreeNode(reader
->faketext
);
2241 if (reader
->ctxt
!= NULL
) {
2242 if (reader
->dict
== reader
->ctxt
->dict
)
2243 reader
->dict
= NULL
;
2244 if (reader
->ctxt
->myDoc
!= NULL
) {
2245 if (reader
->preserve
== 0)
2246 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2247 reader
->ctxt
->myDoc
= NULL
;
2249 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2250 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2251 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2252 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2253 reader
->ctxt
->vctxt
.vstateMax
= 0;
2255 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2256 xmlFreeParserCtxt(reader
->ctxt
);
2258 if (reader
->sax
!= NULL
)
2259 xmlFree(reader
->sax
);
2260 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
))
2261 xmlFreeParserInputBuffer(reader
->input
);
2262 if (reader
->buffer
!= NULL
)
2263 xmlBufFree(reader
->buffer
);
2264 if (reader
->entTab
!= NULL
)
2265 xmlFree(reader
->entTab
);
2266 if (reader
->dict
!= NULL
)
2267 xmlDictFree(reader
->dict
);
2271 /************************************************************************
2273 * Methods for XmlTextReader *
2275 ************************************************************************/
2277 * xmlTextReaderClose:
2278 * @reader: the xmlTextReaderPtr used
2280 * This method releases any resources allocated by the current instance
2281 * changes the state to Closed and close any underlying input.
2283 * Returns 0 or -1 in case of error
2286 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2289 reader
->node
= NULL
;
2290 reader
->curnode
= NULL
;
2291 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2292 if (reader
->ctxt
!= NULL
) {
2293 xmlStopParser(reader
->ctxt
);
2294 if (reader
->ctxt
->myDoc
!= NULL
) {
2295 if (reader
->preserve
== 0)
2296 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2297 reader
->ctxt
->myDoc
= NULL
;
2300 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2301 xmlFreeParserInputBuffer(reader
->input
);
2302 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2308 * xmlTextReaderGetAttributeNo:
2309 * @reader: the xmlTextReaderPtr used
2310 * @no: the zero-based index of the attribute relative to the containing element
2312 * Provides the value of the attribute with the specified index relative
2313 * to the containing element.
2315 * Returns a string containing the value of the specified attribute, or NULL
2316 * in case of error. The string must be deallocated by the caller.
2319 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2327 if (reader
->node
== NULL
)
2329 if (reader
->curnode
!= NULL
)
2331 /* TODO: handle the xmlDecl */
2332 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2335 ns
= reader
->node
->nsDef
;
2336 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2340 return(xmlStrdup(ns
->href
));
2342 cur
= reader
->node
->properties
;
2350 /* TODO walk the DTD if present */
2352 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2353 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2358 * xmlTextReaderGetAttribute:
2359 * @reader: the xmlTextReaderPtr used
2360 * @name: the qualified name of the attribute.
2362 * Provides the value of the attribute with the specified qualified name.
2364 * Returns a string containing the value of the specified attribute, or NULL
2365 * in case of error. The string must be deallocated by the caller.
2368 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2369 xmlChar
*prefix
= NULL
;
2372 xmlChar
*ret
= NULL
;
2374 if ((reader
== NULL
) || (name
== NULL
))
2376 if (reader
->node
== NULL
)
2378 if (reader
->curnode
!= NULL
)
2381 /* TODO: handle the xmlDecl */
2382 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2385 localname
= xmlSplitQName2(name
, &prefix
);
2386 if (localname
== NULL
) {
2388 * Namespace default decl
2390 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2391 ns
= reader
->node
->nsDef
;
2392 while (ns
!= NULL
) {
2393 if (ns
->prefix
== NULL
) {
2394 return(xmlStrdup(ns
->href
));
2400 return(xmlGetNoNsProp(reader
->node
, name
));
2404 * Namespace default decl
2406 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2407 ns
= reader
->node
->nsDef
;
2408 while (ns
!= NULL
) {
2409 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2410 ret
= xmlStrdup(ns
->href
);
2416 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2418 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2429 * xmlTextReaderGetAttributeNs:
2430 * @reader: the xmlTextReaderPtr used
2431 * @localName: the local name of the attribute.
2432 * @namespaceURI: the namespace URI of the attribute.
2434 * Provides the value of the specified attribute
2436 * Returns a string containing the value of the specified attribute, or NULL
2437 * in case of error. The string must be deallocated by the caller.
2440 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2441 const xmlChar
*namespaceURI
) {
2442 xmlChar
*prefix
= NULL
;
2445 if ((reader
== NULL
) || (localName
== NULL
))
2447 if (reader
->node
== NULL
)
2449 if (reader
->curnode
!= NULL
)
2452 /* TODO: handle the xmlDecl */
2453 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2456 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2457 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2458 prefix
= BAD_CAST localName
;
2460 ns
= reader
->node
->nsDef
;
2461 while (ns
!= NULL
) {
2462 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2463 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2464 return xmlStrdup(ns
->href
);
2471 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2475 * xmlTextReaderGetRemainder:
2476 * @reader: the xmlTextReaderPtr used
2478 * Method to get the remainder of the buffered XML. this method stops the
2479 * parser, set its state to End Of File and return the input stream with
2480 * what is left that the parser did not use.
2482 * The implementation is not good, the parser certainly procgressed past
2483 * what's left in reader->input, and there is an allocation problem. Best
2484 * would be to rewrite it differently.
2486 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2489 xmlParserInputBufferPtr
2490 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2491 xmlParserInputBufferPtr ret
= NULL
;
2495 if (reader
->node
== NULL
)
2498 reader
->node
= NULL
;
2499 reader
->curnode
= NULL
;
2500 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2501 if (reader
->ctxt
!= NULL
) {
2502 xmlStopParser(reader
->ctxt
);
2503 if (reader
->ctxt
->myDoc
!= NULL
) {
2504 if (reader
->preserve
== 0)
2505 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2506 reader
->ctxt
->myDoc
= NULL
;
2509 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2510 ret
= reader
->input
;
2511 reader
->input
= NULL
;
2512 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2515 * Hum, one may need to duplicate the data structure because
2516 * without reference counting the input may be freed twice:
2517 * - by the layer which allocated it.
2518 * - by the layer to which would have been returned to.
2527 * xmlTextReaderLookupNamespace:
2528 * @reader: the xmlTextReaderPtr used
2529 * @prefix: the prefix whose namespace URI is to be resolved. To return
2530 * the default namespace, specify NULL
2532 * Resolves a namespace prefix in the scope of the current element.
2534 * Returns a string containing the namespace URI to which the prefix maps
2535 * or NULL in case of error. The string must be deallocated by the caller.
2538 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2543 if (reader
->node
== NULL
)
2546 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2549 return(xmlStrdup(ns
->href
));
2553 * xmlTextReaderMoveToAttributeNo:
2554 * @reader: the xmlTextReaderPtr used
2555 * @no: the zero-based index of the attribute relative to the containing
2558 * Moves the position of the current instance to the attribute with
2559 * the specified index relative to the containing element.
2561 * Returns 1 in case of success, -1 in case of error, 0 if not found
2564 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2571 if (reader
->node
== NULL
)
2573 /* TODO: handle the xmlDecl */
2574 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2577 reader
->curnode
= NULL
;
2579 ns
= reader
->node
->nsDef
;
2580 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2584 reader
->curnode
= (xmlNodePtr
) ns
;
2588 cur
= reader
->node
->properties
;
2596 /* TODO walk the DTD if present */
2598 reader
->curnode
= (xmlNodePtr
) cur
;
2603 * xmlTextReaderMoveToAttribute:
2604 * @reader: the xmlTextReaderPtr used
2605 * @name: the qualified name of the attribute.
2607 * Moves the position of the current instance to the attribute with
2608 * the specified qualified name.
2610 * Returns 1 in case of success, -1 in case of error, 0 if not found
2613 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2614 xmlChar
*prefix
= NULL
;
2619 if ((reader
== NULL
) || (name
== NULL
))
2621 if (reader
->node
== NULL
)
2624 /* TODO: handle the xmlDecl */
2625 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2628 localname
= xmlSplitQName2(name
, &prefix
);
2629 if (localname
== NULL
) {
2631 * Namespace default decl
2633 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2634 ns
= reader
->node
->nsDef
;
2635 while (ns
!= NULL
) {
2636 if (ns
->prefix
== NULL
) {
2637 reader
->curnode
= (xmlNodePtr
) ns
;
2645 prop
= reader
->node
->properties
;
2646 while (prop
!= NULL
) {
2649 * - same attribute names
2650 * - and the attribute carrying that namespace
2652 if ((xmlStrEqual(prop
->name
, name
)) &&
2653 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2654 reader
->curnode
= (xmlNodePtr
) prop
;
2663 * Namespace default decl
2665 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2666 ns
= reader
->node
->nsDef
;
2667 while (ns
!= NULL
) {
2668 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2669 reader
->curnode
= (xmlNodePtr
) ns
;
2676 prop
= reader
->node
->properties
;
2677 while (prop
!= NULL
) {
2680 * - same attribute names
2681 * - and the attribute carrying that namespace
2683 if ((xmlStrEqual(prop
->name
, localname
)) &&
2684 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2685 reader
->curnode
= (xmlNodePtr
) prop
;
2691 if (localname
!= NULL
)
2698 if (localname
!= NULL
)
2706 * xmlTextReaderMoveToAttributeNs:
2707 * @reader: the xmlTextReaderPtr used
2708 * @localName: the local name of the attribute.
2709 * @namespaceURI: the namespace URI of the attribute.
2711 * Moves the position of the current instance to the attribute with the
2712 * specified local name and namespace URI.
2714 * Returns 1 in case of success, -1 in case of error, 0 if not found
2717 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2718 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2722 xmlChar
*prefix
= NULL
;
2724 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2726 if (reader
->node
== NULL
)
2728 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2730 node
= reader
->node
;
2732 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2733 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2734 prefix
= BAD_CAST localName
;
2736 ns
= reader
->node
->nsDef
;
2737 while (ns
!= NULL
) {
2738 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2739 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2740 reader
->curnode
= (xmlNodePtr
) ns
;
2748 prop
= node
->properties
;
2749 while (prop
!= NULL
) {
2752 * - same attribute names
2753 * - and the attribute carrying that namespace
2755 if (xmlStrEqual(prop
->name
, localName
) &&
2756 ((prop
->ns
!= NULL
) &&
2757 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2758 reader
->curnode
= (xmlNodePtr
) prop
;
2767 * xmlTextReaderMoveToFirstAttribute:
2768 * @reader: the xmlTextReaderPtr used
2770 * Moves the position of the current instance to the first attribute
2771 * associated with the current node.
2773 * Returns 1 in case of success, -1 in case of error, 0 if not found
2776 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2779 if (reader
->node
== NULL
)
2781 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2784 if (reader
->node
->nsDef
!= NULL
) {
2785 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2788 if (reader
->node
->properties
!= NULL
) {
2789 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2796 * xmlTextReaderMoveToNextAttribute:
2797 * @reader: the xmlTextReaderPtr used
2799 * Moves the position of the current instance to the next attribute
2800 * associated with the current node.
2802 * Returns 1 in case of success, -1 in case of error, 0 if not found
2805 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2808 if (reader
->node
== NULL
)
2810 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2812 if (reader
->curnode
== NULL
)
2813 return(xmlTextReaderMoveToFirstAttribute(reader
));
2815 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2816 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2817 if (ns
->next
!= NULL
) {
2818 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2821 if (reader
->node
->properties
!= NULL
) {
2822 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2826 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2827 (reader
->curnode
->next
!= NULL
)) {
2828 reader
->curnode
= reader
->curnode
->next
;
2835 * xmlTextReaderMoveToElement:
2836 * @reader: the xmlTextReaderPtr used
2838 * Moves the position of the current instance to the node that
2839 * contains the current Attribute node.
2841 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2844 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2847 if (reader
->node
== NULL
)
2849 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2851 if (reader
->curnode
!= NULL
) {
2852 reader
->curnode
= NULL
;
2859 * xmlTextReaderReadAttributeValue:
2860 * @reader: the xmlTextReaderPtr used
2862 * Parses an attribute value into one or more Text and EntityReference nodes.
2864 * Returns 1 in case of success, 0 if the reader was not positionned on an
2865 * ttribute node or all the attribute values have been read, or -1
2869 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2872 if (reader
->node
== NULL
)
2874 if (reader
->curnode
== NULL
)
2876 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2877 if (reader
->curnode
->children
== NULL
)
2879 reader
->curnode
= reader
->curnode
->children
;
2880 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2881 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2883 if (reader
->faketext
== NULL
) {
2884 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2887 if ((reader
->faketext
->content
!= NULL
) &&
2888 (reader
->faketext
->content
!=
2889 (xmlChar
*) &(reader
->faketext
->properties
)))
2890 xmlFree(reader
->faketext
->content
);
2891 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2893 reader
->curnode
= reader
->faketext
;
2895 if (reader
->curnode
->next
== NULL
)
2897 reader
->curnode
= reader
->curnode
->next
;
2903 * xmlTextReaderConstEncoding:
2904 * @reader: the xmlTextReaderPtr used
2906 * Determine the encoding of the document being read.
2908 * Returns a string containing the encoding of the document or NULL in
2909 * case of error. The string is deallocated with the reader.
2912 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2913 xmlDocPtr doc
= NULL
;
2916 if (reader
->doc
!= NULL
)
2918 else if (reader
->ctxt
!= NULL
)
2919 doc
= reader
->ctxt
->myDoc
;
2923 if (doc
->encoding
== NULL
)
2926 return(CONSTSTR(doc
->encoding
));
2930 /************************************************************************
2932 * Acces API to the current node *
2934 ************************************************************************/
2936 * xmlTextReaderAttributeCount:
2937 * @reader: the xmlTextReaderPtr used
2939 * Provides the number of attributes of the current node
2941 * Returns 0 i no attributes, -1 in case of error or the attribute count
2944 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2952 if (reader
->node
== NULL
)
2955 if (reader
->curnode
!= NULL
)
2956 node
= reader
->curnode
;
2958 node
= reader
->node
;
2960 if (node
->type
!= XML_ELEMENT_NODE
)
2962 if ((reader
->state
== XML_TEXTREADER_END
) ||
2963 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2966 attr
= node
->properties
;
2967 while (attr
!= NULL
) {
2972 while (ns
!= NULL
) {
2980 * xmlTextReaderNodeType:
2981 * @reader: the xmlTextReaderPtr used
2983 * Get the node type of the current node
2985 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2987 * Returns the xmlNodeType of the current node or -1 in case of error
2990 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
2995 if (reader
->node
== NULL
)
2996 return(XML_READER_TYPE_NONE
);
2997 if (reader
->curnode
!= NULL
)
2998 node
= reader
->curnode
;
3000 node
= reader
->node
;
3001 switch (node
->type
) {
3002 case XML_ELEMENT_NODE
:
3003 if ((reader
->state
== XML_TEXTREADER_END
) ||
3004 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
3005 return(XML_READER_TYPE_END_ELEMENT
);
3006 return(XML_READER_TYPE_ELEMENT
);
3007 case XML_NAMESPACE_DECL
:
3008 case XML_ATTRIBUTE_NODE
:
3009 return(XML_READER_TYPE_ATTRIBUTE
);
3011 if (xmlIsBlankNode(reader
->node
)) {
3012 if (xmlNodeGetSpacePreserve(reader
->node
))
3013 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
3015 return(XML_READER_TYPE_WHITESPACE
);
3017 return(XML_READER_TYPE_TEXT
);
3019 case XML_CDATA_SECTION_NODE
:
3020 return(XML_READER_TYPE_CDATA
);
3021 case XML_ENTITY_REF_NODE
:
3022 return(XML_READER_TYPE_ENTITY_REFERENCE
);
3023 case XML_ENTITY_NODE
:
3024 return(XML_READER_TYPE_ENTITY
);
3026 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
3027 case XML_COMMENT_NODE
:
3028 return(XML_READER_TYPE_COMMENT
);
3029 case XML_DOCUMENT_NODE
:
3030 case XML_HTML_DOCUMENT_NODE
:
3031 #ifdef LIBXML_DOCB_ENABLED
3032 case XML_DOCB_DOCUMENT_NODE
:
3034 return(XML_READER_TYPE_DOCUMENT
);
3035 case XML_DOCUMENT_FRAG_NODE
:
3036 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
3037 case XML_NOTATION_NODE
:
3038 return(XML_READER_TYPE_NOTATION
);
3039 case XML_DOCUMENT_TYPE_NODE
:
3041 return(XML_READER_TYPE_DOCUMENT_TYPE
);
3043 case XML_ELEMENT_DECL
:
3044 case XML_ATTRIBUTE_DECL
:
3045 case XML_ENTITY_DECL
:
3046 case XML_XINCLUDE_START
:
3047 case XML_XINCLUDE_END
:
3048 return(XML_READER_TYPE_NONE
);
3054 * xmlTextReaderIsEmptyElement:
3055 * @reader: the xmlTextReaderPtr used
3057 * Check if the current node is empty
3059 * Returns 1 if empty, 0 if not and -1 in case of error
3062 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3063 if ((reader
== NULL
) || (reader
->node
== NULL
))
3065 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3067 if (reader
->curnode
!= NULL
)
3069 if (reader
->node
->children
!= NULL
)
3071 if (reader
->state
== XML_TEXTREADER_END
)
3073 if (reader
->doc
!= NULL
)
3075 #ifdef LIBXML_XINCLUDE_ENABLED
3076 if (reader
->in_xinclude
> 0)
3079 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3083 * xmlTextReaderLocalName:
3084 * @reader: the xmlTextReaderPtr used
3086 * The local name of the node.
3088 * Returns the local name or NULL if not available,
3089 * if non NULL it need to be freed by the caller.
3092 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3094 if ((reader
== NULL
) || (reader
->node
== NULL
))
3096 if (reader
->curnode
!= NULL
)
3097 node
= reader
->curnode
;
3099 node
= reader
->node
;
3100 if (node
->type
== XML_NAMESPACE_DECL
) {
3101 xmlNsPtr ns
= (xmlNsPtr
) node
;
3102 if (ns
->prefix
== NULL
)
3103 return(xmlStrdup(BAD_CAST
"xmlns"));
3105 return(xmlStrdup(ns
->prefix
));
3107 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3108 (node
->type
!= XML_ATTRIBUTE_NODE
))
3109 return(xmlTextReaderName(reader
));
3110 return(xmlStrdup(node
->name
));
3114 * xmlTextReaderConstLocalName:
3115 * @reader: the xmlTextReaderPtr used
3117 * The local name of the node.
3119 * Returns the local name or NULL if not available, the
3120 * string will be deallocated with the reader.
3123 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3125 if ((reader
== NULL
) || (reader
->node
== NULL
))
3127 if (reader
->curnode
!= NULL
)
3128 node
= reader
->curnode
;
3130 node
= reader
->node
;
3131 if (node
->type
== XML_NAMESPACE_DECL
) {
3132 xmlNsPtr ns
= (xmlNsPtr
) node
;
3133 if (ns
->prefix
== NULL
)
3134 return(CONSTSTR(BAD_CAST
"xmlns"));
3138 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3139 (node
->type
!= XML_ATTRIBUTE_NODE
))
3140 return(xmlTextReaderConstName(reader
));
3145 * xmlTextReaderName:
3146 * @reader: the xmlTextReaderPtr used
3148 * The qualified name of the node, equal to Prefix :LocalName.
3150 * Returns the local name or NULL if not available,
3151 * if non NULL it need to be freed by the caller.
3154 xmlTextReaderName(xmlTextReaderPtr reader
) {
3158 if ((reader
== NULL
) || (reader
->node
== NULL
))
3160 if (reader
->curnode
!= NULL
)
3161 node
= reader
->curnode
;
3163 node
= reader
->node
;
3164 switch (node
->type
) {
3165 case XML_ELEMENT_NODE
:
3166 case XML_ATTRIBUTE_NODE
:
3167 if ((node
->ns
== NULL
) ||
3168 (node
->ns
->prefix
== NULL
))
3169 return(xmlStrdup(node
->name
));
3171 ret
= xmlStrdup(node
->ns
->prefix
);
3172 ret
= xmlStrcat(ret
, BAD_CAST
":");
3173 ret
= xmlStrcat(ret
, node
->name
);
3176 return(xmlStrdup(BAD_CAST
"#text"));
3177 case XML_CDATA_SECTION_NODE
:
3178 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3179 case XML_ENTITY_NODE
:
3180 case XML_ENTITY_REF_NODE
:
3181 return(xmlStrdup(node
->name
));
3183 return(xmlStrdup(node
->name
));
3184 case XML_COMMENT_NODE
:
3185 return(xmlStrdup(BAD_CAST
"#comment"));
3186 case XML_DOCUMENT_NODE
:
3187 case XML_HTML_DOCUMENT_NODE
:
3188 #ifdef LIBXML_DOCB_ENABLED
3189 case XML_DOCB_DOCUMENT_NODE
:
3191 return(xmlStrdup(BAD_CAST
"#document"));
3192 case XML_DOCUMENT_FRAG_NODE
:
3193 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3194 case XML_NOTATION_NODE
:
3195 return(xmlStrdup(node
->name
));
3196 case XML_DOCUMENT_TYPE_NODE
:
3198 return(xmlStrdup(node
->name
));
3199 case XML_NAMESPACE_DECL
: {
3200 xmlNsPtr ns
= (xmlNsPtr
) node
;
3202 ret
= xmlStrdup(BAD_CAST
"xmlns");
3203 if (ns
->prefix
== NULL
)
3205 ret
= xmlStrcat(ret
, BAD_CAST
":");
3206 ret
= xmlStrcat(ret
, ns
->prefix
);
3210 case XML_ELEMENT_DECL
:
3211 case XML_ATTRIBUTE_DECL
:
3212 case XML_ENTITY_DECL
:
3213 case XML_XINCLUDE_START
:
3214 case XML_XINCLUDE_END
:
3221 * xmlTextReaderConstName:
3222 * @reader: the xmlTextReaderPtr used
3224 * The qualified name of the node, equal to Prefix :LocalName.
3226 * Returns the local name or NULL if not available, the string is
3227 * deallocated with the reader.
3230 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3233 if ((reader
== NULL
) || (reader
->node
== NULL
))
3235 if (reader
->curnode
!= NULL
)
3236 node
= reader
->curnode
;
3238 node
= reader
->node
;
3239 switch (node
->type
) {
3240 case XML_ELEMENT_NODE
:
3241 case XML_ATTRIBUTE_NODE
:
3242 if ((node
->ns
== NULL
) ||
3243 (node
->ns
->prefix
== NULL
))
3245 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3247 return(CONSTSTR(BAD_CAST
"#text"));
3248 case XML_CDATA_SECTION_NODE
:
3249 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3250 case XML_ENTITY_NODE
:
3251 case XML_ENTITY_REF_NODE
:
3252 return(CONSTSTR(node
->name
));
3254 return(CONSTSTR(node
->name
));
3255 case XML_COMMENT_NODE
:
3256 return(CONSTSTR(BAD_CAST
"#comment"));
3257 case XML_DOCUMENT_NODE
:
3258 case XML_HTML_DOCUMENT_NODE
:
3259 #ifdef LIBXML_DOCB_ENABLED
3260 case XML_DOCB_DOCUMENT_NODE
:
3262 return(CONSTSTR(BAD_CAST
"#document"));
3263 case XML_DOCUMENT_FRAG_NODE
:
3264 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3265 case XML_NOTATION_NODE
:
3266 return(CONSTSTR(node
->name
));
3267 case XML_DOCUMENT_TYPE_NODE
:
3269 return(CONSTSTR(node
->name
));
3270 case XML_NAMESPACE_DECL
: {
3271 xmlNsPtr ns
= (xmlNsPtr
) node
;
3273 if (ns
->prefix
== NULL
)
3274 return(CONSTSTR(BAD_CAST
"xmlns"));
3275 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3278 case XML_ELEMENT_DECL
:
3279 case XML_ATTRIBUTE_DECL
:
3280 case XML_ENTITY_DECL
:
3281 case XML_XINCLUDE_START
:
3282 case XML_XINCLUDE_END
:
3289 * xmlTextReaderPrefix:
3290 * @reader: the xmlTextReaderPtr used
3292 * A shorthand reference to the namespace associated with the node.
3294 * Returns the prefix or NULL if not available,
3295 * if non NULL it need to be freed by the caller.
3298 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3300 if ((reader
== NULL
) || (reader
->node
== NULL
))
3302 if (reader
->curnode
!= NULL
)
3303 node
= reader
->curnode
;
3305 node
= reader
->node
;
3306 if (node
->type
== XML_NAMESPACE_DECL
) {
3307 xmlNsPtr ns
= (xmlNsPtr
) node
;
3308 if (ns
->prefix
== NULL
)
3310 return(xmlStrdup(BAD_CAST
"xmlns"));
3312 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3313 (node
->type
!= XML_ATTRIBUTE_NODE
))
3315 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3316 return(xmlStrdup(node
->ns
->prefix
));
3321 * xmlTextReaderConstPrefix:
3322 * @reader: the xmlTextReaderPtr used
3324 * A shorthand reference to the namespace associated with the node.
3326 * Returns the prefix or NULL if not available, the string is deallocated
3330 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3332 if ((reader
== NULL
) || (reader
->node
== NULL
))
3334 if (reader
->curnode
!= NULL
)
3335 node
= reader
->curnode
;
3337 node
= reader
->node
;
3338 if (node
->type
== XML_NAMESPACE_DECL
) {
3339 xmlNsPtr ns
= (xmlNsPtr
) node
;
3340 if (ns
->prefix
== NULL
)
3342 return(CONSTSTR(BAD_CAST
"xmlns"));
3344 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3345 (node
->type
!= XML_ATTRIBUTE_NODE
))
3347 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3348 return(CONSTSTR(node
->ns
->prefix
));
3353 * xmlTextReaderNamespaceUri:
3354 * @reader: the xmlTextReaderPtr used
3356 * The URI defining the namespace associated with the node.
3358 * Returns the namespace URI or NULL if not available,
3359 * if non NULL it need to be freed by the caller.
3362 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3364 if ((reader
== NULL
) || (reader
->node
== NULL
))
3366 if (reader
->curnode
!= NULL
)
3367 node
= reader
->curnode
;
3369 node
= reader
->node
;
3370 if (node
->type
== XML_NAMESPACE_DECL
)
3371 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3372 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3373 (node
->type
!= XML_ATTRIBUTE_NODE
))
3375 if (node
->ns
!= NULL
)
3376 return(xmlStrdup(node
->ns
->href
));
3381 * xmlTextReaderConstNamespaceUri:
3382 * @reader: the xmlTextReaderPtr used
3384 * The URI defining the namespace associated with the node.
3386 * Returns the namespace URI or NULL if not available, the string
3387 * will be deallocated with the reader
3390 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3392 if ((reader
== NULL
) || (reader
->node
== NULL
))
3394 if (reader
->curnode
!= NULL
)
3395 node
= reader
->curnode
;
3397 node
= reader
->node
;
3398 if (node
->type
== XML_NAMESPACE_DECL
)
3399 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3400 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3401 (node
->type
!= XML_ATTRIBUTE_NODE
))
3403 if (node
->ns
!= NULL
)
3404 return(CONSTSTR(node
->ns
->href
));
3409 * xmlTextReaderBaseUri:
3410 * @reader: the xmlTextReaderPtr used
3412 * The base URI of the node.
3414 * Returns the base URI or NULL if not available,
3415 * if non NULL it need to be freed by the caller.
3418 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3419 if ((reader
== NULL
) || (reader
->node
== NULL
))
3421 return(xmlNodeGetBase(NULL
, reader
->node
));
3425 * xmlTextReaderConstBaseUri:
3426 * @reader: the xmlTextReaderPtr used
3428 * The base URI of the node.
3430 * Returns the base URI or NULL if not available, the string
3431 * will be deallocated with the reader
3434 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3438 if ((reader
== NULL
) || (reader
->node
== NULL
))
3440 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3443 ret
= CONSTSTR(tmp
);
3449 * xmlTextReaderDepth:
3450 * @reader: the xmlTextReaderPtr used
3452 * The depth of the node in the tree.
3454 * Returns the depth or -1 in case of error
3457 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3460 if (reader
->node
== NULL
)
3463 if (reader
->curnode
!= NULL
) {
3464 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3465 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3466 return(reader
->depth
+ 1);
3467 return(reader
->depth
+ 2);
3469 return(reader
->depth
);
3473 * xmlTextReaderHasAttributes:
3474 * @reader: the xmlTextReaderPtr used
3476 * Whether the node has attributes.
3478 * Returns 1 if true, 0 if false, and -1 in case or error
3481 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3485 if (reader
->node
== NULL
)
3487 if (reader
->curnode
!= NULL
)
3488 node
= reader
->curnode
;
3490 node
= reader
->node
;
3492 if ((node
->type
== XML_ELEMENT_NODE
) &&
3493 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3495 /* TODO: handle the xmlDecl */
3500 * xmlTextReaderHasValue:
3501 * @reader: the xmlTextReaderPtr used
3503 * Whether the node can have a text value.
3505 * Returns 1 if true, 0 if false, and -1 in case or error
3508 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3512 if (reader
->node
== NULL
)
3514 if (reader
->curnode
!= NULL
)
3515 node
= reader
->curnode
;
3517 node
= reader
->node
;
3519 switch (node
->type
) {
3520 case XML_ATTRIBUTE_NODE
:
3522 case XML_CDATA_SECTION_NODE
:
3524 case XML_COMMENT_NODE
:
3525 case XML_NAMESPACE_DECL
:
3534 * xmlTextReaderValue:
3535 * @reader: the xmlTextReaderPtr used
3537 * Provides the text value of the node if present
3539 * Returns the string or NULL if not available. The result must be deallocated
3543 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3547 if (reader
->node
== NULL
)
3549 if (reader
->curnode
!= NULL
)
3550 node
= reader
->curnode
;
3552 node
= reader
->node
;
3554 switch (node
->type
) {
3555 case XML_NAMESPACE_DECL
:
3556 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3557 case XML_ATTRIBUTE_NODE
:{
3558 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3560 if (attr
->parent
!= NULL
)
3561 return (xmlNodeListGetString
3562 (attr
->parent
->doc
, attr
->children
, 1));
3564 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3568 case XML_CDATA_SECTION_NODE
:
3570 case XML_COMMENT_NODE
:
3571 if (node
->content
!= NULL
)
3572 return (xmlStrdup(node
->content
));
3580 * xmlTextReaderConstValue:
3581 * @reader: the xmlTextReaderPtr used
3583 * Provides the text value of the node if present
3585 * Returns the string or NULL if not available. The result will be
3586 * deallocated on the next Read() operation.
3589 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3593 if (reader
->node
== NULL
)
3595 if (reader
->curnode
!= NULL
)
3596 node
= reader
->curnode
;
3598 node
= reader
->node
;
3600 switch (node
->type
) {
3601 case XML_NAMESPACE_DECL
:
3602 return(((xmlNsPtr
) node
)->href
);
3603 case XML_ATTRIBUTE_NODE
:{
3604 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3606 if ((attr
->children
!= NULL
) &&
3607 (attr
->children
->type
== XML_TEXT_NODE
) &&
3608 (attr
->children
->next
== NULL
))
3609 return(attr
->children
->content
);
3611 if (reader
->buffer
== NULL
) {
3612 reader
->buffer
= xmlBufCreateSize(100);
3613 if (reader
->buffer
== NULL
) {
3614 xmlGenericError(xmlGenericErrorContext
,
3615 "xmlTextReaderSetup : malloc failed\n");
3619 xmlBufEmpty(reader
->buffer
);
3620 xmlBufGetNodeContent(reader
->buffer
, node
);
3621 return(xmlBufContent(reader
->buffer
));
3626 case XML_CDATA_SECTION_NODE
:
3628 case XML_COMMENT_NODE
:
3629 return(node
->content
);
3637 * xmlTextReaderIsDefault:
3638 * @reader: the xmlTextReaderPtr used
3640 * Whether an Attribute node was generated from the default value
3641 * defined in the DTD or schema.
3643 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3646 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3653 * xmlTextReaderQuoteChar:
3654 * @reader: the xmlTextReaderPtr used
3656 * The quotation mark character used to enclose the value of an attribute.
3658 * Returns " or ' and -1 in case of error
3661 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3664 /* TODO maybe lookup the attribute value for " first */
3669 * xmlTextReaderXmlLang:
3670 * @reader: the xmlTextReaderPtr used
3672 * The xml:lang scope within which the node resides.
3674 * Returns the xml:lang value or NULL if none exists.,
3675 * if non NULL it need to be freed by the caller.
3678 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3681 if (reader
->node
== NULL
)
3683 return(xmlNodeGetLang(reader
->node
));
3687 * xmlTextReaderConstXmlLang:
3688 * @reader: the xmlTextReaderPtr used
3690 * The xml:lang scope within which the node resides.
3692 * Returns the xml:lang value or NULL if none exists.
3695 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3701 if (reader
->node
== NULL
)
3703 tmp
= xmlNodeGetLang(reader
->node
);
3706 ret
= CONSTSTR(tmp
);
3712 * xmlTextReaderConstString:
3713 * @reader: the xmlTextReaderPtr used
3714 * @str: the string to intern.
3716 * Get an interned string from the reader, allows for example to
3717 * speedup string name comparisons
3719 * Returns an interned copy of the string or NULL in case of error. The
3720 * string will be deallocated with the reader.
3723 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3726 return(CONSTSTR(str
));
3730 * xmlTextReaderNormalization:
3731 * @reader: the xmlTextReaderPtr used
3733 * The value indicating whether to normalize white space and attribute values.
3734 * Since attribute value and end of line normalizations are a MUST in the XML
3735 * specification only the value true is accepted. The broken bahaviour of
3736 * accepting out of range character entities like � is of course not
3739 * Returns 1 or -1 in case of error.
3742 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3748 /************************************************************************
3750 * Extensions to the base APIs *
3752 ************************************************************************/
3755 * xmlTextReaderSetParserProp:
3756 * @reader: the xmlTextReaderPtr used
3757 * @prop: the xmlParserProperties to set
3758 * @value: usually 0 or 1 to (de)activate it
3760 * Change the parser processing behaviour by changing some of its internal
3761 * properties. Note that some properties can only be changed before any
3762 * read has been done.
3764 * Returns 0 if the call was successful, or -1 in case of error
3767 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3768 xmlParserProperties p
= (xmlParserProperties
) prop
;
3769 xmlParserCtxtPtr ctxt
;
3771 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3773 ctxt
= reader
->ctxt
;
3776 case XML_PARSER_LOADDTD
:
3778 if (ctxt
->loadsubset
== 0) {
3779 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3781 ctxt
->loadsubset
= XML_DETECT_IDS
;
3784 ctxt
->loadsubset
= 0;
3787 case XML_PARSER_DEFAULTATTRS
:
3789 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3791 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3792 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3795 case XML_PARSER_VALIDATE
:
3798 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3803 case XML_PARSER_SUBST_ENTITIES
:
3805 ctxt
->replaceEntities
= 1;
3807 ctxt
->replaceEntities
= 0;
3815 * xmlTextReaderGetParserProp:
3816 * @reader: the xmlTextReaderPtr used
3817 * @prop: the xmlParserProperties to get
3819 * Read the parser internal property.
3821 * Returns the value, usually 0 or 1, or -1 in case of error.
3824 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3825 xmlParserProperties p
= (xmlParserProperties
) prop
;
3826 xmlParserCtxtPtr ctxt
;
3828 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3830 ctxt
= reader
->ctxt
;
3833 case XML_PARSER_LOADDTD
:
3834 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3837 case XML_PARSER_DEFAULTATTRS
:
3838 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3841 case XML_PARSER_VALIDATE
:
3842 return(reader
->validate
);
3843 case XML_PARSER_SUBST_ENTITIES
:
3844 return(ctxt
->replaceEntities
);
3851 * xmlTextReaderGetParserLineNumber:
3852 * @reader: the user data (XML reader context)
3854 * Provide the line number of the current parsing point.
3856 * Returns an int or 0 if not available
3859 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3861 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3862 (reader
->ctxt
->input
== NULL
)) {
3865 return (reader
->ctxt
->input
->line
);
3869 * xmlTextReaderGetParserColumnNumber:
3870 * @reader: the user data (XML reader context)
3872 * Provide the column number of the current parsing point.
3874 * Returns an int or 0 if not available
3877 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3879 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3880 (reader
->ctxt
->input
== NULL
)) {
3883 return (reader
->ctxt
->input
->col
);
3887 * xmlTextReaderCurrentNode:
3888 * @reader: the xmlTextReaderPtr used
3890 * Hacking interface allowing to get the xmlNodePtr correponding to the
3891 * current node being accessed by the xmlTextReader. This is dangerous
3892 * because the underlying node may be destroyed on the next Reads.
3894 * Returns the xmlNodePtr or NULL in case of error.
3897 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3901 if (reader
->curnode
!= NULL
)
3902 return(reader
->curnode
);
3903 return(reader
->node
);
3907 * xmlTextReaderPreserve:
3908 * @reader: the xmlTextReaderPtr used
3910 * This tells the XML Reader to preserve the current node.
3911 * The caller must also use xmlTextReaderCurrentDoc() to
3912 * keep an handle on the resulting document once parsing has finished
3914 * Returns the xmlNodePtr or NULL in case of error.
3917 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3918 xmlNodePtr cur
, parent
;
3923 if (reader
->curnode
!= NULL
)
3924 cur
= reader
->curnode
;
3930 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3931 cur
->extra
|= NODE_IS_PRESERVED
;
3932 cur
->extra
|= NODE_IS_SPRESERVED
;
3934 reader
->preserves
++;
3936 parent
= cur
->parent
;;
3937 while (parent
!= NULL
) {
3938 if (parent
->type
== XML_ELEMENT_NODE
)
3939 parent
->extra
|= NODE_IS_PRESERVED
;
3940 parent
= parent
->parent
;
3945 #ifdef LIBXML_PATTERN_ENABLED
3947 * xmlTextReaderPreservePattern:
3948 * @reader: the xmlTextReaderPtr used
3949 * @pattern: an XPath subset pattern
3950 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3952 * This tells the XML Reader to preserve all nodes matched by the
3953 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3954 * keep an handle on the resulting document once parsing has finished
3956 * Returns a positive number in case of success and -1 in case of error
3959 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3960 const xmlChar
**namespaces
)
3964 if ((reader
== NULL
) || (pattern
== NULL
))
3967 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
3971 if (reader
->patternMax
<= 0) {
3972 reader
->patternMax
= 4;
3973 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
3974 sizeof(reader
->patternTab
[0]));
3975 if (reader
->patternTab
== NULL
) {
3976 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
3980 if (reader
->patternNr
>= reader
->patternMax
) {
3982 reader
->patternMax
*= 2;
3983 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
3984 reader
->patternMax
*
3985 sizeof(reader
->patternTab
[0]));
3987 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
3988 reader
->patternMax
/= 2;
3991 reader
->patternTab
= tmp
;
3993 reader
->patternTab
[reader
->patternNr
] = comp
;
3994 return(reader
->patternNr
++);
3999 * xmlTextReaderCurrentDoc:
4000 * @reader: the xmlTextReaderPtr used
4002 * Hacking interface allowing to get the xmlDocPtr correponding to the
4003 * current document being accessed by the xmlTextReader.
4004 * NOTE: as a result of this call, the reader will not destroy the
4005 * associated XML document and calling xmlFreeDoc() on the result
4006 * is needed once the reader parsing has finished.
4008 * Returns the xmlDocPtr or NULL in case of error.
4011 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
4014 if (reader
->doc
!= NULL
)
4015 return(reader
->doc
);
4016 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
4019 reader
->preserve
= 1;
4020 return(reader
->ctxt
->myDoc
);
4023 #ifdef LIBXML_SCHEMAS_ENABLED
4024 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
);
4026 static void XMLCDECL
4027 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...);
4029 static void XMLCDECL
4030 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...);
4032 static void XMLCDECL
4033 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
4035 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4042 str
= xmlTextReaderBuildMessage(msg
, ap
);
4043 if (!reader
->errorFunc
) {
4044 xmlTextReaderValidityError(ctx
, "%s", str
);
4046 reader
->errorFunc(reader
->errorFuncArg
, str
,
4047 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4048 NULL
/* locator */ );
4055 static void XMLCDECL
4056 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4058 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4065 str
= xmlTextReaderBuildMessage(msg
, ap
);
4066 if (!reader
->errorFunc
) {
4067 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4069 reader
->errorFunc(reader
->errorFuncArg
, str
,
4070 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4071 NULL
/* locator */ );
4079 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4082 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4084 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4086 if (reader
->sErrorFunc
) {
4087 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4089 xmlTextReaderStructuredError(reader
, error
);
4093 * xmlTextReaderRelaxNGSetSchema:
4094 * @reader: the xmlTextReaderPtr used
4095 * @schema: a precompiled RelaxNG schema
4097 * Use RelaxNG to validate the document as it is processed.
4098 * Activation is only possible before the first Read().
4099 * if @schema is NULL, then RelaxNG validation is desactivated.
4100 @ The @schema should not be freed until the reader is deallocated
4101 * or its use has been deactivated.
4103 * Returns 0 in case the RelaxNG validation could be (des)activated and
4104 * -1 in case of error.
4107 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4110 if (schema
== NULL
) {
4111 if (reader
->rngSchemas
!= NULL
) {
4112 xmlRelaxNGFree(reader
->rngSchemas
);
4113 reader
->rngSchemas
= NULL
;
4115 if (reader
->rngValidCtxt
!= NULL
) {
4116 if (! reader
->rngPreserveCtxt
)
4117 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4118 reader
->rngValidCtxt
= NULL
;
4120 reader
->rngPreserveCtxt
= 0;
4123 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4125 if (reader
->rngSchemas
!= NULL
) {
4126 xmlRelaxNGFree(reader
->rngSchemas
);
4127 reader
->rngSchemas
= NULL
;
4129 if (reader
->rngValidCtxt
!= NULL
) {
4130 if (! reader
->rngPreserveCtxt
)
4131 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4132 reader
->rngValidCtxt
= NULL
;
4134 reader
->rngPreserveCtxt
= 0;
4135 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4136 if (reader
->rngValidCtxt
== NULL
)
4138 if (reader
->errorFunc
!= NULL
) {
4139 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4140 xmlTextReaderValidityErrorRelay
,
4141 xmlTextReaderValidityWarningRelay
,
4144 if (reader
->sErrorFunc
!= NULL
) {
4145 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4146 xmlTextReaderValidityStructuredRelay
,
4149 reader
->rngValidErrors
= 0;
4150 reader
->rngFullNode
= NULL
;
4151 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4156 * xmlTextReaderLocator:
4157 * @ctx: the xmlTextReaderPtr used
4158 * @file: returned file information
4159 * @line: returned line information
4161 * Internal locator function for the readers
4163 * Returns 0 in case the Schema validation could be (des)activated and
4164 * -1 in case of error.
4167 xmlTextReaderLocator(void *ctx
, const char **file
, unsigned long *line
) {
4168 xmlTextReaderPtr reader
;
4170 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
4178 reader
= (xmlTextReaderPtr
) ctx
;
4179 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->input
!= NULL
)) {
4181 *file
= reader
->ctxt
->input
->filename
;
4183 *line
= reader
->ctxt
->input
->line
;
4186 if (reader
->node
!= NULL
) {
4191 res
= xmlGetLineNo(reader
->node
);
4193 *line
= (unsigned long) res
;
4198 xmlDocPtr doc
= reader
->node
->doc
;
4199 if ((doc
!= NULL
) && (doc
->URL
!= NULL
))
4200 *file
= (const char *) doc
->URL
;
4210 * xmlTextReaderSetSchema:
4211 * @reader: the xmlTextReaderPtr used
4212 * @schema: a precompiled Schema schema
4214 * Use XSD Schema to validate the document as it is processed.
4215 * Activation is only possible before the first Read().
4216 * if @schema is NULL, then Schema validation is desactivated.
4217 @ The @schema should not be freed until the reader is deallocated
4218 * or its use has been deactivated.
4220 * Returns 0 in case the Schema validation could be (des)activated and
4221 * -1 in case of error.
4224 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4227 if (schema
== NULL
) {
4228 if (reader
->xsdPlug
!= NULL
) {
4229 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4230 reader
->xsdPlug
= NULL
;
4232 if (reader
->xsdValidCtxt
!= NULL
) {
4233 if (! reader
->xsdPreserveCtxt
)
4234 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4235 reader
->xsdValidCtxt
= NULL
;
4237 reader
->xsdPreserveCtxt
= 0;
4238 if (reader
->xsdSchemas
!= NULL
) {
4239 xmlSchemaFree(reader
->xsdSchemas
);
4240 reader
->xsdSchemas
= NULL
;
4244 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4246 if (reader
->xsdPlug
!= NULL
) {
4247 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4248 reader
->xsdPlug
= NULL
;
4250 if (reader
->xsdValidCtxt
!= NULL
) {
4251 if (! reader
->xsdPreserveCtxt
)
4252 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4253 reader
->xsdValidCtxt
= NULL
;
4255 reader
->xsdPreserveCtxt
= 0;
4256 if (reader
->xsdSchemas
!= NULL
) {
4257 xmlSchemaFree(reader
->xsdSchemas
);
4258 reader
->xsdSchemas
= NULL
;
4260 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4261 if (reader
->xsdValidCtxt
== NULL
) {
4262 xmlSchemaFree(reader
->xsdSchemas
);
4263 reader
->xsdSchemas
= NULL
;
4266 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4267 &(reader
->ctxt
->sax
),
4268 &(reader
->ctxt
->userData
));
4269 if (reader
->xsdPlug
== NULL
) {
4270 xmlSchemaFree(reader
->xsdSchemas
);
4271 reader
->xsdSchemas
= NULL
;
4272 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4273 reader
->xsdValidCtxt
= NULL
;
4276 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4277 xmlTextReaderLocator
,
4280 if (reader
->errorFunc
!= NULL
) {
4281 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4282 xmlTextReaderValidityErrorRelay
,
4283 xmlTextReaderValidityWarningRelay
,
4286 if (reader
->sErrorFunc
!= NULL
) {
4287 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4288 xmlTextReaderValidityStructuredRelay
,
4291 reader
->xsdValidErrors
= 0;
4292 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4297 * xmlTextReaderRelaxNGValidateInternal:
4298 * @reader: the xmlTextReaderPtr used
4299 * @rng: the path to a RelaxNG schema or NULL
4300 * @ctxt: the RelaxNG schema validation context or NULL
4301 * @options: options (not yet used)
4303 * Use RelaxNG to validate the document as it is processed.
4304 * Activation is only possible before the first Read().
4305 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
4307 * Returns 0 in case the RelaxNG validation could be (de)activated and
4308 * -1 in case of error.
4311 xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader
,
4313 xmlRelaxNGValidCtxtPtr ctxt
,
4314 int options ATTRIBUTE_UNUSED
)
4319 if ((rng
!= NULL
) && (ctxt
!= NULL
))
4322 if (((rng
!= NULL
) || (ctxt
!= NULL
)) &&
4323 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4324 (reader
->ctxt
== NULL
)))
4327 /* Cleanup previous validation stuff. */
4328 if (reader
->rngValidCtxt
!= NULL
) {
4329 if ( !reader
->rngPreserveCtxt
)
4330 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4331 reader
->rngValidCtxt
= NULL
;
4333 reader
->rngPreserveCtxt
= 0;
4334 if (reader
->rngSchemas
!= NULL
) {
4335 xmlRelaxNGFree(reader
->rngSchemas
);
4336 reader
->rngSchemas
= NULL
;
4339 if ((rng
== NULL
) && (ctxt
== NULL
)) {
4340 /* We just want to deactivate the validation, so get out. */
4346 xmlRelaxNGParserCtxtPtr pctxt
;
4347 /* Parse the schema and create validation environment. */
4349 pctxt
= xmlRelaxNGNewParserCtxt(rng
);
4350 if (reader
->errorFunc
!= NULL
) {
4351 xmlRelaxNGSetParserErrors(pctxt
,
4352 xmlTextReaderValidityErrorRelay
,
4353 xmlTextReaderValidityWarningRelay
,
4356 if (reader
->sErrorFunc
!= NULL
) {
4357 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4358 xmlTextReaderValidityStructuredRelay
,
4361 reader
->rngSchemas
= xmlRelaxNGParse(pctxt
);
4362 xmlRelaxNGFreeParserCtxt(pctxt
);
4363 if (reader
->rngSchemas
== NULL
)
4365 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4366 if (reader
->rngValidCtxt
== NULL
) {
4367 xmlRelaxNGFree(reader
->rngSchemas
);
4368 reader
->rngSchemas
= NULL
;
4372 /* Use the given validation context. */
4373 reader
->rngValidCtxt
= ctxt
;
4374 reader
->rngPreserveCtxt
= 1;
4377 * Redirect the validation context's error channels to use
4378 * the reader channels.
4379 * TODO: In case the user provides the validation context we
4380 * could make this redirection optional.
4382 if (reader
->errorFunc
!= NULL
) {
4383 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4384 xmlTextReaderValidityErrorRelay
,
4385 xmlTextReaderValidityWarningRelay
,
4388 if (reader
->sErrorFunc
!= NULL
) {
4389 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4390 xmlTextReaderValidityStructuredRelay
,
4393 reader
->rngValidErrors
= 0;
4394 reader
->rngFullNode
= NULL
;
4395 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4400 * xmlTextReaderSchemaValidateInternal:
4401 * @reader: the xmlTextReaderPtr used
4402 * @xsd: the path to a W3C XSD schema or NULL
4403 * @ctxt: the XML Schema validation context or NULL
4404 * @options: options (not used yet)
4406 * Validate the document as it is processed using XML Schema.
4407 * Activation is only possible before the first Read().
4408 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4410 * Returns 0 in case the schemas validation could be (de)activated and
4411 * -1 in case of error.
4414 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4416 xmlSchemaValidCtxtPtr ctxt
,
4417 int options ATTRIBUTE_UNUSED
)
4422 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4425 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4426 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4427 (reader
->ctxt
== NULL
)))
4430 /* Cleanup previous validation stuff. */
4431 if (reader
->xsdPlug
!= NULL
) {
4432 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4433 reader
->xsdPlug
= NULL
;
4435 if (reader
->xsdValidCtxt
!= NULL
) {
4436 if (! reader
->xsdPreserveCtxt
)
4437 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4438 reader
->xsdValidCtxt
= NULL
;
4440 reader
->xsdPreserveCtxt
= 0;
4441 if (reader
->xsdSchemas
!= NULL
) {
4442 xmlSchemaFree(reader
->xsdSchemas
);
4443 reader
->xsdSchemas
= NULL
;
4446 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4447 /* We just want to deactivate the validation, so get out. */
4452 xmlSchemaParserCtxtPtr pctxt
;
4453 /* Parse the schema and create validation environment. */
4454 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4455 if (reader
->errorFunc
!= NULL
) {
4456 xmlSchemaSetParserErrors(pctxt
,
4457 xmlTextReaderValidityErrorRelay
,
4458 xmlTextReaderValidityWarningRelay
,
4461 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4462 xmlSchemaFreeParserCtxt(pctxt
);
4463 if (reader
->xsdSchemas
== NULL
)
4465 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4466 if (reader
->xsdValidCtxt
== NULL
) {
4467 xmlSchemaFree(reader
->xsdSchemas
);
4468 reader
->xsdSchemas
= NULL
;
4471 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4472 &(reader
->ctxt
->sax
),
4473 &(reader
->ctxt
->userData
));
4474 if (reader
->xsdPlug
== NULL
) {
4475 xmlSchemaFree(reader
->xsdSchemas
);
4476 reader
->xsdSchemas
= NULL
;
4477 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4478 reader
->xsdValidCtxt
= NULL
;
4482 /* Use the given validation context. */
4483 reader
->xsdValidCtxt
= ctxt
;
4484 reader
->xsdPreserveCtxt
= 1;
4485 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4486 &(reader
->ctxt
->sax
),
4487 &(reader
->ctxt
->userData
));
4488 if (reader
->xsdPlug
== NULL
) {
4489 reader
->xsdValidCtxt
= NULL
;
4490 reader
->xsdPreserveCtxt
= 0;
4494 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4495 xmlTextReaderLocator
,
4498 * Redirect the validation context's error channels to use
4499 * the reader channels.
4500 * TODO: In case the user provides the validation context we
4501 * could make this redirection optional.
4503 if (reader
->errorFunc
!= NULL
) {
4504 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4505 xmlTextReaderValidityErrorRelay
,
4506 xmlTextReaderValidityWarningRelay
,
4509 if (reader
->sErrorFunc
!= NULL
) {
4510 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4511 xmlTextReaderValidityStructuredRelay
,
4514 reader
->xsdValidErrors
= 0;
4515 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4520 * xmlTextReaderSchemaValidateCtxt:
4521 * @reader: the xmlTextReaderPtr used
4522 * @ctxt: the XML Schema validation context or NULL
4523 * @options: options (not used yet)
4525 * Use W3C XSD 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 XML Schema validation is deactivated.
4529 * Returns 0 in case the schemas validation could be (de)activated and
4530 * -1 in case of error.
4533 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4534 xmlSchemaValidCtxtPtr ctxt
,
4537 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4541 * xmlTextReaderSchemaValidate:
4542 * @reader: the xmlTextReaderPtr used
4543 * @xsd: the path to a W3C XSD schema or NULL
4545 * Use W3C XSD schema to validate the document as it is processed.
4546 * Activation is only possible before the first Read().
4547 * If @xsd is NULL, then XML Schema validation is deactivated.
4549 * Returns 0 in case the schemas validation could be (de)activated and
4550 * -1 in case of error.
4553 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4555 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4559 * xmlTextReaderRelaxNGValidateCtxt:
4560 * @reader: the xmlTextReaderPtr used
4561 * @ctxt: the RelaxNG schema validation context or NULL
4562 * @options: options (not used yet)
4564 * Use RelaxNG schema context to validate the document as it is processed.
4565 * Activation is only possible before the first Read().
4566 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
4568 * Returns 0 in case the schemas validation could be (de)activated and
4569 * -1 in case of error.
4572 xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader
,
4573 xmlRelaxNGValidCtxtPtr ctxt
,
4576 return(xmlTextReaderRelaxNGValidateInternal(reader
, NULL
, ctxt
, options
));
4580 * xmlTextReaderRelaxNGValidate:
4581 * @reader: the xmlTextReaderPtr used
4582 * @rng: the path to a RelaxNG schema or NULL
4584 * Use RelaxNG schema to validate the document as it is processed.
4585 * Activation is only possible before the first Read().
4586 * If @rng is NULL, then RelaxNG schema validation is deactivated.
4588 * Returns 0 in case the schemas validation could be (de)activated and
4589 * -1 in case of error.
4592 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
)
4594 return(xmlTextReaderRelaxNGValidateInternal(reader
, rng
, NULL
, 0));
4600 * xmlTextReaderIsNamespaceDecl:
4601 * @reader: the xmlTextReaderPtr used
4603 * Determine whether the current node is a namespace declaration
4604 * rather than a regular attribute.
4606 * Returns 1 if the current node is a namespace declaration, 0 if it
4607 * is a regular attribute or other type of node, or -1 in case of
4611 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4615 if (reader
->node
== NULL
)
4617 if (reader
->curnode
!= NULL
)
4618 node
= reader
->curnode
;
4620 node
= reader
->node
;
4622 if (XML_NAMESPACE_DECL
== node
->type
)
4629 * xmlTextReaderConstXmlVersion:
4630 * @reader: the xmlTextReaderPtr used
4632 * Determine the XML version of the document being read.
4634 * Returns a string containing the XML version of the document or NULL
4635 * in case of error. The string is deallocated with the reader.
4638 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4639 xmlDocPtr doc
= NULL
;
4642 if (reader
->doc
!= NULL
)
4644 else if (reader
->ctxt
!= NULL
)
4645 doc
= reader
->ctxt
->myDoc
;
4649 if (doc
->version
== NULL
)
4652 return(CONSTSTR(doc
->version
));
4656 * xmlTextReaderStandalone:
4657 * @reader: the xmlTextReaderPtr used
4659 * Determine the standalone status of the document being read.
4661 * Returns 1 if the document was declared to be standalone, 0 if it
4662 * was declared to be not standalone, or -1 if the document did not
4663 * specify its standalone status or in case of error.
4666 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4667 xmlDocPtr doc
= NULL
;
4670 if (reader
->doc
!= NULL
)
4672 else if (reader
->ctxt
!= NULL
)
4673 doc
= reader
->ctxt
->myDoc
;
4677 return(doc
->standalone
);
4680 /************************************************************************
4682 * Error Handling Extensions *
4684 ************************************************************************/
4686 /* helper to build a xmlMalloc'ed string from a format and va_list */
4688 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4697 chars
= vsnprintf(str
, size
, msg
, aq
);
4700 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4705 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4707 if (chars
< MAX_ERR_MSG_SIZE
)
4710 size
= MAX_ERR_MSG_SIZE
;
4711 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4712 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4724 * xmlTextReaderLocatorLineNumber:
4725 * @locator: the xmlTextReaderLocatorPtr used
4727 * Obtain the line number for the given locator.
4729 * Returns the line number or -1 in case of error.
4732 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4733 /* we know that locator is a xmlParserCtxtPtr */
4734 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4737 if (locator
== NULL
)
4739 if (ctx
->node
!= NULL
) {
4740 ret
= xmlGetLineNo(ctx
->node
);
4743 /* inspired from error.c */
4744 xmlParserInputPtr input
;
4746 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4747 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4748 if (input
!= NULL
) {
4760 * xmlTextReaderLocatorBaseURI:
4761 * @locator: the xmlTextReaderLocatorPtr used
4763 * Obtain the base URI for the given locator.
4765 * Returns the base URI or NULL in case of error,
4766 * if non NULL it need to be freed by the caller.
4769 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4770 /* we know that locator is a xmlParserCtxtPtr */
4771 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4772 xmlChar
*ret
= NULL
;
4774 if (locator
== NULL
)
4776 if (ctx
->node
!= NULL
) {
4777 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4780 /* inspired from error.c */
4781 xmlParserInputPtr input
;
4783 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4784 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4785 if (input
!= NULL
) {
4786 ret
= xmlStrdup(BAD_CAST input
->filename
);
4797 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4800 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4802 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4805 if (reader
->errorFunc
)
4806 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4807 (xmlTextReaderLocatorPtr
) ctx
);
4813 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4815 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4817 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4819 if (error
&& reader
->sErrorFunc
) {
4820 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4824 static void XMLCDECL
4825 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4830 xmlTextReaderGenericError(ctxt
,
4831 XML_PARSER_SEVERITY_ERROR
,
4832 xmlTextReaderBuildMessage(msg
, ap
));
4837 static void XMLCDECL
4838 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4843 xmlTextReaderGenericError(ctxt
,
4844 XML_PARSER_SEVERITY_WARNING
,
4845 xmlTextReaderBuildMessage(msg
, ap
));
4849 static void XMLCDECL
4850 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4854 int len
= xmlStrlen((const xmlChar
*) msg
);
4856 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4858 * some callbacks only report locator information:
4859 * skip them (mimicking behaviour in error.c)
4862 xmlTextReaderGenericError(ctxt
,
4863 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4864 xmlTextReaderBuildMessage(msg
, ap
));
4869 static void XMLCDECL
4870 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4874 int len
= xmlStrlen((const xmlChar
*) msg
);
4876 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4878 * some callbacks only report locator information:
4879 * skip them (mimicking behaviour in error.c)
4882 xmlTextReaderGenericError(ctxt
,
4883 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4884 xmlTextReaderBuildMessage(msg
, ap
));
4890 * xmlTextReaderSetErrorHandler:
4891 * @reader: the xmlTextReaderPtr used
4892 * @f: the callback function to call on error and warnings
4893 * @arg: a user argument to pass to the callback function
4895 * Register a callback function that will be called on error and warnings.
4897 * If @f is NULL, the default error and warning handlers are restored.
4900 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4901 xmlTextReaderErrorFunc f
, void *arg
)
4904 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4905 reader
->ctxt
->sax
->serror
= NULL
;
4906 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4907 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4908 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4909 reader
->errorFunc
= f
;
4910 reader
->sErrorFunc
= NULL
;
4911 reader
->errorFuncArg
= arg
;
4912 #ifdef LIBXML_SCHEMAS_ENABLED
4913 if (reader
->rngValidCtxt
) {
4914 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4915 xmlTextReaderValidityErrorRelay
,
4916 xmlTextReaderValidityWarningRelay
,
4918 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4921 if (reader
->xsdValidCtxt
) {
4922 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4923 xmlTextReaderValidityErrorRelay
,
4924 xmlTextReaderValidityWarningRelay
,
4926 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4931 /* restore defaults */
4932 reader
->ctxt
->sax
->error
= xmlParserError
;
4933 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4934 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4935 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4936 reader
->errorFunc
= NULL
;
4937 reader
->sErrorFunc
= NULL
;
4938 reader
->errorFuncArg
= NULL
;
4939 #ifdef LIBXML_SCHEMAS_ENABLED
4940 if (reader
->rngValidCtxt
) {
4941 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4943 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4946 if (reader
->xsdValidCtxt
) {
4947 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4949 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4957 * xmlTextReaderSetStructuredErrorHandler:
4958 * @reader: the xmlTextReaderPtr used
4959 * @f: the callback function to call on error and warnings
4960 * @arg: a user argument to pass to the callback function
4962 * Register a callback function that will be called on error and warnings.
4964 * If @f is NULL, the default error and warning handlers are restored.
4967 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
4968 xmlStructuredErrorFunc f
, void *arg
)
4971 reader
->ctxt
->sax
->error
= NULL
;
4972 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
4973 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4974 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4975 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4976 reader
->sErrorFunc
= f
;
4977 reader
->errorFunc
= NULL
;
4978 reader
->errorFuncArg
= arg
;
4979 #ifdef LIBXML_SCHEMAS_ENABLED
4980 if (reader
->rngValidCtxt
) {
4981 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4983 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4984 xmlTextReaderValidityStructuredRelay
,
4987 if (reader
->xsdValidCtxt
) {
4988 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4990 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4991 xmlTextReaderValidityStructuredRelay
,
4996 /* restore defaults */
4997 reader
->ctxt
->sax
->error
= xmlParserError
;
4998 reader
->ctxt
->sax
->serror
= NULL
;
4999 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
5000 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
5001 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
5002 reader
->errorFunc
= NULL
;
5003 reader
->sErrorFunc
= NULL
;
5004 reader
->errorFuncArg
= NULL
;
5005 #ifdef LIBXML_SCHEMAS_ENABLED
5006 if (reader
->rngValidCtxt
) {
5007 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
5009 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
5012 if (reader
->xsdValidCtxt
) {
5013 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
5015 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
5023 * xmlTextReaderIsValid:
5024 * @reader: the xmlTextReaderPtr used
5026 * Retrieve the validity status from the parser context
5028 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
5031 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
5035 #ifdef LIBXML_SCHEMAS_ENABLED
5036 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
5037 return (reader
->rngValidErrors
== 0);
5038 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
5039 return (reader
->xsdValidErrors
== 0);
5041 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
5042 return (reader
->ctxt
->valid
);
5047 * xmlTextReaderGetErrorHandler:
5048 * @reader: the xmlTextReaderPtr used
5049 * @f: the callback function or NULL is no callback has been registered
5050 * @arg: a user argument
5052 * Retrieve the error callback function and user argument.
5055 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
5056 xmlTextReaderErrorFunc
* f
, void **arg
)
5059 *f
= reader
->errorFunc
;
5061 *arg
= reader
->errorFuncArg
;
5063 /************************************************************************
5065 * New set (2.6.0) of simpler and more flexible APIs *
5067 ************************************************************************/
5070 * xmlTextReaderSetup:
5071 * @reader: an XML reader
5072 * @input: xmlParserInputBufferPtr used to feed the reader, will
5073 * be destroyed with it.
5074 * @URL: the base URL to use for the document
5075 * @encoding: the document encoding, or NULL
5076 * @options: a combination of xmlParserOption
5078 * Setup an XML reader with new options
5080 * Returns 0 in case of success and -1 in case of error.
5083 xmlTextReaderSetup(xmlTextReaderPtr reader
,
5084 xmlParserInputBufferPtr input
, const char *URL
,
5085 const char *encoding
, int options
)
5087 if (reader
== NULL
) {
5089 xmlFreeParserInputBuffer(input
);
5094 * we force the generation of compact text nodes on the reader
5095 * since usr applications should never modify the tree
5097 options
|= XML_PARSE_COMPACT
;
5101 reader
->parserFlags
= options
;
5102 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
5103 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
5104 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
5105 xmlFreeParserInputBuffer(reader
->input
);
5106 reader
->input
= NULL
;
5107 reader
->allocs
-= XML_TEXTREADER_INPUT
;
5109 if (input
!= NULL
) {
5110 reader
->input
= input
;
5111 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5113 if (reader
->buffer
== NULL
)
5114 reader
->buffer
= xmlBufCreateSize(100);
5115 if (reader
->buffer
== NULL
) {
5116 xmlGenericError(xmlGenericErrorContext
,
5117 "xmlTextReaderSetup : malloc failed\n");
5120 if (reader
->sax
== NULL
)
5121 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
5122 if (reader
->sax
== NULL
) {
5123 xmlGenericError(xmlGenericErrorContext
,
5124 "xmlTextReaderSetup : malloc failed\n");
5127 xmlSAXVersion(reader
->sax
, 2);
5128 reader
->startElement
= reader
->sax
->startElement
;
5129 reader
->sax
->startElement
= xmlTextReaderStartElement
;
5130 reader
->endElement
= reader
->sax
->endElement
;
5131 reader
->sax
->endElement
= xmlTextReaderEndElement
;
5132 #ifdef LIBXML_SAX1_ENABLED
5133 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
5134 #endif /* LIBXML_SAX1_ENABLED */
5135 reader
->startElementNs
= reader
->sax
->startElementNs
;
5136 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
5137 reader
->endElementNs
= reader
->sax
->endElementNs
;
5138 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
5139 #ifdef LIBXML_SAX1_ENABLED
5141 reader
->startElementNs
= NULL
;
5142 reader
->endElementNs
= NULL
;
5144 #endif /* LIBXML_SAX1_ENABLED */
5145 reader
->characters
= reader
->sax
->characters
;
5146 reader
->sax
->characters
= xmlTextReaderCharacters
;
5147 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
5148 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
5149 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
5151 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5152 reader
->node
= NULL
;
5153 reader
->curnode
= NULL
;
5154 if (input
!= NULL
) {
5155 if (xmlBufUse(reader
->input
->buffer
) < 4) {
5156 xmlParserInputBufferRead(input
, 4);
5158 if (reader
->ctxt
== NULL
) {
5159 if (xmlBufUse(reader
->input
->buffer
) >= 4) {
5160 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5161 (const char *) xmlBufContent(reader
->input
->buffer
),
5167 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5172 xmlParserInputPtr inputStream
;
5173 xmlParserInputBufferPtr buf
;
5174 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5176 xmlCtxtReset(reader
->ctxt
);
5177 buf
= xmlAllocParserInputBuffer(enc
);
5178 if (buf
== NULL
) return(-1);
5179 inputStream
= xmlNewInputStream(reader
->ctxt
);
5180 if (inputStream
== NULL
) {
5181 xmlFreeParserInputBuffer(buf
);
5186 inputStream
->filename
= NULL
;
5188 inputStream
->filename
= (char *)
5189 xmlCanonicPath((const xmlChar
*) URL
);
5190 inputStream
->buf
= buf
;
5191 xmlBufResetInput(buf
->buffer
, inputStream
);
5193 inputPush(reader
->ctxt
, inputStream
);
5196 if (reader
->ctxt
== NULL
) {
5197 xmlGenericError(xmlGenericErrorContext
,
5198 "xmlTextReaderSetup : malloc failed\n");
5202 if (reader
->dict
!= NULL
) {
5203 if (reader
->ctxt
->dict
!= NULL
) {
5204 if (reader
->dict
!= reader
->ctxt
->dict
) {
5205 xmlDictFree(reader
->dict
);
5206 reader
->dict
= reader
->ctxt
->dict
;
5209 reader
->ctxt
->dict
= reader
->dict
;
5212 if (reader
->ctxt
->dict
== NULL
)
5213 reader
->ctxt
->dict
= xmlDictCreate();
5214 reader
->dict
= reader
->ctxt
->dict
;
5216 reader
->ctxt
->_private
= reader
;
5217 reader
->ctxt
->linenumbers
= 1;
5218 reader
->ctxt
->dictNames
= 1;
5220 * use the parser dictionnary to allocate all elements and attributes names
5222 reader
->ctxt
->docdict
= 1;
5223 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5225 #ifdef LIBXML_XINCLUDE_ENABLED
5226 if (reader
->xincctxt
!= NULL
) {
5227 xmlXIncludeFreeContext(reader
->xincctxt
);
5228 reader
->xincctxt
= NULL
;
5230 if (options
& XML_PARSE_XINCLUDE
) {
5231 reader
->xinclude
= 1;
5232 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5233 options
-= XML_PARSE_XINCLUDE
;
5235 reader
->xinclude
= 0;
5236 reader
->in_xinclude
= 0;
5238 #ifdef LIBXML_PATTERN_ENABLED
5239 if (reader
->patternTab
== NULL
) {
5240 reader
->patternNr
= 0;
5241 reader
->patternMax
= 0;
5243 while (reader
->patternNr
> 0) {
5244 reader
->patternNr
--;
5245 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5246 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5247 reader
->patternTab
[reader
->patternNr
] = NULL
;
5252 if (options
& XML_PARSE_DTDVALID
)
5253 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5255 xmlCtxtUseOptions(reader
->ctxt
, options
);
5256 if (encoding
!= NULL
) {
5257 xmlCharEncodingHandlerPtr hdlr
;
5259 hdlr
= xmlFindCharEncodingHandler(encoding
);
5261 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5263 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5264 (reader
->ctxt
->input
->filename
== NULL
))
5265 reader
->ctxt
->input
->filename
= (char *)
5266 xmlStrdup((const xmlChar
*) URL
);
5274 * xmlTextReaderByteConsumed:
5275 * @reader: an XML reader
5277 * This function provides the current index of the parser used
5278 * by the reader, relative to the start of the current entity.
5279 * This function actually just wraps a call to xmlBytesConsumed()
5280 * for the parser context associated with the reader.
5281 * See xmlBytesConsumed() for more information.
5283 * Returns the index in bytes from the beginning of the entity or -1
5284 * in case the index could not be computed.
5287 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5288 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5290 return(xmlByteConsumed(reader
->ctxt
));
5296 * @doc: a preparsed document
5298 * Create an xmltextReader for a preparsed document.
5300 * Returns the new reader or NULL in case of error.
5303 xmlReaderWalker(xmlDocPtr doc
)
5305 xmlTextReaderPtr ret
;
5310 ret
= xmlMalloc(sizeof(xmlTextReader
));
5312 xmlGenericError(xmlGenericErrorContext
,
5313 "xmlNewTextReader : malloc failed\n");
5316 memset(ret
, 0, sizeof(xmlTextReader
));
5319 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5321 ret
->curnode
= NULL
;
5324 ret
->allocs
= XML_TEXTREADER_CTXT
;
5326 ret
->state
= XML_TEXTREADER_START
;
5327 ret
->dict
= xmlDictCreate();
5333 * @cur: a pointer to a zero terminated string
5334 * @URL: the base URL to use for the document
5335 * @encoding: the document encoding, or NULL
5336 * @options: a combination of xmlParserOption
5338 * Create an xmltextReader for an XML in-memory document.
5339 * The parsing flags @options are a combination of xmlParserOption.
5341 * Returns the new reader or NULL in case of error.
5344 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5351 len
= xmlStrlen(cur
);
5353 return (xmlReaderForMemory
5354 ((const char *) cur
, len
, URL
, encoding
, options
));
5359 * @filename: a file or URL
5360 * @encoding: the document encoding, or NULL
5361 * @options: a combination of xmlParserOption
5363 * parse an XML file from the filesystem or the network.
5364 * The parsing flags @options are a combination of xmlParserOption.
5366 * Returns the new reader or NULL in case of error.
5369 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5371 xmlTextReaderPtr reader
;
5373 reader
= xmlNewTextReaderFilename(filename
);
5376 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5381 * xmlReaderForMemory:
5382 * @buffer: a pointer to a char array
5383 * @size: the size of the array
5384 * @URL: the base URL to use for the document
5385 * @encoding: the document encoding, or NULL
5386 * @options: a combination of xmlParserOption
5388 * Create an xmltextReader for an XML in-memory document.
5389 * The parsing flags @options are a combination of xmlParserOption.
5391 * Returns the new reader or NULL in case of error.
5394 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5395 const char *encoding
, int options
)
5397 xmlTextReaderPtr reader
;
5398 xmlParserInputBufferPtr buf
;
5400 buf
= xmlParserInputBufferCreateStatic(buffer
, size
,
5401 XML_CHAR_ENCODING_NONE
);
5405 reader
= xmlNewTextReader(buf
, URL
);
5406 if (reader
== NULL
) {
5407 xmlFreeParserInputBuffer(buf
);
5410 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5411 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5417 * @fd: an open file descriptor
5418 * @URL: the base URL to use for the document
5419 * @encoding: the document encoding, or NULL
5420 * @options: a combination of xmlParserOption
5422 * Create an xmltextReader for an XML from a file descriptor.
5423 * The parsing flags @options are a combination of xmlParserOption.
5424 * NOTE that the file descriptor will not be closed when the
5425 * reader is closed or reset.
5427 * Returns the new reader or NULL in case of error.
5430 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5432 xmlTextReaderPtr reader
;
5433 xmlParserInputBufferPtr input
;
5438 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5441 input
->closecallback
= NULL
;
5442 reader
= xmlNewTextReader(input
, URL
);
5443 if (reader
== NULL
) {
5444 xmlFreeParserInputBuffer(input
);
5447 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5448 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5454 * @ioread: an I/O read function
5455 * @ioclose: an I/O close function
5456 * @ioctx: an I/O handler
5457 * @URL: the base URL to use for the document
5458 * @encoding: the document encoding, or NULL
5459 * @options: a combination of xmlParserOption
5461 * Create an xmltextReader for an XML document from I/O functions and source.
5462 * The parsing flags @options are a combination of xmlParserOption.
5464 * Returns the new reader or NULL in case of error.
5467 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5468 void *ioctx
, const char *URL
, const char *encoding
,
5471 xmlTextReaderPtr reader
;
5472 xmlParserInputBufferPtr input
;
5477 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5478 XML_CHAR_ENCODING_NONE
);
5479 if (input
== NULL
) {
5480 if (ioclose
!= NULL
)
5484 reader
= xmlNewTextReader(input
, URL
);
5485 if (reader
== NULL
) {
5486 xmlFreeParserInputBuffer(input
);
5489 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5490 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5495 * xmlReaderNewWalker:
5496 * @reader: an XML reader
5497 * @doc: a preparsed document
5499 * Setup an xmltextReader to parse a preparsed XML document.
5500 * This reuses the existing @reader xmlTextReader.
5502 * Returns 0 in case of success and -1 in case of error
5505 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5512 if (reader
->input
!= NULL
) {
5513 xmlFreeParserInputBuffer(reader
->input
);
5515 if (reader
->ctxt
!= NULL
) {
5516 xmlCtxtReset(reader
->ctxt
);
5520 reader
->input
= NULL
;
5521 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5522 reader
->node
= NULL
;
5523 reader
->curnode
= NULL
;
5526 reader
->allocs
= XML_TEXTREADER_CTXT
;
5528 reader
->state
= XML_TEXTREADER_START
;
5529 if (reader
->dict
== NULL
) {
5530 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5531 reader
->dict
= reader
->ctxt
->dict
;
5533 reader
->dict
= xmlDictCreate();
5540 * @reader: an XML reader
5541 * @cur: a pointer to a zero terminated string
5542 * @URL: the base URL to use for the document
5543 * @encoding: the document encoding, or NULL
5544 * @options: a combination of xmlParserOption
5546 * Setup an xmltextReader to parse an XML in-memory document.
5547 * The parsing flags @options are a combination of xmlParserOption.
5548 * This reuses the existing @reader xmlTextReader.
5550 * Returns 0 in case of success and -1 in case of error
5553 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5554 const char *URL
, const char *encoding
, int options
)
5564 len
= xmlStrlen(cur
);
5565 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5566 URL
, encoding
, options
));
5571 * @reader: an XML reader
5572 * @filename: a file or URL
5573 * @encoding: the document encoding, or NULL
5574 * @options: a combination of xmlParserOption
5576 * parse an XML file from the filesystem or the network.
5577 * The parsing flags @options are a combination of xmlParserOption.
5578 * This reuses the existing @reader xmlTextReader.
5580 * Returns 0 in case of success and -1 in case of error
5583 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5584 const char *encoding
, int options
)
5586 xmlParserInputBufferPtr input
;
5588 if (filename
== NULL
)
5594 xmlParserInputBufferCreateFilename(filename
,
5595 XML_CHAR_ENCODING_NONE
);
5598 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5602 * xmlReaderNewMemory:
5603 * @reader: an XML reader
5604 * @buffer: a pointer to a char array
5605 * @size: the size of the array
5606 * @URL: the base URL to use for the document
5607 * @encoding: the document encoding, or NULL
5608 * @options: a combination of xmlParserOption
5610 * Setup an xmltextReader to parse an XML in-memory document.
5611 * The parsing flags @options are a combination of xmlParserOption.
5612 * This reuses the existing @reader xmlTextReader.
5614 * Returns 0 in case of success and -1 in case of error
5617 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5618 const char *URL
, const char *encoding
, int options
)
5620 xmlParserInputBufferPtr input
;
5627 input
= xmlParserInputBufferCreateStatic(buffer
, size
,
5628 XML_CHAR_ENCODING_NONE
);
5629 if (input
== NULL
) {
5632 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5637 * @reader: an XML reader
5638 * @fd: an open file descriptor
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 from a file descriptor.
5644 * NOTE that the file descriptor will not be closed when the
5645 * reader is closed or reset.
5646 * The parsing flags @options are a combination of xmlParserOption.
5647 * This reuses the existing @reader xmlTextReader.
5649 * Returns 0 in case of success and -1 in case of error
5652 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5653 const char *URL
, const char *encoding
, int options
)
5655 xmlParserInputBufferPtr input
;
5662 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5665 input
->closecallback
= NULL
;
5666 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5671 * @reader: an XML reader
5672 * @ioread: an I/O read function
5673 * @ioclose: an I/O close function
5674 * @ioctx: an I/O handler
5675 * @URL: the base URL to use for the document
5676 * @encoding: the document encoding, or NULL
5677 * @options: a combination of xmlParserOption
5679 * Setup an xmltextReader to parse an XML document from I/O functions
5681 * The parsing flags @options are a combination of xmlParserOption.
5682 * This reuses the existing @reader xmlTextReader.
5684 * Returns 0 in case of success and -1 in case of error
5687 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5688 xmlInputCloseCallback ioclose
, void *ioctx
,
5689 const char *URL
, const char *encoding
, int options
)
5691 xmlParserInputBufferPtr input
;
5698 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5699 XML_CHAR_ENCODING_NONE
);
5700 if (input
== NULL
) {
5701 if (ioclose
!= NULL
)
5705 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5708 /************************************************************************
5712 ************************************************************************/
5717 * @in: the input buffer
5718 * @inlen: the size of the input (in), the size read from it (out)
5719 * @to: the output buffer
5720 * @tolen: the size of the output (in), the size written to (out)
5722 * Base64 decoder, reads from @in and save in @to
5723 * TODO: tell jody when this is actually exported
5725 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5726 * 2 if there wasn't enough space on the output or -1 in case of error.
5729 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5730 unsigned char *to
, unsigned long *tolen
)
5732 unsigned long incur
; /* current index in in[] */
5734 unsigned long inblk
; /* last block index in in[] */
5736 unsigned long outcur
; /* current index in out[] */
5738 unsigned long inmax
; /* size of in[] */
5740 unsigned long outmax
; /* size of out[] */
5742 unsigned char cur
; /* the current value read from in[] */
5744 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5746 int nbintmp
; /* number of byte in intmp[] */
5748 int is_ignore
; /* cur should be ignored */
5750 int is_end
= 0; /* the end of the base64 was found */
5756 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5771 if ((cur
>= 'A') && (cur
<= 'Z'))
5773 else if ((cur
>= 'a') && (cur
<= 'z'))
5774 cur
= cur
- 'a' + 26;
5775 else if ((cur
>= '0') && (cur
<= '9'))
5776 cur
= cur
- '0' + 52;
5777 else if (cur
== '+')
5779 else if (cur
== '/')
5781 else if (cur
== '.')
5783 else if (cur
== '=') /*no op , end of the base64 stream */
5799 if ((nbintmp
== 1) || (nbintmp
== 2))
5806 intmp
[nbintmp
++] = cur
;
5808 * if intmp is full, push the 4byte sequence as a 3 byte
5813 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5815 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5816 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5817 if (outcur
+ 3 >= outmax
) {
5822 for (i
= 0; i
< nbouttmp
; i
++)
5823 to
[outcur
++] = outtmp
[i
];
5840 * Test routine for the xmlBase64Decode function
5844 main(int argc
, char **argv
)
5846 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5854 unsigned long inlen
= strlen(input
);
5856 unsigned long outlen
= 100;
5860 unsigned long cons
, tmp
, tmp2
, prod
;
5865 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5868 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5869 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5877 while (cons
< inlen
) {
5879 tmp2
= inlen
- cons
;
5881 printf("%ld %ld\n", cons
, prod
);
5882 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5885 printf("%ld %ld\n", cons
, prod
);
5887 output2
[outlen
] = 0;
5888 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5896 while (cons
< inlen
) {
5898 tmp2
= inlen
- cons
;
5902 printf("%ld %ld\n", cons
, prod
);
5903 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5906 printf("%ld %ld\n", cons
, prod
);
5908 output3
[outlen
] = 0;
5909 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5915 #endif /* NOT_USED_YET */
5916 #define bottom_xmlreader
5917 #include "elfgcchack.h"
5918 #endif /* LIBXML_READER_ENABLED */