2 * xmlreader.c: implements the xmlTextReader streaming node API
5 * XmlTextReader.Normalization Property won't be supported, since
6 * it makes the parser non compliant to the XML recommendation
8 * See Copyright for the status of this software.
15 * - XML Schemas validation
20 #ifdef LIBXML_READER_ENABLED
21 #include <string.h> /* for memset() only ! */
31 #include <libxml/xmlmemory.h>
32 #include <libxml/xmlIO.h>
33 #include <libxml/xmlreader.h>
34 #include <libxml/parserInternals.h>
35 #ifdef LIBXML_SCHEMAS_ENABLED
36 #include <libxml/relaxng.h>
37 #include <libxml/xmlschemas.h>
39 #include <libxml/uri.h>
40 #ifdef LIBXML_XINCLUDE_ENABLED
41 #include <libxml/xinclude.h>
43 #ifdef LIBXML_PATTERN_ENABLED
44 #include <libxml/pattern.h>
47 #define MAX_ERR_MSG_SIZE 64000
50 * The following VA_COPY was coded following an example in
51 * the Samba project. It may not be sufficient for some
52 * esoteric implementations of va_list (i.e. it may need
53 * something involving a memcpy) but (hopefully) will be
54 * sufficient for libxml2.
58 #define VA_COPY(dest, src) va_copy(dest, src)
61 #define VA_COPY(dest,src) __va_copy(dest, src)
63 #define VA_COPY(dest,src) (dest) = (src)
68 /* #define DEBUG_CALLBACKS */
69 /* #define DEBUG_READER */
74 * macro to flag unimplemented blocks
77 xmlGenericError(xmlGenericErrorContext, \
78 "Unimplemented block at %s:%d\n", \
82 #define DUMP_READER xmlTextReaderDebug(reader);
87 #define CHUNK_SIZE 512
88 /************************************************************************
90 * The parser: maps the Text Reader API on top of the existing *
91 * parsing routines building a tree *
93 ************************************************************************/
95 #define XML_TEXTREADER_INPUT 1
96 #define XML_TEXTREADER_CTXT 2
99 XML_TEXTREADER_NONE
= -1,
100 XML_TEXTREADER_START
= 0,
101 XML_TEXTREADER_ELEMENT
= 1,
102 XML_TEXTREADER_END
= 2,
103 XML_TEXTREADER_EMPTY
= 3,
104 XML_TEXTREADER_BACKTRACK
= 4,
105 XML_TEXTREADER_DONE
= 5,
106 XML_TEXTREADER_ERROR
= 6
107 } xmlTextReaderState
;
110 XML_TEXTREADER_NOT_VALIDATE
= 0,
111 XML_TEXTREADER_VALIDATE_DTD
= 1,
112 XML_TEXTREADER_VALIDATE_RNG
= 2,
113 XML_TEXTREADER_VALIDATE_XSD
= 4
114 } xmlTextReaderValidate
;
116 struct _xmlTextReader
{
117 int mode
; /* the parsing mode */
118 xmlDocPtr doc
; /* when walking an existing doc */
119 xmlTextReaderValidate validate
;/* is there any validation */
120 int allocs
; /* what structure were deallocated */
121 xmlTextReaderState state
;
122 xmlParserCtxtPtr ctxt
; /* the parser context */
123 xmlSAXHandlerPtr sax
; /* the parser SAX callbacks */
124 xmlParserInputBufferPtr input
; /* the input */
125 startElementSAXFunc startElement
;/* initial SAX callbacks */
126 endElementSAXFunc endElement
; /* idem */
127 startElementNsSAX2Func startElementNs
;/* idem */
128 endElementNsSAX2Func endElementNs
; /* idem */
129 charactersSAXFunc characters
;
130 cdataBlockSAXFunc cdataBlock
;
131 unsigned int base
; /* base of the segment in the input */
132 unsigned int cur
; /* current position in the input */
133 xmlNodePtr node
; /* current node */
134 xmlNodePtr curnode
;/* current attribute node */
135 int depth
; /* depth of the current node */
136 xmlNodePtr faketext
;/* fake xmlNs chld */
137 int preserve
;/* preserve the resulting document */
138 xmlBufferPtr buffer
; /* used to return const xmlChar * */
139 xmlDictPtr dict
; /* the context dictionnary */
141 /* entity stack when traversing entities content */
142 xmlNodePtr ent
; /* Current Entity Ref Node */
143 int entNr
; /* Depth of the entities stack */
144 int entMax
; /* Max depth of the entities stack */
145 xmlNodePtr
*entTab
; /* array of entities */
148 xmlTextReaderErrorFunc errorFunc
; /* callback function */
149 void *errorFuncArg
; /* callback function user argument */
151 #ifdef LIBXML_SCHEMAS_ENABLED
152 /* Handling of RelaxNG validation */
153 xmlRelaxNGPtr rngSchemas
; /* The Relax NG schemas */
154 xmlRelaxNGValidCtxtPtr rngValidCtxt
;/* The Relax NG validation context */
155 int rngValidErrors
;/* The number of errors detected */
156 xmlNodePtr rngFullNode
; /* the node if RNG not progressive */
157 /* Handling of Schemas validation */
158 xmlSchemaPtr xsdSchemas
; /* The Schemas schemas */
159 xmlSchemaValidCtxtPtr xsdValidCtxt
;/* The Schemas validation context */
160 int xsdPreserveCtxt
; /* 1 if the context was provided by the user */
161 int xsdValidErrors
;/* The number of errors detected */
162 xmlSchemaSAXPlugPtr xsdPlug
; /* the schemas plug in SAX pipeline */
164 #ifdef LIBXML_XINCLUDE_ENABLED
165 /* Handling of XInclude processing */
166 int xinclude
; /* is xinclude asked for */
167 const xmlChar
* xinclude_name
; /* the xinclude name from dict */
168 xmlXIncludeCtxtPtr xincctxt
; /* the xinclude context */
169 int in_xinclude
; /* counts for xinclude */
171 #ifdef LIBXML_PATTERN_ENABLED
172 int patternNr
; /* number of preserve patterns */
173 int patternMax
; /* max preserve patterns */
174 xmlPatternPtr
*patternTab
; /* array of preserve patterns */
176 int preserves
; /* level of preserves */
177 int parserFlags
; /* the set of options set */
178 /* Structured error handling */
179 xmlStructuredErrorFunc sErrorFunc
; /* callback function */
182 #define NODE_IS_EMPTY 0x1
183 #define NODE_IS_PRESERVED 0x2
184 #define NODE_IS_SPRESERVED 0x4
189 * Macro used to return an interned string
191 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
192 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
194 static int xmlTextReaderReadTree(xmlTextReaderPtr reader
);
195 static int xmlTextReaderNextTree(xmlTextReaderPtr reader
);
197 /************************************************************************
199 * Our own version of the freeing routines as we recycle nodes *
201 ************************************************************************/
206 * Free a string if it is not owned by the "dict" dictionnary in the
209 #define DICT_FREE(str) \
210 if ((str) && ((!dict) || \
211 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
212 xmlFree((char *)(str));
214 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
);
215 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
);
221 * Deallocate the memory used by an id definition
224 xmlFreeID(xmlIDPtr id
) {
225 xmlDictPtr dict
= NULL
;
227 if (id
== NULL
) return;
230 dict
= id
->doc
->dict
;
232 if (id
->value
!= NULL
)
238 * xmlTextReaderRemoveID:
240 * @attr: the attribute
242 * Remove the given attribute from the ID table maintained internally.
244 * Returns -1 if the lookup failed and 0 otherwise
247 xmlTextReaderRemoveID(xmlDocPtr doc
, xmlAttrPtr attr
) {
252 if (doc
== NULL
) return(-1);
253 if (attr
== NULL
) return(-1);
254 table
= (xmlIDTablePtr
) doc
->ids
;
258 ID
= xmlNodeListGetString(doc
, attr
->children
, 1);
261 id
= xmlHashLookup(table
, ID
);
263 if (id
== NULL
|| id
->attr
!= attr
) {
266 id
->name
= attr
->name
;
272 * xmlTextReaderFreeProp:
273 * @reader: the xmlTextReaderPtr used
279 xmlTextReaderFreeProp(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
282 dict
= reader
->ctxt
->dict
;
283 if (cur
== NULL
) return;
285 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
286 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
288 /* Check for ID removal -> leading to invalid references ! */
289 if ((cur
->parent
!= NULL
) && (cur
->parent
->doc
!= NULL
) &&
290 ((cur
->parent
->doc
->intSubset
!= NULL
) ||
291 (cur
->parent
->doc
->extSubset
!= NULL
))) {
292 if (xmlIsID(cur
->parent
->doc
, cur
->parent
, cur
))
293 xmlTextReaderRemoveID(cur
->parent
->doc
, cur
);
295 if (cur
->children
!= NULL
)
296 xmlTextReaderFreeNodeList(reader
, cur
->children
);
298 DICT_FREE(cur
->name
);
299 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
300 (reader
->ctxt
->freeAttrsNr
< 100)) {
301 cur
->next
= reader
->ctxt
->freeAttrs
;
302 reader
->ctxt
->freeAttrs
= cur
;
303 reader
->ctxt
->freeAttrsNr
++;
310 * xmlTextReaderFreePropList:
311 * @reader: the xmlTextReaderPtr used
312 * @cur: the first property in the list
314 * Free a property and all its siblings, all the children are freed too.
317 xmlTextReaderFreePropList(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
319 if (cur
== NULL
) return;
320 while (cur
!= NULL
) {
322 xmlTextReaderFreeProp(reader
, cur
);
328 * xmlTextReaderFreeNodeList:
329 * @reader: the xmlTextReaderPtr used
330 * @cur: the first node in the list
332 * Free a node and all its siblings, this is a recursive behaviour, all
333 * the children are freed too.
336 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
340 dict
= reader
->ctxt
->dict
;
341 if (cur
== NULL
) return;
342 if (cur
->type
== XML_NAMESPACE_DECL
) {
343 xmlFreeNsList((xmlNsPtr
) cur
);
346 if ((cur
->type
== XML_DOCUMENT_NODE
) ||
347 (cur
->type
== XML_HTML_DOCUMENT_NODE
)) {
348 xmlFreeDoc((xmlDocPtr
) cur
);
351 while (cur
!= NULL
) {
353 /* unroll to speed up freeing the document */
354 if (cur
->type
!= XML_DTD_NODE
) {
356 if ((cur
->children
!= NULL
) &&
357 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
358 if (cur
->children
->parent
== cur
)
359 xmlTextReaderFreeNodeList(reader
, cur
->children
);
360 cur
->children
= NULL
;
363 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
364 xmlDeregisterNodeDefaultValue(cur
);
366 if (((cur
->type
== XML_ELEMENT_NODE
) ||
367 (cur
->type
== XML_XINCLUDE_START
) ||
368 (cur
->type
== XML_XINCLUDE_END
)) &&
369 (cur
->properties
!= NULL
))
370 xmlTextReaderFreePropList(reader
, cur
->properties
);
371 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
372 (cur
->type
!= XML_ELEMENT_NODE
) &&
373 (cur
->type
!= XML_XINCLUDE_START
) &&
374 (cur
->type
!= XML_XINCLUDE_END
) &&
375 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
376 DICT_FREE(cur
->content
);
378 if (((cur
->type
== XML_ELEMENT_NODE
) ||
379 (cur
->type
== XML_XINCLUDE_START
) ||
380 (cur
->type
== XML_XINCLUDE_END
)) &&
381 (cur
->nsDef
!= NULL
))
382 xmlFreeNsList(cur
->nsDef
);
385 * we don't free element names here they are interned now
387 if ((cur
->type
!= XML_TEXT_NODE
) &&
388 (cur
->type
!= XML_COMMENT_NODE
))
389 DICT_FREE(cur
->name
);
390 if (((cur
->type
== XML_ELEMENT_NODE
) ||
391 (cur
->type
== XML_TEXT_NODE
)) &&
392 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
393 (reader
->ctxt
->freeElemsNr
< 100)) {
394 cur
->next
= reader
->ctxt
->freeElems
;
395 reader
->ctxt
->freeElems
= cur
;
396 reader
->ctxt
->freeElemsNr
++;
406 * xmlTextReaderFreeNode:
407 * @reader: the xmlTextReaderPtr used
410 * Free a node, this is a recursive behaviour, all the children are freed too.
411 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
414 xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
417 dict
= reader
->ctxt
->dict
;
418 if (cur
->type
== XML_DTD_NODE
) {
419 xmlFreeDtd((xmlDtdPtr
) cur
);
422 if (cur
->type
== XML_NAMESPACE_DECL
) {
423 xmlFreeNs((xmlNsPtr
) cur
);
426 if (cur
->type
== XML_ATTRIBUTE_NODE
) {
427 xmlTextReaderFreeProp(reader
, (xmlAttrPtr
) cur
);
431 if ((cur
->children
!= NULL
) &&
432 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
433 if (cur
->children
->parent
== cur
)
434 xmlTextReaderFreeNodeList(reader
, cur
->children
);
435 cur
->children
= NULL
;
438 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
439 xmlDeregisterNodeDefaultValue(cur
);
441 if (((cur
->type
== XML_ELEMENT_NODE
) ||
442 (cur
->type
== XML_XINCLUDE_START
) ||
443 (cur
->type
== XML_XINCLUDE_END
)) &&
444 (cur
->properties
!= NULL
))
445 xmlTextReaderFreePropList(reader
, cur
->properties
);
446 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
447 (cur
->type
!= XML_ELEMENT_NODE
) &&
448 (cur
->type
!= XML_XINCLUDE_START
) &&
449 (cur
->type
!= XML_XINCLUDE_END
) &&
450 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
451 DICT_FREE(cur
->content
);
453 if (((cur
->type
== XML_ELEMENT_NODE
) ||
454 (cur
->type
== XML_XINCLUDE_START
) ||
455 (cur
->type
== XML_XINCLUDE_END
)) &&
456 (cur
->nsDef
!= NULL
))
457 xmlFreeNsList(cur
->nsDef
);
460 * we don't free names here they are interned now
462 if ((cur
->type
!= XML_TEXT_NODE
) &&
463 (cur
->type
!= XML_COMMENT_NODE
))
464 DICT_FREE(cur
->name
);
466 if (((cur
->type
== XML_ELEMENT_NODE
) ||
467 (cur
->type
== XML_TEXT_NODE
)) &&
468 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
469 (reader
->ctxt
->freeElemsNr
< 100)) {
470 cur
->next
= reader
->ctxt
->freeElems
;
471 reader
->ctxt
->freeElems
= cur
;
472 reader
->ctxt
->freeElemsNr
++;
479 * xmlTextReaderFreeIDTable:
480 * @table: An id table
482 * Deallocate the memory used by an ID hash table.
485 xmlTextReaderFreeIDTable(xmlIDTablePtr table
) {
486 xmlHashFree(table
, (xmlHashDeallocator
) xmlFreeID
);
490 * xmlTextReaderFreeDoc:
491 * @reader: the xmlTextReaderPtr used
492 * @cur: pointer to the document
494 * Free up all the structures used by a document, tree included.
497 xmlTextReaderFreeDoc(xmlTextReaderPtr reader
, xmlDocPtr cur
) {
498 xmlDtdPtr extSubset
, intSubset
;
500 if (cur
== NULL
) return;
502 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
503 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
506 * Do this before freeing the children list to avoid ID lookups
508 if (cur
->ids
!= NULL
) xmlTextReaderFreeIDTable((xmlIDTablePtr
) cur
->ids
);
510 if (cur
->refs
!= NULL
) xmlFreeRefTable((xmlRefTablePtr
) cur
->refs
);
512 extSubset
= cur
->extSubset
;
513 intSubset
= cur
->intSubset
;
514 if (intSubset
== extSubset
)
516 if (extSubset
!= NULL
) {
517 xmlUnlinkNode((xmlNodePtr
) cur
->extSubset
);
518 cur
->extSubset
= NULL
;
519 xmlFreeDtd(extSubset
);
521 if (intSubset
!= NULL
) {
522 xmlUnlinkNode((xmlNodePtr
) cur
->intSubset
);
523 cur
->intSubset
= NULL
;
524 xmlFreeDtd(intSubset
);
527 if (cur
->children
!= NULL
) xmlTextReaderFreeNodeList(reader
, cur
->children
);
529 if (cur
->version
!= NULL
) xmlFree((char *) cur
->version
);
530 if (cur
->name
!= NULL
) xmlFree((char *) cur
->name
);
531 if (cur
->encoding
!= NULL
) xmlFree((char *) cur
->encoding
);
532 if (cur
->oldNs
!= NULL
) xmlFreeNsList(cur
->oldNs
);
533 if (cur
->URL
!= NULL
) xmlFree((char *) cur
->URL
);
534 if (cur
->dict
!= NULL
) xmlDictFree(cur
->dict
);
539 /************************************************************************
541 * The reader core parser *
543 ************************************************************************/
546 xmlTextReaderDebug(xmlTextReaderPtr reader
) {
547 if ((reader
== NULL
) || (reader
->ctxt
== NULL
)) {
548 fprintf(stderr
, "xmlTextReader NULL\n");
551 fprintf(stderr
, "xmlTextReader: state %d depth %d ",
552 reader
->state
, reader
->depth
);
553 if (reader
->node
== NULL
) {
554 fprintf(stderr
, "node = NULL\n");
556 fprintf(stderr
, "node %s\n", reader
->node
->name
);
558 fprintf(stderr
, " input: base %d, cur %d, depth %d: ",
559 reader
->base
, reader
->cur
, reader
->ctxt
->nodeNr
);
560 if (reader
->input
->buffer
== NULL
) {
561 fprintf(stderr
, "buffer is NULL\n");
563 #ifdef LIBXML_DEBUG_ENABLED
564 xmlDebugDumpString(stderr
,
565 &reader
->input
->buffer
->content
[reader
->cur
]);
567 fprintf(stderr
, "\n");
573 * xmlTextReaderEntPush:
574 * @reader: the xmlTextReaderPtr used
575 * @value: the entity reference node
577 * Pushes a new entity reference node on top of the entities stack
579 * Returns 0 in case of error, the index in the stack otherwise
582 xmlTextReaderEntPush(xmlTextReaderPtr reader
, xmlNodePtr value
)
584 if (reader
->entMax
<= 0) {
586 reader
->entTab
= (xmlNodePtr
*) xmlMalloc(reader
->entMax
*
587 sizeof(reader
->entTab
[0]));
588 if (reader
->entTab
== NULL
) {
589 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
593 if (reader
->entNr
>= reader
->entMax
) {
596 (xmlNodePtr
*) xmlRealloc(reader
->entTab
,
598 sizeof(reader
->entTab
[0]));
599 if (reader
->entTab
== NULL
) {
600 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
604 reader
->entTab
[reader
->entNr
] = value
;
606 return (reader
->entNr
++);
610 * xmlTextReaderEntPop:
611 * @reader: the xmlTextReaderPtr used
613 * Pops the top element entity from the entities stack
615 * Returns the entity just removed
618 xmlTextReaderEntPop(xmlTextReaderPtr reader
)
622 if (reader
->entNr
<= 0)
625 if (reader
->entNr
> 0)
626 reader
->ent
= reader
->entTab
[reader
->entNr
- 1];
629 ret
= reader
->entTab
[reader
->entNr
];
630 reader
->entTab
[reader
->entNr
] = NULL
;
635 * xmlTextReaderStartElement:
636 * @ctx: the user data (XML parser context)
637 * @fullname: The element name, including namespace prefix
638 * @atts: An array of name/value attributes pairs, NULL terminated
640 * called when an opening tag has been processed.
643 xmlTextReaderStartElement(void *ctx
, const xmlChar
*fullname
,
644 const xmlChar
**atts
) {
645 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
646 xmlTextReaderPtr reader
= ctxt
->_private
;
648 #ifdef DEBUG_CALLBACKS
649 printf("xmlTextReaderStartElement(%s)\n", fullname
);
651 if ((reader
!= NULL
) && (reader
->startElement
!= NULL
)) {
652 reader
->startElement(ctx
, fullname
, atts
);
653 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
654 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
655 (ctxt
->input
->cur
[1] == '>'))
656 ctxt
->node
->extra
= NODE_IS_EMPTY
;
659 reader
->state
= XML_TEXTREADER_ELEMENT
;
663 * xmlTextReaderEndElement:
664 * @ctx: the user data (XML parser context)
665 * @fullname: The element name, including namespace prefix
667 * called when an ending tag has been processed.
670 xmlTextReaderEndElement(void *ctx
, const xmlChar
*fullname
) {
671 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
672 xmlTextReaderPtr reader
= ctxt
->_private
;
674 #ifdef DEBUG_CALLBACKS
675 printf("xmlTextReaderEndElement(%s)\n", fullname
);
677 if ((reader
!= NULL
) && (reader
->endElement
!= NULL
)) {
678 reader
->endElement(ctx
, fullname
);
683 * xmlTextReaderStartElementNs:
684 * @ctx: the user data (XML parser context)
685 * @localname: the local name of the element
686 * @prefix: the element namespace prefix if available
687 * @URI: the element namespace name if available
688 * @nb_namespaces: number of namespace definitions on that node
689 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
690 * @nb_attributes: the number of attributes on that node
691 * nb_defaulted: the number of defaulted attributes.
692 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
695 * called when an opening tag has been processed.
698 xmlTextReaderStartElementNs(void *ctx
,
699 const xmlChar
*localname
,
700 const xmlChar
*prefix
,
703 const xmlChar
**namespaces
,
706 const xmlChar
**attributes
)
708 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
709 xmlTextReaderPtr reader
= ctxt
->_private
;
711 #ifdef DEBUG_CALLBACKS
712 printf("xmlTextReaderStartElementNs(%s)\n", localname
);
714 if ((reader
!= NULL
) && (reader
->startElementNs
!= NULL
)) {
715 reader
->startElementNs(ctx
, localname
, prefix
, URI
, nb_namespaces
,
716 namespaces
, nb_attributes
, nb_defaulted
,
718 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
719 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
720 (ctxt
->input
->cur
[1] == '>'))
721 ctxt
->node
->extra
= NODE_IS_EMPTY
;
724 reader
->state
= XML_TEXTREADER_ELEMENT
;
728 * xmlTextReaderEndElementNs:
729 * @ctx: the user data (XML parser context)
730 * @localname: the local name of the element
731 * @prefix: the element namespace prefix if available
732 * @URI: the element namespace name if available
734 * called when an ending tag has been processed.
737 xmlTextReaderEndElementNs(void *ctx
,
738 const xmlChar
* localname
,
739 const xmlChar
* prefix
,
742 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
743 xmlTextReaderPtr reader
= ctxt
->_private
;
745 #ifdef DEBUG_CALLBACKS
746 printf("xmlTextReaderEndElementNs(%s)\n", localname
);
748 if ((reader
!= NULL
) && (reader
->endElementNs
!= NULL
)) {
749 reader
->endElementNs(ctx
, localname
, prefix
, URI
);
755 * xmlTextReaderCharacters:
756 * @ctx: the user data (XML parser context)
757 * @ch: a xmlChar string
758 * @len: the number of xmlChar
760 * receiving some chars from the parser.
763 xmlTextReaderCharacters(void *ctx
, const xmlChar
*ch
, int len
)
765 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
766 xmlTextReaderPtr reader
= ctxt
->_private
;
768 #ifdef DEBUG_CALLBACKS
769 printf("xmlTextReaderCharacters()\n");
771 if ((reader
!= NULL
) && (reader
->characters
!= NULL
)) {
772 reader
->characters(ctx
, ch
, len
);
777 * xmlTextReaderCDataBlock:
778 * @ctx: the user data (XML parser context)
779 * @value: The pcdata content
780 * @len: the block length
782 * called when a pcdata block has been parsed
785 xmlTextReaderCDataBlock(void *ctx
, const xmlChar
*ch
, int len
)
787 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
788 xmlTextReaderPtr reader
= ctxt
->_private
;
790 #ifdef DEBUG_CALLBACKS
791 printf("xmlTextReaderCDataBlock()\n");
793 if ((reader
!= NULL
) && (reader
->cdataBlock
!= NULL
)) {
794 reader
->cdataBlock(ctx
, ch
, len
);
799 * xmlTextReaderPushData:
800 * @reader: the xmlTextReaderPtr used
802 * Push data down the progressive parser until a significant callback
805 * Returns -1 in case of failure, 0 otherwise
808 xmlTextReaderPushData(xmlTextReaderPtr reader
) {
811 xmlTextReaderState oldstate
;
813 if ((reader
->input
== NULL
) || (reader
->input
->buffer
== NULL
))
816 oldstate
= reader
->state
;
817 reader
->state
= XML_TEXTREADER_NONE
;
818 inbuf
= reader
->input
->buffer
;
820 while (reader
->state
== XML_TEXTREADER_NONE
) {
821 if (inbuf
->use
< reader
->cur
+ CHUNK_SIZE
) {
823 * Refill the buffer unless we are at the end of the stream
825 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
826 val
= xmlParserInputBufferRead(reader
->input
, 4096);
828 (inbuf
->alloc
== XML_BUFFER_ALLOC_IMMUTABLE
)) {
829 if (inbuf
->use
== reader
->cur
) {
830 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
831 reader
->state
= oldstate
;
833 } else if (val
< 0) {
834 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
835 reader
->state
= oldstate
;
836 if ((oldstate
!= XML_TEXTREADER_START
) ||
837 (reader
->ctxt
->myDoc
!= NULL
))
839 } else if (val
== 0) {
840 /* mark the end of the stream and process the remains */
841 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
849 * parse by block of CHUNK_SIZE bytes, various tests show that
850 * it's the best tradeoff at least on a 1.2GH Duron
852 if (inbuf
->use
>= reader
->cur
+ CHUNK_SIZE
) {
853 val
= xmlParseChunk(reader
->ctxt
,
854 (const char *) &inbuf
->content
[reader
->cur
],
856 reader
->cur
+= CHUNK_SIZE
;
857 if ((val
!= 0) || (reader
->ctxt
->wellFormed
== 0))
860 s
= inbuf
->use
- reader
->cur
;
861 val
= xmlParseChunk(reader
->ctxt
,
862 (const char *) &inbuf
->content
[reader
->cur
],
865 if ((val
!= 0) || (reader
->ctxt
->wellFormed
== 0))
872 * Discard the consumed input when needed and possible
874 if (reader
->mode
== XML_TEXTREADER_MODE_INTERACTIVE
) {
875 if (inbuf
->alloc
!= XML_BUFFER_ALLOC_IMMUTABLE
) {
876 if ((reader
->cur
>= 4096) &&
877 (inbuf
->use
- reader
->cur
<= CHUNK_SIZE
)) {
878 val
= xmlBufferShrink(inbuf
, reader
->cur
);
887 * At the end of the stream signal that the work is done to the Push
890 else if (reader
->mode
== XML_TEXTREADER_MODE_EOF
) {
891 if (reader
->state
!= XML_TEXTREADER_DONE
) {
892 s
= inbuf
->use
- reader
->cur
;
893 val
= xmlParseChunk(reader
->ctxt
,
894 (const char *) &inbuf
->content
[reader
->cur
],
896 reader
->cur
= inbuf
->use
;
897 reader
->state
= XML_TEXTREADER_DONE
;
898 if ((val
!= 0) || (reader
->ctxt
->wellFormed
== 0))
902 reader
->state
= oldstate
;
906 #ifdef LIBXML_REGEXP_ENABLED
908 * xmlTextReaderValidatePush:
909 * @reader: the xmlTextReaderPtr used
911 * Push the current node for validation
914 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
) {
915 xmlNodePtr node
= reader
->node
;
917 #ifdef LIBXML_VALID_ENABLED
918 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
919 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
920 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
921 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
922 reader
->ctxt
->myDoc
, node
, node
->name
);
924 /* TODO use the BuildQName interface */
927 qname
= xmlStrdup(node
->ns
->prefix
);
928 qname
= xmlStrcat(qname
, BAD_CAST
":");
929 qname
= xmlStrcat(qname
, node
->name
);
930 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
931 reader
->ctxt
->myDoc
, node
, qname
);
936 #endif /* LIBXML_VALID_ENABLED */
937 #ifdef LIBXML_SCHEMAS_ENABLED
938 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
939 (reader
->rngValidCtxt
!= NULL
)) {
942 if (reader
->rngFullNode
!= NULL
) return;
943 ret
= xmlRelaxNGValidatePushElement(reader
->rngValidCtxt
,
948 * this element requires a full tree
950 node
= xmlTextReaderExpand(reader
);
952 printf("Expand failed !\n");
955 ret
= xmlRelaxNGValidateFullElement(reader
->rngValidCtxt
,
958 reader
->rngFullNode
= node
;
962 reader
->rngValidErrors
++;
968 * xmlTextReaderValidateCData:
969 * @reader: the xmlTextReaderPtr used
970 * @data: pointer to the CData
971 * @len: lenght of the CData block in bytes.
973 * Push some CData for validation
976 xmlTextReaderValidateCData(xmlTextReaderPtr reader
,
977 const xmlChar
*data
, int len
) {
978 #ifdef LIBXML_VALID_ENABLED
979 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
980 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
981 reader
->ctxt
->valid
&= xmlValidatePushCData(&reader
->ctxt
->vctxt
,
984 #endif /* LIBXML_VALID_ENABLED */
985 #ifdef LIBXML_SCHEMAS_ENABLED
986 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
987 (reader
->rngValidCtxt
!= NULL
)) {
990 if (reader
->rngFullNode
!= NULL
) return;
991 ret
= xmlRelaxNGValidatePushCData(reader
->rngValidCtxt
, data
, len
);
993 reader
->rngValidErrors
++;
999 * xmlTextReaderValidatePop:
1000 * @reader: the xmlTextReaderPtr used
1002 * Pop the current node from validation
1005 xmlTextReaderValidatePop(xmlTextReaderPtr reader
) {
1006 xmlNodePtr node
= reader
->node
;
1008 #ifdef LIBXML_VALID_ENABLED
1009 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
1010 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
1011 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
1012 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1013 reader
->ctxt
->myDoc
, node
, node
->name
);
1015 /* TODO use the BuildQName interface */
1018 qname
= xmlStrdup(node
->ns
->prefix
);
1019 qname
= xmlStrcat(qname
, BAD_CAST
":");
1020 qname
= xmlStrcat(qname
, node
->name
);
1021 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1022 reader
->ctxt
->myDoc
, node
, qname
);
1027 #endif /* LIBXML_VALID_ENABLED */
1028 #ifdef LIBXML_SCHEMAS_ENABLED
1029 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1030 (reader
->rngValidCtxt
!= NULL
)) {
1033 if (reader
->rngFullNode
!= NULL
) {
1034 if (node
== reader
->rngFullNode
)
1035 reader
->rngFullNode
= NULL
;
1038 ret
= xmlRelaxNGValidatePopElement(reader
->rngValidCtxt
,
1039 reader
->ctxt
->myDoc
,
1042 reader
->rngValidErrors
++;
1048 * xmlTextReaderValidateEntity:
1049 * @reader: the xmlTextReaderPtr used
1051 * Handle the validation when an entity reference is encountered and
1052 * entity substitution is not activated. As a result the parser interface
1053 * must walk through the entity and do the validation calls
1056 xmlTextReaderValidateEntity(xmlTextReaderPtr reader
) {
1057 xmlNodePtr oldnode
= reader
->node
;
1058 xmlNodePtr node
= reader
->node
;
1059 xmlParserCtxtPtr ctxt
= reader
->ctxt
;
1062 if (node
->type
== XML_ENTITY_REF_NODE
) {
1064 * Case where the underlying tree is not availble, lookup the entity
1067 if ((node
->children
== NULL
) && (ctxt
->sax
!= NULL
) &&
1068 (ctxt
->sax
->getEntity
!= NULL
)) {
1069 node
->children
= (xmlNodePtr
)
1070 ctxt
->sax
->getEntity(ctxt
, node
->name
);
1073 if ((node
->children
!= NULL
) &&
1074 (node
->children
->type
== XML_ENTITY_DECL
) &&
1075 (node
->children
->children
!= NULL
)) {
1076 xmlTextReaderEntPush(reader
, node
);
1077 node
= node
->children
->children
;
1081 * The error has probably be raised already.
1083 if (node
== oldnode
)
1087 #ifdef LIBXML_REGEXP_ENABLED
1088 } else if (node
->type
== XML_ELEMENT_NODE
) {
1089 reader
->node
= node
;
1090 xmlTextReaderValidatePush(reader
);
1091 } else if ((node
->type
== XML_TEXT_NODE
) ||
1092 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1093 xmlTextReaderValidateCData(reader
, node
->content
,
1094 xmlStrlen(node
->content
));
1101 if (node
->children
!= NULL
) {
1102 node
= node
->children
;
1104 } else if (node
->type
== XML_ELEMENT_NODE
) {
1105 xmlTextReaderValidatePop(reader
);
1107 if (node
->next
!= NULL
) {
1112 node
= node
->parent
;
1113 if (node
->type
== XML_ELEMENT_NODE
) {
1115 if (reader
->entNr
== 0) {
1116 while ((tmp
= node
->last
) != NULL
) {
1117 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1119 xmlTextReaderFreeNode(reader
, tmp
);
1124 reader
->node
= node
;
1125 xmlTextReaderValidatePop(reader
);
1127 if ((node
->type
== XML_ENTITY_DECL
) &&
1128 (reader
->ent
!= NULL
) && (reader
->ent
->children
== node
)) {
1129 node
= xmlTextReaderEntPop(reader
);
1131 if (node
== oldnode
)
1133 if (node
->next
!= NULL
) {
1137 } while ((node
!= NULL
) && (node
!= oldnode
));
1138 } while ((node
!= NULL
) && (node
!= oldnode
));
1139 reader
->node
= oldnode
;
1141 #endif /* LIBXML_REGEXP_ENABLED */
1145 * xmlTextReaderGetSuccessor:
1146 * @cur: the current node
1148 * Get the successor of a node if available.
1150 * Returns the successor node or NULL
1153 xmlTextReaderGetSuccessor(xmlNodePtr cur
) {
1154 if (cur
== NULL
) return(NULL
) ; /* ERROR */
1155 if (cur
->next
!= NULL
) return(cur
->next
) ;
1158 if (cur
== NULL
) break;
1159 if (cur
->next
!= NULL
) return(cur
->next
);
1160 } while (cur
!= NULL
);
1165 * xmlTextReaderDoExpand:
1166 * @reader: the xmlTextReaderPtr used
1168 * Makes sure that the current node is fully read as well as all its
1169 * descendant. It means the full DOM subtree must be available at the
1172 * Returns 1 if the node was expanded successfully, 0 if there is no more
1173 * nodes to read, or -1 in case of error
1176 xmlTextReaderDoExpand(xmlTextReaderPtr reader
) {
1179 if ((reader
== NULL
) || (reader
->node
== NULL
) || (reader
->ctxt
== NULL
))
1182 if (reader
->ctxt
->instate
== XML_PARSER_EOF
) return(1);
1184 if (xmlTextReaderGetSuccessor(reader
->node
) != NULL
)
1186 if (reader
->ctxt
->nodeNr
< reader
->depth
)
1188 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1190 val
= xmlTextReaderPushData(reader
);
1192 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1195 } while(reader
->mode
!= XML_TEXTREADER_MODE_EOF
);
1200 * xmlTextReaderCollectSiblings:
1201 * @node: the first child
1203 * Traverse depth-first through all sibling nodes and their children
1204 * nodes and concatenate their content. This is an auxiliary function
1205 * to xmlTextReaderReadString.
1207 * Returns a string containing the content, or NULL in case of error.
1210 xmlTextReaderCollectSiblings(xmlNodePtr node
)
1212 xmlBufferPtr buffer
;
1215 buffer
= xmlBufferCreate();
1219 for ( ; node
!= NULL
; node
= node
->next
) {
1220 switch (node
->type
) {
1222 case XML_CDATA_SECTION_NODE
:
1223 xmlBufferCat(buffer
, node
->content
);
1225 case XML_ELEMENT_NODE
: {
1228 tmp
= xmlTextReaderCollectSiblings(node
->children
);
1229 xmlBufferCat(buffer
, tmp
);
1237 ret
= buffer
->content
;
1238 buffer
->content
= NULL
;
1239 xmlBufferFree(buffer
);
1244 * xmlTextReaderRead:
1245 * @reader: the xmlTextReaderPtr used
1247 * Moves the position of the current instance to the next node in
1248 * the stream, exposing its properties.
1250 * Returns 1 if the node was read successfully, 0 if there is no more
1251 * nodes to read, or -1 in case of error
1254 xmlTextReaderRead(xmlTextReaderPtr reader
) {
1255 int val
, olddepth
= 0;
1256 xmlTextReaderState oldstate
= XML_TEXTREADER_START
;
1257 xmlNodePtr oldnode
= NULL
;
1262 reader
->curnode
= NULL
;
1263 if (reader
->doc
!= NULL
)
1264 return(xmlTextReaderReadTree(reader
));
1265 if (reader
->ctxt
== NULL
)
1267 if (reader
->ctxt
->wellFormed
!= 1)
1271 fprintf(stderr
, "\nREAD ");
1274 if (reader
->mode
== XML_TEXTREADER_MODE_INITIAL
) {
1275 reader
->mode
= XML_TEXTREADER_MODE_INTERACTIVE
;
1280 val
= xmlTextReaderPushData(reader
);
1282 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1283 reader
->state
= XML_TEXTREADER_ERROR
;
1286 } while ((reader
->ctxt
->node
== NULL
) &&
1287 ((reader
->mode
!= XML_TEXTREADER_MODE_EOF
) &&
1288 (reader
->state
!= XML_TEXTREADER_DONE
)));
1289 if (reader
->ctxt
->node
== NULL
) {
1290 if (reader
->ctxt
->myDoc
!= NULL
) {
1291 reader
->node
= reader
->ctxt
->myDoc
->children
;
1293 if (reader
->node
== NULL
){
1294 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1295 reader
->state
= XML_TEXTREADER_ERROR
;
1298 reader
->state
= XML_TEXTREADER_ELEMENT
;
1300 if (reader
->ctxt
->myDoc
!= NULL
) {
1301 reader
->node
= reader
->ctxt
->myDoc
->children
;
1303 if (reader
->node
== NULL
)
1304 reader
->node
= reader
->ctxt
->nodeTab
[0];
1305 reader
->state
= XML_TEXTREADER_ELEMENT
;
1308 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
1311 oldstate
= reader
->state
;
1312 olddepth
= reader
->ctxt
->nodeNr
;
1313 oldnode
= reader
->node
;
1316 if (reader
->node
== NULL
) {
1317 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1324 * If we are not backtracking on ancestors or examined nodes,
1325 * that the parser didn't finished or that we arent at the end
1326 * of stream, continue processing.
1328 while ((reader
->node
!= NULL
) && (reader
->node
->next
== NULL
) &&
1329 (reader
->ctxt
->nodeNr
== olddepth
) &&
1330 ((oldstate
== XML_TEXTREADER_BACKTRACK
) ||
1331 (reader
->node
->children
== NULL
) ||
1332 (reader
->node
->type
== XML_ENTITY_REF_NODE
) ||
1333 ((reader
->node
->children
!= NULL
) &&
1334 (reader
->node
->children
->type
== XML_TEXT_NODE
) &&
1335 (reader
->node
->children
->next
== NULL
)) ||
1336 (reader
->node
->type
== XML_DTD_NODE
) ||
1337 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1338 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) &&
1339 ((reader
->ctxt
->node
== NULL
) ||
1340 (reader
->ctxt
->node
== reader
->node
) ||
1341 (reader
->ctxt
->node
== reader
->node
->parent
)) &&
1342 (reader
->ctxt
->instate
!= XML_PARSER_EOF
)) {
1343 val
= xmlTextReaderPushData(reader
);
1345 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1346 reader
->state
= XML_TEXTREADER_ERROR
;
1349 if (reader
->node
== NULL
)
1352 if (oldstate
!= XML_TEXTREADER_BACKTRACK
) {
1353 if ((reader
->node
->children
!= NULL
) &&
1354 (reader
->node
->type
!= XML_ENTITY_REF_NODE
) &&
1355 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1356 (reader
->node
->type
!= XML_DTD_NODE
)) {
1357 reader
->node
= reader
->node
->children
;
1359 reader
->state
= XML_TEXTREADER_ELEMENT
;
1363 if (reader
->node
->next
!= NULL
) {
1364 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1365 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1366 (reader
->node
->children
== NULL
) &&
1367 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)
1368 #ifdef LIBXML_XINCLUDE_ENABLED
1369 && (reader
->in_xinclude
<= 0)
1372 reader
->state
= XML_TEXTREADER_END
;
1375 #ifdef LIBXML_REGEXP_ENABLED
1376 if ((reader
->validate
) &&
1377 (reader
->node
->type
== XML_ELEMENT_NODE
))
1378 xmlTextReaderValidatePop(reader
);
1379 #endif /* LIBXML_REGEXP_ENABLED */
1380 if ((reader
->preserves
> 0) &&
1381 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1382 reader
->preserves
--;
1383 reader
->node
= reader
->node
->next
;
1384 reader
->state
= XML_TEXTREADER_ELEMENT
;
1387 * Cleanup of the old node
1389 if ((reader
->preserves
== 0) &&
1390 #ifdef LIBXML_XINCLUDE_ENABLED
1391 (reader
->in_xinclude
== 0) &&
1393 (reader
->entNr
== 0) &&
1394 (reader
->node
->prev
!= NULL
) &&
1395 (reader
->node
->prev
->type
!= XML_DTD_NODE
)) {
1396 xmlNodePtr tmp
= reader
->node
->prev
;
1397 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1399 xmlTextReaderFreeNode(reader
, tmp
);
1405 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1406 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1407 (reader
->node
->children
== NULL
) &&
1408 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)) {;
1409 reader
->state
= XML_TEXTREADER_END
;
1412 #ifdef LIBXML_REGEXP_ENABLED
1413 if ((reader
->validate
) && (reader
->node
->type
== XML_ELEMENT_NODE
))
1414 xmlTextReaderValidatePop(reader
);
1415 #endif /* LIBXML_REGEXP_ENABLED */
1416 if ((reader
->preserves
> 0) &&
1417 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1418 reader
->preserves
--;
1419 reader
->node
= reader
->node
->parent
;
1420 if ((reader
->node
== NULL
) ||
1421 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1422 #ifdef LIBXML_DOCB_ENABLED
1423 (reader
->node
->type
== XML_DOCB_DOCUMENT_NODE
) ||
1425 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) {
1426 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
1427 val
= xmlParseChunk(reader
->ctxt
, "", 0, 1);
1428 reader
->state
= XML_TEXTREADER_DONE
;
1432 reader
->node
= NULL
;
1436 * Cleanup of the old node
1438 if ((oldnode
!= NULL
) && (reader
->preserves
== 0) &&
1439 #ifdef LIBXML_XINCLUDE_ENABLED
1440 (reader
->in_xinclude
== 0) &&
1442 (reader
->entNr
== 0) &&
1443 (oldnode
->type
!= XML_DTD_NODE
) &&
1444 ((oldnode
->extra
& NODE_IS_PRESERVED
) == 0)) {
1445 xmlUnlinkNode(oldnode
);
1446 xmlTextReaderFreeNode(reader
, oldnode
);
1451 if ((reader
->preserves
== 0) &&
1452 #ifdef LIBXML_XINCLUDE_ENABLED
1453 (reader
->in_xinclude
== 0) &&
1455 (reader
->entNr
== 0) &&
1456 (reader
->node
->last
!= NULL
) &&
1457 ((reader
->node
->last
->extra
& NODE_IS_PRESERVED
) == 0)) {
1458 xmlNodePtr tmp
= reader
->node
->last
;
1460 xmlTextReaderFreeNode(reader
, tmp
);
1463 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1469 * If we are in the middle of a piece of CDATA make sure it's finished
1471 if ((reader
->node
!= NULL
) &&
1472 (reader
->node
->next
== NULL
) &&
1473 ((reader
->node
->type
== XML_TEXT_NODE
) ||
1474 (reader
->node
->type
== XML_CDATA_SECTION_NODE
))) {
1475 if (xmlTextReaderExpand(reader
) == NULL
)
1479 #ifdef LIBXML_XINCLUDE_ENABLED
1481 * Handle XInclude if asked for
1483 if ((reader
->xinclude
) && (reader
->node
!= NULL
) &&
1484 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1485 (reader
->node
->ns
!= NULL
) &&
1486 ((xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_NS
)) ||
1487 (xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_OLD_NS
)))) {
1488 if (reader
->xincctxt
== NULL
) {
1489 reader
->xincctxt
= xmlXIncludeNewContext(reader
->ctxt
->myDoc
);
1490 xmlXIncludeSetFlags(reader
->xincctxt
,
1491 reader
->parserFlags
& (~XML_PARSE_NOXINCNODE
));
1494 * expand that node and process it
1496 if (xmlTextReaderExpand(reader
) == NULL
)
1498 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1500 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1501 reader
->in_xinclude
++;
1504 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1505 reader
->in_xinclude
--;
1510 * Handle entities enter and exit when in entity replacement mode
1512 if ((reader
->node
!= NULL
) &&
1513 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1514 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1516 * Case where the underlying tree is not availble, lookup the entity
1519 if ((reader
->node
->children
== NULL
) && (reader
->ctxt
->sax
!= NULL
) &&
1520 (reader
->ctxt
->sax
->getEntity
!= NULL
)) {
1521 reader
->node
->children
= (xmlNodePtr
)
1522 reader
->ctxt
->sax
->getEntity(reader
->ctxt
, reader
->node
->name
);
1525 if ((reader
->node
->children
!= NULL
) &&
1526 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1527 (reader
->node
->children
->children
!= NULL
)) {
1528 xmlTextReaderEntPush(reader
, reader
->node
);
1529 reader
->node
= reader
->node
->children
->children
;
1531 #ifdef LIBXML_REGEXP_ENABLED
1532 } else if ((reader
->node
!= NULL
) &&
1533 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1534 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1535 xmlTextReaderValidateEntity(reader
);
1536 #endif /* LIBXML_REGEXP_ENABLED */
1538 if ((reader
->node
!= NULL
) &&
1539 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1540 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1541 reader
->node
= xmlTextReaderEntPop(reader
);
1545 #ifdef LIBXML_REGEXP_ENABLED
1546 if ((reader
->validate
) && (reader
->node
!= NULL
)) {
1547 xmlNodePtr node
= reader
->node
;
1549 if ((node
->type
== XML_ELEMENT_NODE
) &&
1550 ((reader
->state
!= XML_TEXTREADER_END
) &&
1551 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1552 xmlTextReaderValidatePush(reader
);
1553 } else if ((node
->type
== XML_TEXT_NODE
) ||
1554 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1555 xmlTextReaderValidateCData(reader
, node
->content
,
1556 xmlStrlen(node
->content
));
1559 #endif /* LIBXML_REGEXP_ENABLED */
1560 #ifdef LIBXML_PATTERN_ENABLED
1561 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1562 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1564 for (i
= 0;i
< reader
->patternNr
;i
++) {
1565 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1566 xmlTextReaderPreserve(reader
);
1571 #endif /* LIBXML_PATTERN_ENABLED */
1572 #ifdef LIBXML_SCHEMAS_ENABLED
1573 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1574 (reader
->xsdValidErrors
== 0) &&
1575 (reader
->xsdValidCtxt
!= NULL
)) {
1576 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1578 #endif /* LIBXML_PATTERN_ENABLED */
1581 reader
->state
= XML_TEXTREADER_DONE
;
1586 * xmlTextReaderReadState:
1587 * @reader: the xmlTextReaderPtr used
1589 * Gets the read state of the reader.
1591 * Returns the state value, or -1 in case of error
1594 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1597 return(reader
->mode
);
1601 * xmlTextReaderExpand:
1602 * @reader: the xmlTextReaderPtr used
1604 * Reads the contents of the current node and the full subtree. It then makes
1605 * the subtree available until the next xmlTextReaderRead() call
1607 * Returns a node pointer valid until the next xmlTextReaderRead() call
1608 * or NULL in case of error.
1611 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1612 if ((reader
== NULL
) || (reader
->node
== NULL
))
1614 if (reader
->doc
!= NULL
)
1615 return(reader
->node
);
1616 if (reader
->ctxt
== NULL
)
1618 if (xmlTextReaderDoExpand(reader
) < 0)
1620 return(reader
->node
);
1624 * xmlTextReaderNext:
1625 * @reader: the xmlTextReaderPtr used
1627 * Skip to the node following the current one in document order while
1628 * avoiding the subtree if any.
1630 * Returns 1 if the node was read successfully, 0 if there is no more
1631 * nodes to read, or -1 in case of error
1634 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1640 if (reader
->doc
!= NULL
)
1641 return(xmlTextReaderNextTree(reader
));
1643 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1644 return(xmlTextReaderRead(reader
));
1645 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1646 return(xmlTextReaderRead(reader
));
1647 if (cur
->extra
& NODE_IS_EMPTY
)
1648 return(xmlTextReaderRead(reader
));
1650 ret
= xmlTextReaderRead(reader
);
1653 } while (reader
->node
!= cur
);
1654 return(xmlTextReaderRead(reader
));
1657 #ifdef LIBXML_WRITER_ENABLED
1659 * xmlTextReaderReadInnerXml:
1660 * @reader: the xmlTextReaderPtr used
1662 * Reads the contents of the current node, including child nodes and markup.
1664 * Returns a string containing the XML content, or NULL if the current node
1665 * is neither an element nor attribute, or has no child nodes. The
1666 * string must be deallocated by the caller.
1669 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1672 xmlNodePtr node
, cur_node
;
1673 xmlBufferPtr buff
, buff2
;
1676 if (xmlTextReaderExpand(reader
) == NULL
) {
1680 buff
= xmlBufferCreate();
1681 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1682 cur_node
= cur_node
->next
) {
1683 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1684 buff2
= xmlBufferCreate();
1685 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1687 xmlBufferFree(buff2
);
1688 xmlBufferFree(buff
);
1691 xmlBufferCat(buff
, buff2
->content
);
1693 xmlBufferFree(buff2
);
1695 resbuf
= buff
->content
;
1696 buff
->content
= NULL
;
1698 xmlBufferFree(buff
);
1703 #ifdef LIBXML_WRITER_ENABLED
1705 * xmlTextReaderReadOuterXml:
1706 * @reader: the xmlTextReaderPtr used
1708 * Reads the contents of the current node, including child nodes and markup.
1710 * Returns a string containing the XML content, or NULL if the current node
1711 * is neither an element nor attribute, or has no child nodes. The
1712 * string must be deallocated by the caller.
1715 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1722 node
= reader
->node
;
1724 if (xmlTextReaderExpand(reader
) == NULL
) {
1727 node
= xmlDocCopyNode(node
, doc
, 1);
1728 buff
= xmlBufferCreate();
1729 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1731 xmlBufferFree(buff
);
1735 resbuf
= buff
->content
;
1736 buff
->content
= NULL
;
1739 xmlBufferFree(buff
);
1745 * xmlTextReaderReadString:
1746 * @reader: the xmlTextReaderPtr used
1748 * Reads the contents of an element or a text node as a string.
1750 * Returns a string containing the contents of the Element or Text node,
1751 * or NULL if the reader is positioned on any other type of node.
1752 * The string must be deallocated by the caller.
1755 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1759 if ((reader
== NULL
) || (reader
->node
== NULL
))
1762 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1763 switch (node
->type
) {
1765 if (node
->content
!= NULL
)
1766 return(xmlStrdup(node
->content
));
1768 case XML_ELEMENT_NODE
:
1769 if (xmlTextReaderDoExpand(reader
) != -1) {
1770 return xmlTextReaderCollectSiblings(node
->children
);
1772 case XML_ATTRIBUTE_NODE
:
1783 * xmlTextReaderReadBase64:
1784 * @reader: the xmlTextReaderPtr used
1785 * @array: a byte array to store the content.
1786 * @offset: the zero-based index into array where the method should
1788 * @len: the number of bytes to write.
1790 * Reads and decodes the Base64 encoded contents of an element and
1791 * stores the result in a byte buffer.
1793 * Returns the number of bytes written to array, or zero if the current
1794 * instance is not positioned on an element or -1 in case of error.
1797 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1798 unsigned char *array ATTRIBUTE_UNUSED
,
1799 int offset ATTRIBUTE_UNUSED
,
1800 int len ATTRIBUTE_UNUSED
) {
1801 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1803 if (reader
->ctxt
->wellFormed
!= 1)
1806 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1813 * xmlTextReaderReadBinHex:
1814 * @reader: the xmlTextReaderPtr used
1815 * @array: a byte array to store the content.
1816 * @offset: the zero-based index into array where the method should
1818 * @len: the number of bytes to write.
1820 * Reads and decodes the BinHex encoded contents of an element and
1821 * stores the result in a byte buffer.
1823 * Returns the number of bytes written to array, or zero if the current
1824 * instance is not positioned on an element or -1 in case of error.
1827 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1828 unsigned char *array ATTRIBUTE_UNUSED
,
1829 int offset ATTRIBUTE_UNUSED
,
1830 int len ATTRIBUTE_UNUSED
) {
1831 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1833 if (reader
->ctxt
->wellFormed
!= 1)
1836 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1843 /************************************************************************
1845 * Operating on a preparsed tree *
1847 ************************************************************************/
1849 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1854 if (reader
->state
== XML_TEXTREADER_END
)
1857 if (reader
->node
== NULL
) {
1858 if (reader
->doc
->children
== NULL
) {
1859 reader
->state
= XML_TEXTREADER_END
;
1863 reader
->node
= reader
->doc
->children
;
1864 reader
->state
= XML_TEXTREADER_START
;
1868 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1869 /* Here removed traversal to child, because we want to skip the subtree,
1870 replace with traversal to sibling to skip subtree */
1871 if (reader
->node
->next
!= 0) {
1872 /* Move to sibling if present,skipping sub-tree */
1873 reader
->node
= reader
->node
->next
;
1874 reader
->state
= XML_TEXTREADER_START
;
1878 /* if reader->node->next is NULL mean no subtree for current node,
1879 so need to move to sibling of parent node if present */
1880 if ((reader
->node
->type
== XML_ELEMENT_NODE
) ||
1881 (reader
->node
->type
== XML_ATTRIBUTE_NODE
)) {
1882 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1883 /* This will move to parent if present */
1884 xmlTextReaderRead(reader
);
1888 if (reader
->node
->next
!= 0) {
1889 reader
->node
= reader
->node
->next
;
1890 reader
->state
= XML_TEXTREADER_START
;
1894 if (reader
->node
->parent
!= 0) {
1895 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1896 reader
->state
= XML_TEXTREADER_END
;
1900 reader
->node
= reader
->node
->parent
;
1902 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1903 /* Repeat process to move to sibling of parent node if present */
1904 xmlTextReaderNextTree(reader
);
1907 reader
->state
= XML_TEXTREADER_END
;
1913 * xmlTextReaderReadTree:
1914 * @reader: the xmlTextReaderPtr used
1916 * Moves the position of the current instance to the next node in
1917 * the stream, exposing its properties.
1919 * Returns 1 if the node was read successfully, 0 if there is no more
1920 * nodes to read, or -1 in case of error
1923 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1924 if (reader
->state
== XML_TEXTREADER_END
)
1928 if (reader
->node
== NULL
) {
1929 if (reader
->doc
->children
== NULL
) {
1930 reader
->state
= XML_TEXTREADER_END
;
1934 reader
->node
= reader
->doc
->children
;
1935 reader
->state
= XML_TEXTREADER_START
;
1939 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1940 (reader
->node
->type
!= XML_DTD_NODE
) &&
1941 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1942 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1943 if (reader
->node
->children
!= NULL
) {
1944 reader
->node
= reader
->node
->children
;
1946 reader
->state
= XML_TEXTREADER_START
;
1950 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1951 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1956 if (reader
->node
->next
!= NULL
) {
1957 reader
->node
= reader
->node
->next
;
1958 reader
->state
= XML_TEXTREADER_START
;
1962 if (reader
->node
->parent
!= NULL
) {
1963 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
1964 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
1965 reader
->state
= XML_TEXTREADER_END
;
1969 reader
->node
= reader
->node
->parent
;
1971 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1975 reader
->state
= XML_TEXTREADER_END
;
1978 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
1979 (reader
->node
->type
== XML_XINCLUDE_END
))
1986 * xmlTextReaderNextSibling:
1987 * @reader: the xmlTextReaderPtr used
1989 * Skip to the node following the current one in document order while
1990 * avoiding the subtree if any.
1991 * Currently implemented only for Readers built on a document
1993 * Returns 1 if the node was read successfully, 0 if there is no more
1994 * nodes to read, or -1 in case of error
1997 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
2000 if (reader
->doc
== NULL
) {
2005 if (reader
->state
== XML_TEXTREADER_END
)
2008 if (reader
->node
== NULL
)
2009 return(xmlTextReaderNextTree(reader
));
2011 if (reader
->node
->next
!= NULL
) {
2012 reader
->node
= reader
->node
->next
;
2013 reader
->state
= XML_TEXTREADER_START
;
2020 /************************************************************************
2022 * Constructor and destructors *
2024 ************************************************************************/
2027 * @input: the xmlParserInputBufferPtr used to read data
2028 * @URI: the URI information for the source if available
2030 * Create an xmlTextReader structure fed with @input
2032 * Returns the new xmlTextReaderPtr or NULL in case of error
2035 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2036 xmlTextReaderPtr ret
;
2040 ret
= xmlMalloc(sizeof(xmlTextReader
));
2042 xmlGenericError(xmlGenericErrorContext
,
2043 "xmlNewTextReader : malloc failed\n");
2046 memset(ret
, 0, sizeof(xmlTextReader
));
2052 ret
->buffer
= xmlBufferCreateSize(100);
2053 if (ret
->buffer
== NULL
) {
2055 xmlGenericError(xmlGenericErrorContext
,
2056 "xmlNewTextReader : malloc failed\n");
2059 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2060 if (ret
->sax
== NULL
) {
2061 xmlBufferFree(ret
->buffer
);
2063 xmlGenericError(xmlGenericErrorContext
,
2064 "xmlNewTextReader : malloc failed\n");
2067 xmlSAXVersion(ret
->sax
, 2);
2068 ret
->startElement
= ret
->sax
->startElement
;
2069 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2070 ret
->endElement
= ret
->sax
->endElement
;
2071 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2072 #ifdef LIBXML_SAX1_ENABLED
2073 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2074 #endif /* LIBXML_SAX1_ENABLED */
2075 ret
->startElementNs
= ret
->sax
->startElementNs
;
2076 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2077 ret
->endElementNs
= ret
->sax
->endElementNs
;
2078 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2079 #ifdef LIBXML_SAX1_ENABLED
2081 ret
->startElementNs
= NULL
;
2082 ret
->endElementNs
= NULL
;
2084 #endif /* LIBXML_SAX1_ENABLED */
2085 ret
->characters
= ret
->sax
->characters
;
2086 ret
->sax
->characters
= xmlTextReaderCharacters
;
2087 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2088 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2089 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2091 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2093 ret
->curnode
= NULL
;
2094 if (ret
->input
->buffer
->use
< 4) {
2095 xmlParserInputBufferRead(input
, 4);
2097 if (ret
->input
->buffer
->use
>= 4) {
2098 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2099 (const char *) ret
->input
->buffer
->content
, 4, URI
);
2103 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2108 if (ret
->ctxt
== NULL
) {
2109 xmlGenericError(xmlGenericErrorContext
,
2110 "xmlNewTextReader : malloc failed\n");
2111 xmlBufferFree(ret
->buffer
);
2116 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2117 ret
->ctxt
->_private
= ret
;
2118 ret
->ctxt
->linenumbers
= 1;
2119 ret
->ctxt
->dictNames
= 1;
2120 ret
->allocs
= XML_TEXTREADER_CTXT
;
2122 * use the parser dictionnary to allocate all elements and attributes names
2124 ret
->ctxt
->docdict
= 1;
2125 ret
->dict
= ret
->ctxt
->dict
;
2126 #ifdef LIBXML_XINCLUDE_ENABLED
2129 #ifdef LIBXML_PATTERN_ENABLED
2130 ret
->patternMax
= 0;
2131 ret
->patternTab
= NULL
;
2137 * xmlNewTextReaderFilename:
2138 * @URI: the URI of the resource to process
2140 * Create an xmlTextReader structure fed with the resource at @URI
2142 * Returns the new xmlTextReaderPtr or NULL in case of error
2145 xmlNewTextReaderFilename(const char *URI
) {
2146 xmlParserInputBufferPtr input
;
2147 xmlTextReaderPtr ret
;
2148 char *directory
= NULL
;
2150 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2153 ret
= xmlNewTextReader(input
, URI
);
2155 xmlFreeParserInputBuffer(input
);
2158 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2159 if (ret
->ctxt
->directory
== NULL
)
2160 directory
= xmlParserGetDirectory(URI
);
2161 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2162 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2163 if (directory
!= NULL
)
2169 * xmlFreeTextReader:
2170 * @reader: the xmlTextReaderPtr
2172 * Deallocate all the resources associated to the reader
2175 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2178 #ifdef LIBXML_SCHEMAS_ENABLED
2179 if (reader
->rngSchemas
!= NULL
) {
2180 xmlRelaxNGFree(reader
->rngSchemas
);
2181 reader
->rngSchemas
= NULL
;
2183 if (reader
->rngValidCtxt
!= NULL
) {
2184 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2185 reader
->rngValidCtxt
= NULL
;
2187 if (reader
->xsdPlug
!= NULL
) {
2188 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2189 reader
->xsdPlug
= NULL
;
2191 if (reader
->xsdValidCtxt
!= NULL
) {
2192 if (! reader
->xsdPreserveCtxt
)
2193 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2194 reader
->xsdValidCtxt
= NULL
;
2196 if (reader
->xsdSchemas
!= NULL
) {
2197 xmlSchemaFree(reader
->xsdSchemas
);
2198 reader
->xsdSchemas
= NULL
;
2201 #ifdef LIBXML_XINCLUDE_ENABLED
2202 if (reader
->xincctxt
!= NULL
)
2203 xmlXIncludeFreeContext(reader
->xincctxt
);
2205 #ifdef LIBXML_PATTERN_ENABLED
2206 if (reader
->patternTab
!= NULL
) {
2208 for (i
= 0;i
< reader
->patternNr
;i
++) {
2209 if (reader
->patternTab
[i
] != NULL
)
2210 xmlFreePattern(reader
->patternTab
[i
]);
2212 xmlFree(reader
->patternTab
);
2215 if (reader
->faketext
!= NULL
) {
2216 xmlFreeNode(reader
->faketext
);
2218 if (reader
->ctxt
!= NULL
) {
2219 if (reader
->dict
== reader
->ctxt
->dict
)
2220 reader
->dict
= NULL
;
2221 if (reader
->ctxt
->myDoc
!= NULL
) {
2222 if (reader
->preserve
== 0)
2223 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2224 reader
->ctxt
->myDoc
= NULL
;
2226 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2227 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2228 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2229 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2230 reader
->ctxt
->vctxt
.vstateMax
= 0;
2232 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2233 xmlFreeParserCtxt(reader
->ctxt
);
2235 if (reader
->sax
!= NULL
)
2236 xmlFree(reader
->sax
);
2237 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
))
2238 xmlFreeParserInputBuffer(reader
->input
);
2239 if (reader
->buffer
!= NULL
)
2240 xmlBufferFree(reader
->buffer
);
2241 if (reader
->entTab
!= NULL
)
2242 xmlFree(reader
->entTab
);
2243 if (reader
->dict
!= NULL
)
2244 xmlDictFree(reader
->dict
);
2248 /************************************************************************
2250 * Methods for XmlTextReader *
2252 ************************************************************************/
2254 * xmlTextReaderClose:
2255 * @reader: the xmlTextReaderPtr used
2257 * This method releases any resources allocated by the current instance
2258 * changes the state to Closed and close any underlying input.
2260 * Returns 0 or -1 in case of error
2263 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2266 reader
->node
= NULL
;
2267 reader
->curnode
= NULL
;
2268 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2269 if (reader
->ctxt
!= NULL
) {
2270 xmlStopParser(reader
->ctxt
);
2271 if (reader
->ctxt
->myDoc
!= NULL
) {
2272 if (reader
->preserve
== 0)
2273 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2274 reader
->ctxt
->myDoc
= NULL
;
2277 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2278 xmlFreeParserInputBuffer(reader
->input
);
2279 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2285 * xmlTextReaderGetAttributeNo:
2286 * @reader: the xmlTextReaderPtr used
2287 * @no: the zero-based index of the attribute relative to the containing element
2289 * Provides the value of the attribute with the specified index relative
2290 * to the containing element.
2292 * Returns a string containing the value of the specified attribute, or NULL
2293 * in case of error. The string must be deallocated by the caller.
2296 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2304 if (reader
->node
== NULL
)
2306 if (reader
->curnode
!= NULL
)
2308 /* TODO: handle the xmlDecl */
2309 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2312 ns
= reader
->node
->nsDef
;
2313 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2317 return(xmlStrdup(ns
->href
));
2319 cur
= reader
->node
->properties
;
2327 /* TODO walk the DTD if present */
2329 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2330 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2335 * xmlTextReaderGetAttribute:
2336 * @reader: the xmlTextReaderPtr used
2337 * @name: the qualified name of the attribute.
2339 * Provides the value of the attribute with the specified qualified name.
2341 * Returns a string containing the value of the specified attribute, or NULL
2342 * in case of error. The string must be deallocated by the caller.
2345 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2346 xmlChar
*prefix
= NULL
;
2349 xmlChar
*ret
= NULL
;
2351 if ((reader
== NULL
) || (name
== NULL
))
2353 if (reader
->node
== NULL
)
2355 if (reader
->curnode
!= NULL
)
2358 /* TODO: handle the xmlDecl */
2359 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2362 localname
= xmlSplitQName2(name
, &prefix
);
2363 if (localname
== NULL
) {
2365 * Namespace default decl
2367 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2368 ns
= reader
->node
->nsDef
;
2369 while (ns
!= NULL
) {
2370 if (ns
->prefix
== NULL
) {
2371 return(xmlStrdup(ns
->href
));
2377 return(xmlGetNoNsProp(reader
->node
, name
));
2381 * Namespace default decl
2383 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2384 ns
= reader
->node
->nsDef
;
2385 while (ns
!= NULL
) {
2386 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2387 ret
= xmlStrdup(ns
->href
);
2393 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2395 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2406 * xmlTextReaderGetAttributeNs:
2407 * @reader: the xmlTextReaderPtr used
2408 * @localName: the local name of the attribute.
2409 * @namespaceURI: the namespace URI of the attribute.
2411 * Provides the value of the specified attribute
2413 * Returns a string containing the value of the specified attribute, or NULL
2414 * in case of error. The string must be deallocated by the caller.
2417 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2418 const xmlChar
*namespaceURI
) {
2419 xmlChar
*prefix
= NULL
;
2422 if ((reader
== NULL
) || (localName
== NULL
))
2424 if (reader
->node
== NULL
)
2426 if (reader
->curnode
!= NULL
)
2429 /* TODO: handle the xmlDecl */
2430 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2433 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2434 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2435 prefix
= BAD_CAST localName
;
2437 ns
= reader
->node
->nsDef
;
2438 while (ns
!= NULL
) {
2439 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2440 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2441 return xmlStrdup(ns
->href
);
2448 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2452 * xmlTextReaderGetRemainder:
2453 * @reader: the xmlTextReaderPtr used
2455 * Method to get the remainder of the buffered XML. this method stops the
2456 * parser, set its state to End Of File and return the input stream with
2457 * what is left that the parser did not use.
2459 * The implementation is not good, the parser certainly procgressed past
2460 * what's left in reader->input, and there is an allocation problem. Best
2461 * would be to rewrite it differently.
2463 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2466 xmlParserInputBufferPtr
2467 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2468 xmlParserInputBufferPtr ret
= NULL
;
2472 if (reader
->node
== NULL
)
2475 reader
->node
= NULL
;
2476 reader
->curnode
= NULL
;
2477 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2478 if (reader
->ctxt
!= NULL
) {
2479 xmlStopParser(reader
->ctxt
);
2480 if (reader
->ctxt
->myDoc
!= NULL
) {
2481 if (reader
->preserve
== 0)
2482 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2483 reader
->ctxt
->myDoc
= NULL
;
2486 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2487 ret
= reader
->input
;
2488 reader
->input
= NULL
;
2489 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2492 * Hum, one may need to duplicate the data structure because
2493 * without reference counting the input may be freed twice:
2494 * - by the layer which allocated it.
2495 * - by the layer to which would have been returned to.
2504 * xmlTextReaderLookupNamespace:
2505 * @reader: the xmlTextReaderPtr used
2506 * @prefix: the prefix whose namespace URI is to be resolved. To return
2507 * the default namespace, specify NULL
2509 * Resolves a namespace prefix in the scope of the current element.
2511 * Returns a string containing the namespace URI to which the prefix maps
2512 * or NULL in case of error. The string must be deallocated by the caller.
2515 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2520 if (reader
->node
== NULL
)
2523 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2526 return(xmlStrdup(ns
->href
));
2530 * xmlTextReaderMoveToAttributeNo:
2531 * @reader: the xmlTextReaderPtr used
2532 * @no: the zero-based index of the attribute relative to the containing
2535 * Moves the position of the current instance to the attribute with
2536 * the specified index relative to the containing element.
2538 * Returns 1 in case of success, -1 in case of error, 0 if not found
2541 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2548 if (reader
->node
== NULL
)
2550 /* TODO: handle the xmlDecl */
2551 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2554 reader
->curnode
= NULL
;
2556 ns
= reader
->node
->nsDef
;
2557 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2561 reader
->curnode
= (xmlNodePtr
) ns
;
2565 cur
= reader
->node
->properties
;
2573 /* TODO walk the DTD if present */
2575 reader
->curnode
= (xmlNodePtr
) cur
;
2580 * xmlTextReaderMoveToAttribute:
2581 * @reader: the xmlTextReaderPtr used
2582 * @name: the qualified name of the attribute.
2584 * Moves the position of the current instance to the attribute with
2585 * the specified qualified name.
2587 * Returns 1 in case of success, -1 in case of error, 0 if not found
2590 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2591 xmlChar
*prefix
= NULL
;
2596 if ((reader
== NULL
) || (name
== NULL
))
2598 if (reader
->node
== NULL
)
2601 /* TODO: handle the xmlDecl */
2602 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2605 localname
= xmlSplitQName2(name
, &prefix
);
2606 if (localname
== NULL
) {
2608 * Namespace default decl
2610 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2611 ns
= reader
->node
->nsDef
;
2612 while (ns
!= NULL
) {
2613 if (ns
->prefix
== NULL
) {
2614 reader
->curnode
= (xmlNodePtr
) ns
;
2622 prop
= reader
->node
->properties
;
2623 while (prop
!= NULL
) {
2626 * - same attribute names
2627 * - and the attribute carrying that namespace
2629 if ((xmlStrEqual(prop
->name
, name
)) &&
2630 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2631 reader
->curnode
= (xmlNodePtr
) prop
;
2640 * Namespace default decl
2642 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2643 ns
= reader
->node
->nsDef
;
2644 while (ns
!= NULL
) {
2645 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2646 reader
->curnode
= (xmlNodePtr
) ns
;
2653 prop
= reader
->node
->properties
;
2654 while (prop
!= NULL
) {
2657 * - same attribute names
2658 * - and the attribute carrying that namespace
2660 if ((xmlStrEqual(prop
->name
, localname
)) &&
2661 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2662 reader
->curnode
= (xmlNodePtr
) prop
;
2668 if (localname
!= NULL
)
2675 if (localname
!= NULL
)
2683 * xmlTextReaderMoveToAttributeNs:
2684 * @reader: the xmlTextReaderPtr used
2685 * @localName: the local name of the attribute.
2686 * @namespaceURI: the namespace URI of the attribute.
2688 * Moves the position of the current instance to the attribute with the
2689 * specified local name and namespace URI.
2691 * Returns 1 in case of success, -1 in case of error, 0 if not found
2694 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2695 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2699 xmlChar
*prefix
= NULL
;
2701 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2703 if (reader
->node
== NULL
)
2705 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2707 node
= reader
->node
;
2709 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2710 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2711 prefix
= BAD_CAST localName
;
2713 ns
= reader
->node
->nsDef
;
2714 while (ns
!= NULL
) {
2715 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2716 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2717 reader
->curnode
= (xmlNodePtr
) ns
;
2725 prop
= node
->properties
;
2726 while (prop
!= NULL
) {
2729 * - same attribute names
2730 * - and the attribute carrying that namespace
2732 if (xmlStrEqual(prop
->name
, localName
) &&
2733 ((prop
->ns
!= NULL
) &&
2734 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2735 reader
->curnode
= (xmlNodePtr
) prop
;
2744 * xmlTextReaderMoveToFirstAttribute:
2745 * @reader: the xmlTextReaderPtr used
2747 * Moves the position of the current instance to the first attribute
2748 * associated with the current node.
2750 * Returns 1 in case of success, -1 in case of error, 0 if not found
2753 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2756 if (reader
->node
== NULL
)
2758 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2761 if (reader
->node
->nsDef
!= NULL
) {
2762 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2765 if (reader
->node
->properties
!= NULL
) {
2766 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2773 * xmlTextReaderMoveToNextAttribute:
2774 * @reader: the xmlTextReaderPtr used
2776 * Moves the position of the current instance to the next attribute
2777 * associated with the current node.
2779 * Returns 1 in case of success, -1 in case of error, 0 if not found
2782 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2785 if (reader
->node
== NULL
)
2787 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2789 if (reader
->curnode
== NULL
)
2790 return(xmlTextReaderMoveToFirstAttribute(reader
));
2792 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2793 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2794 if (ns
->next
!= NULL
) {
2795 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2798 if (reader
->node
->properties
!= NULL
) {
2799 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2803 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2804 (reader
->curnode
->next
!= NULL
)) {
2805 reader
->curnode
= reader
->curnode
->next
;
2812 * xmlTextReaderMoveToElement:
2813 * @reader: the xmlTextReaderPtr used
2815 * Moves the position of the current instance to the node that
2816 * contains the current Attribute node.
2818 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2821 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2824 if (reader
->node
== NULL
)
2826 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2828 if (reader
->curnode
!= NULL
) {
2829 reader
->curnode
= NULL
;
2836 * xmlTextReaderReadAttributeValue:
2837 * @reader: the xmlTextReaderPtr used
2839 * Parses an attribute value into one or more Text and EntityReference nodes.
2841 * Returns 1 in case of success, 0 if the reader was not positionned on an
2842 * ttribute node or all the attribute values have been read, or -1
2846 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2849 if (reader
->node
== NULL
)
2851 if (reader
->curnode
== NULL
)
2853 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2854 if (reader
->curnode
->children
== NULL
)
2856 reader
->curnode
= reader
->curnode
->children
;
2857 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2858 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2860 if (reader
->faketext
== NULL
) {
2861 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2864 if ((reader
->faketext
->content
!= NULL
) &&
2865 (reader
->faketext
->content
!=
2866 (xmlChar
*) &(reader
->faketext
->properties
)))
2867 xmlFree(reader
->faketext
->content
);
2868 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2870 reader
->curnode
= reader
->faketext
;
2872 if (reader
->curnode
->next
== NULL
)
2874 reader
->curnode
= reader
->curnode
->next
;
2880 * xmlTextReaderConstEncoding:
2881 * @reader: the xmlTextReaderPtr used
2883 * Determine the encoding of the document being read.
2885 * Returns a string containing the encoding of the document or NULL in
2886 * case of error. The string is deallocated with the reader.
2889 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2890 xmlDocPtr doc
= NULL
;
2893 if (reader
->doc
!= NULL
)
2895 else if (reader
->ctxt
!= NULL
)
2896 doc
= reader
->ctxt
->myDoc
;
2900 if (doc
->encoding
== NULL
)
2903 return(CONSTSTR(doc
->encoding
));
2907 /************************************************************************
2909 * Acces API to the current node *
2911 ************************************************************************/
2913 * xmlTextReaderAttributeCount:
2914 * @reader: the xmlTextReaderPtr used
2916 * Provides the number of attributes of the current node
2918 * Returns 0 i no attributes, -1 in case of error or the attribute count
2921 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2929 if (reader
->node
== NULL
)
2932 if (reader
->curnode
!= NULL
)
2933 node
= reader
->curnode
;
2935 node
= reader
->node
;
2937 if (node
->type
!= XML_ELEMENT_NODE
)
2939 if ((reader
->state
== XML_TEXTREADER_END
) ||
2940 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2943 attr
= node
->properties
;
2944 while (attr
!= NULL
) {
2949 while (ns
!= NULL
) {
2957 * xmlTextReaderNodeType:
2958 * @reader: the xmlTextReaderPtr used
2960 * Get the node type of the current node
2962 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
2964 * Returns the xmlNodeType of the current node or -1 in case of error
2967 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
2972 if (reader
->node
== NULL
)
2973 return(XML_READER_TYPE_NONE
);
2974 if (reader
->curnode
!= NULL
)
2975 node
= reader
->curnode
;
2977 node
= reader
->node
;
2978 switch (node
->type
) {
2979 case XML_ELEMENT_NODE
:
2980 if ((reader
->state
== XML_TEXTREADER_END
) ||
2981 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2982 return(XML_READER_TYPE_END_ELEMENT
);
2983 return(XML_READER_TYPE_ELEMENT
);
2984 case XML_NAMESPACE_DECL
:
2985 case XML_ATTRIBUTE_NODE
:
2986 return(XML_READER_TYPE_ATTRIBUTE
);
2988 if (xmlIsBlankNode(reader
->node
)) {
2989 if (xmlNodeGetSpacePreserve(reader
->node
))
2990 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
2992 return(XML_READER_TYPE_WHITESPACE
);
2994 return(XML_READER_TYPE_TEXT
);
2996 case XML_CDATA_SECTION_NODE
:
2997 return(XML_READER_TYPE_CDATA
);
2998 case XML_ENTITY_REF_NODE
:
2999 return(XML_READER_TYPE_ENTITY_REFERENCE
);
3000 case XML_ENTITY_NODE
:
3001 return(XML_READER_TYPE_ENTITY
);
3003 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
3004 case XML_COMMENT_NODE
:
3005 return(XML_READER_TYPE_COMMENT
);
3006 case XML_DOCUMENT_NODE
:
3007 case XML_HTML_DOCUMENT_NODE
:
3008 #ifdef LIBXML_DOCB_ENABLED
3009 case XML_DOCB_DOCUMENT_NODE
:
3011 return(XML_READER_TYPE_DOCUMENT
);
3012 case XML_DOCUMENT_FRAG_NODE
:
3013 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
3014 case XML_NOTATION_NODE
:
3015 return(XML_READER_TYPE_NOTATION
);
3016 case XML_DOCUMENT_TYPE_NODE
:
3018 return(XML_READER_TYPE_DOCUMENT_TYPE
);
3020 case XML_ELEMENT_DECL
:
3021 case XML_ATTRIBUTE_DECL
:
3022 case XML_ENTITY_DECL
:
3023 case XML_XINCLUDE_START
:
3024 case XML_XINCLUDE_END
:
3025 return(XML_READER_TYPE_NONE
);
3031 * xmlTextReaderIsEmptyElement:
3032 * @reader: the xmlTextReaderPtr used
3034 * Check if the current node is empty
3036 * Returns 1 if empty, 0 if not and -1 in case of error
3039 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3040 if ((reader
== NULL
) || (reader
->node
== NULL
))
3042 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3044 if (reader
->curnode
!= NULL
)
3046 if (reader
->node
->children
!= NULL
)
3048 if (reader
->state
== XML_TEXTREADER_END
)
3050 if (reader
->doc
!= NULL
)
3052 #ifdef LIBXML_XINCLUDE_ENABLED
3053 if (reader
->in_xinclude
> 0)
3056 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3060 * xmlTextReaderLocalName:
3061 * @reader: the xmlTextReaderPtr used
3063 * The local name of the node.
3065 * Returns the local name or NULL if not available,
3066 * if non NULL it need to be freed by the caller.
3069 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3071 if ((reader
== NULL
) || (reader
->node
== NULL
))
3073 if (reader
->curnode
!= NULL
)
3074 node
= reader
->curnode
;
3076 node
= reader
->node
;
3077 if (node
->type
== XML_NAMESPACE_DECL
) {
3078 xmlNsPtr ns
= (xmlNsPtr
) node
;
3079 if (ns
->prefix
== NULL
)
3080 return(xmlStrdup(BAD_CAST
"xmlns"));
3082 return(xmlStrdup(ns
->prefix
));
3084 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3085 (node
->type
!= XML_ATTRIBUTE_NODE
))
3086 return(xmlTextReaderName(reader
));
3087 return(xmlStrdup(node
->name
));
3091 * xmlTextReaderConstLocalName:
3092 * @reader: the xmlTextReaderPtr used
3094 * The local name of the node.
3096 * Returns the local name or NULL if not available, the
3097 * string will be deallocated with the reader.
3100 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3102 if ((reader
== NULL
) || (reader
->node
== NULL
))
3104 if (reader
->curnode
!= NULL
)
3105 node
= reader
->curnode
;
3107 node
= reader
->node
;
3108 if (node
->type
== XML_NAMESPACE_DECL
) {
3109 xmlNsPtr ns
= (xmlNsPtr
) node
;
3110 if (ns
->prefix
== NULL
)
3111 return(CONSTSTR(BAD_CAST
"xmlns"));
3115 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3116 (node
->type
!= XML_ATTRIBUTE_NODE
))
3117 return(xmlTextReaderConstName(reader
));
3122 * xmlTextReaderName:
3123 * @reader: the xmlTextReaderPtr used
3125 * The qualified name of the node, equal to Prefix :LocalName.
3127 * Returns the local name or NULL if not available,
3128 * if non NULL it need to be freed by the caller.
3131 xmlTextReaderName(xmlTextReaderPtr reader
) {
3135 if ((reader
== NULL
) || (reader
->node
== NULL
))
3137 if (reader
->curnode
!= NULL
)
3138 node
= reader
->curnode
;
3140 node
= reader
->node
;
3141 switch (node
->type
) {
3142 case XML_ELEMENT_NODE
:
3143 case XML_ATTRIBUTE_NODE
:
3144 if ((node
->ns
== NULL
) ||
3145 (node
->ns
->prefix
== NULL
))
3146 return(xmlStrdup(node
->name
));
3148 ret
= xmlStrdup(node
->ns
->prefix
);
3149 ret
= xmlStrcat(ret
, BAD_CAST
":");
3150 ret
= xmlStrcat(ret
, node
->name
);
3153 return(xmlStrdup(BAD_CAST
"#text"));
3154 case XML_CDATA_SECTION_NODE
:
3155 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3156 case XML_ENTITY_NODE
:
3157 case XML_ENTITY_REF_NODE
:
3158 return(xmlStrdup(node
->name
));
3160 return(xmlStrdup(node
->name
));
3161 case XML_COMMENT_NODE
:
3162 return(xmlStrdup(BAD_CAST
"#comment"));
3163 case XML_DOCUMENT_NODE
:
3164 case XML_HTML_DOCUMENT_NODE
:
3165 #ifdef LIBXML_DOCB_ENABLED
3166 case XML_DOCB_DOCUMENT_NODE
:
3168 return(xmlStrdup(BAD_CAST
"#document"));
3169 case XML_DOCUMENT_FRAG_NODE
:
3170 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3171 case XML_NOTATION_NODE
:
3172 return(xmlStrdup(node
->name
));
3173 case XML_DOCUMENT_TYPE_NODE
:
3175 return(xmlStrdup(node
->name
));
3176 case XML_NAMESPACE_DECL
: {
3177 xmlNsPtr ns
= (xmlNsPtr
) node
;
3179 ret
= xmlStrdup(BAD_CAST
"xmlns");
3180 if (ns
->prefix
== NULL
)
3182 ret
= xmlStrcat(ret
, BAD_CAST
":");
3183 ret
= xmlStrcat(ret
, ns
->prefix
);
3187 case XML_ELEMENT_DECL
:
3188 case XML_ATTRIBUTE_DECL
:
3189 case XML_ENTITY_DECL
:
3190 case XML_XINCLUDE_START
:
3191 case XML_XINCLUDE_END
:
3198 * xmlTextReaderConstName:
3199 * @reader: the xmlTextReaderPtr used
3201 * The qualified name of the node, equal to Prefix :LocalName.
3203 * Returns the local name or NULL if not available, the string is
3204 * deallocated with the reader.
3207 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3210 if ((reader
== NULL
) || (reader
->node
== NULL
))
3212 if (reader
->curnode
!= NULL
)
3213 node
= reader
->curnode
;
3215 node
= reader
->node
;
3216 switch (node
->type
) {
3217 case XML_ELEMENT_NODE
:
3218 case XML_ATTRIBUTE_NODE
:
3219 if ((node
->ns
== NULL
) ||
3220 (node
->ns
->prefix
== NULL
))
3222 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3224 return(CONSTSTR(BAD_CAST
"#text"));
3225 case XML_CDATA_SECTION_NODE
:
3226 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3227 case XML_ENTITY_NODE
:
3228 case XML_ENTITY_REF_NODE
:
3229 return(CONSTSTR(node
->name
));
3231 return(CONSTSTR(node
->name
));
3232 case XML_COMMENT_NODE
:
3233 return(CONSTSTR(BAD_CAST
"#comment"));
3234 case XML_DOCUMENT_NODE
:
3235 case XML_HTML_DOCUMENT_NODE
:
3236 #ifdef LIBXML_DOCB_ENABLED
3237 case XML_DOCB_DOCUMENT_NODE
:
3239 return(CONSTSTR(BAD_CAST
"#document"));
3240 case XML_DOCUMENT_FRAG_NODE
:
3241 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3242 case XML_NOTATION_NODE
:
3243 return(CONSTSTR(node
->name
));
3244 case XML_DOCUMENT_TYPE_NODE
:
3246 return(CONSTSTR(node
->name
));
3247 case XML_NAMESPACE_DECL
: {
3248 xmlNsPtr ns
= (xmlNsPtr
) node
;
3250 if (ns
->prefix
== NULL
)
3251 return(CONSTSTR(BAD_CAST
"xmlns"));
3252 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3255 case XML_ELEMENT_DECL
:
3256 case XML_ATTRIBUTE_DECL
:
3257 case XML_ENTITY_DECL
:
3258 case XML_XINCLUDE_START
:
3259 case XML_XINCLUDE_END
:
3266 * xmlTextReaderPrefix:
3267 * @reader: the xmlTextReaderPtr used
3269 * A shorthand reference to the namespace associated with the node.
3271 * Returns the prefix or NULL if not available,
3272 * if non NULL it need to be freed by the caller.
3275 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3277 if ((reader
== NULL
) || (reader
->node
== NULL
))
3279 if (reader
->curnode
!= NULL
)
3280 node
= reader
->curnode
;
3282 node
= reader
->node
;
3283 if (node
->type
== XML_NAMESPACE_DECL
) {
3284 xmlNsPtr ns
= (xmlNsPtr
) node
;
3285 if (ns
->prefix
== NULL
)
3287 return(xmlStrdup(BAD_CAST
"xmlns"));
3289 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3290 (node
->type
!= XML_ATTRIBUTE_NODE
))
3292 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3293 return(xmlStrdup(node
->ns
->prefix
));
3298 * xmlTextReaderConstPrefix:
3299 * @reader: the xmlTextReaderPtr used
3301 * A shorthand reference to the namespace associated with the node.
3303 * Returns the prefix or NULL if not available, the string is deallocated
3307 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3309 if ((reader
== NULL
) || (reader
->node
== NULL
))
3311 if (reader
->curnode
!= NULL
)
3312 node
= reader
->curnode
;
3314 node
= reader
->node
;
3315 if (node
->type
== XML_NAMESPACE_DECL
) {
3316 xmlNsPtr ns
= (xmlNsPtr
) node
;
3317 if (ns
->prefix
== NULL
)
3319 return(CONSTSTR(BAD_CAST
"xmlns"));
3321 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3322 (node
->type
!= XML_ATTRIBUTE_NODE
))
3324 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3325 return(CONSTSTR(node
->ns
->prefix
));
3330 * xmlTextReaderNamespaceUri:
3331 * @reader: the xmlTextReaderPtr used
3333 * The URI defining the namespace associated with the node.
3335 * Returns the namespace URI or NULL if not available,
3336 * if non NULL it need to be freed by the caller.
3339 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3341 if ((reader
== NULL
) || (reader
->node
== NULL
))
3343 if (reader
->curnode
!= NULL
)
3344 node
= reader
->curnode
;
3346 node
= reader
->node
;
3347 if (node
->type
== XML_NAMESPACE_DECL
)
3348 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3349 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3350 (node
->type
!= XML_ATTRIBUTE_NODE
))
3352 if (node
->ns
!= NULL
)
3353 return(xmlStrdup(node
->ns
->href
));
3358 * xmlTextReaderConstNamespaceUri:
3359 * @reader: the xmlTextReaderPtr used
3361 * The URI defining the namespace associated with the node.
3363 * Returns the namespace URI or NULL if not available, the string
3364 * will be deallocated with the reader
3367 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3369 if ((reader
== NULL
) || (reader
->node
== NULL
))
3371 if (reader
->curnode
!= NULL
)
3372 node
= reader
->curnode
;
3374 node
= reader
->node
;
3375 if (node
->type
== XML_NAMESPACE_DECL
)
3376 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3377 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3378 (node
->type
!= XML_ATTRIBUTE_NODE
))
3380 if (node
->ns
!= NULL
)
3381 return(CONSTSTR(node
->ns
->href
));
3386 * xmlTextReaderBaseUri:
3387 * @reader: the xmlTextReaderPtr used
3389 * The base URI of the node.
3391 * Returns the base URI or NULL if not available,
3392 * if non NULL it need to be freed by the caller.
3395 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3396 if ((reader
== NULL
) || (reader
->node
== NULL
))
3398 return(xmlNodeGetBase(NULL
, reader
->node
));
3402 * xmlTextReaderConstBaseUri:
3403 * @reader: the xmlTextReaderPtr used
3405 * The base URI of the node.
3407 * Returns the base URI or NULL if not available, the string
3408 * will be deallocated with the reader
3411 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3415 if ((reader
== NULL
) || (reader
->node
== NULL
))
3417 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3420 ret
= CONSTSTR(tmp
);
3426 * xmlTextReaderDepth:
3427 * @reader: the xmlTextReaderPtr used
3429 * The depth of the node in the tree.
3431 * Returns the depth or -1 in case of error
3434 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3437 if (reader
->node
== NULL
)
3440 if (reader
->curnode
!= NULL
) {
3441 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3442 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3443 return(reader
->depth
+ 1);
3444 return(reader
->depth
+ 2);
3446 return(reader
->depth
);
3450 * xmlTextReaderHasAttributes:
3451 * @reader: the xmlTextReaderPtr used
3453 * Whether the node has attributes.
3455 * Returns 1 if true, 0 if false, and -1 in case or error
3458 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3462 if (reader
->node
== NULL
)
3464 if (reader
->curnode
!= NULL
)
3465 node
= reader
->curnode
;
3467 node
= reader
->node
;
3469 if ((node
->type
== XML_ELEMENT_NODE
) &&
3470 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3472 /* TODO: handle the xmlDecl */
3477 * xmlTextReaderHasValue:
3478 * @reader: the xmlTextReaderPtr used
3480 * Whether the node can have a text value.
3482 * Returns 1 if true, 0 if false, and -1 in case or error
3485 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3489 if (reader
->node
== NULL
)
3491 if (reader
->curnode
!= NULL
)
3492 node
= reader
->curnode
;
3494 node
= reader
->node
;
3496 switch (node
->type
) {
3497 case XML_ATTRIBUTE_NODE
:
3499 case XML_CDATA_SECTION_NODE
:
3501 case XML_COMMENT_NODE
:
3502 case XML_NAMESPACE_DECL
:
3511 * xmlTextReaderValue:
3512 * @reader: the xmlTextReaderPtr used
3514 * Provides the text value of the node if present
3516 * Returns the string or NULL if not available. The result must be deallocated
3520 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3524 if (reader
->node
== NULL
)
3526 if (reader
->curnode
!= NULL
)
3527 node
= reader
->curnode
;
3529 node
= reader
->node
;
3531 switch (node
->type
) {
3532 case XML_NAMESPACE_DECL
:
3533 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3534 case XML_ATTRIBUTE_NODE
:{
3535 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3537 if (attr
->parent
!= NULL
)
3538 return (xmlNodeListGetString
3539 (attr
->parent
->doc
, attr
->children
, 1));
3541 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3545 case XML_CDATA_SECTION_NODE
:
3547 case XML_COMMENT_NODE
:
3548 if (node
->content
!= NULL
)
3549 return (xmlStrdup(node
->content
));
3557 * xmlTextReaderConstValue:
3558 * @reader: the xmlTextReaderPtr used
3560 * Provides the text value of the node if present
3562 * Returns the string or NULL if not available. The result will be
3563 * deallocated on the next Read() operation.
3566 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3570 if (reader
->node
== NULL
)
3572 if (reader
->curnode
!= NULL
)
3573 node
= reader
->curnode
;
3575 node
= reader
->node
;
3577 switch (node
->type
) {
3578 case XML_NAMESPACE_DECL
:
3579 return(((xmlNsPtr
) node
)->href
);
3580 case XML_ATTRIBUTE_NODE
:{
3581 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3583 if ((attr
->children
!= NULL
) &&
3584 (attr
->children
->type
== XML_TEXT_NODE
) &&
3585 (attr
->children
->next
== NULL
))
3586 return(attr
->children
->content
);
3588 if (reader
->buffer
== NULL
)
3589 reader
->buffer
= xmlBufferCreateSize(100);
3590 if (reader
->buffer
== NULL
) {
3591 xmlGenericError(xmlGenericErrorContext
,
3592 "xmlTextReaderSetup : malloc failed\n");
3595 reader
->buffer
->use
= 0;
3596 xmlNodeBufGetContent(reader
->buffer
, node
);
3597 return(reader
->buffer
->content
);
3602 case XML_CDATA_SECTION_NODE
:
3604 case XML_COMMENT_NODE
:
3605 return(node
->content
);
3613 * xmlTextReaderIsDefault:
3614 * @reader: the xmlTextReaderPtr used
3616 * Whether an Attribute node was generated from the default value
3617 * defined in the DTD or schema.
3619 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3622 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3629 * xmlTextReaderQuoteChar:
3630 * @reader: the xmlTextReaderPtr used
3632 * The quotation mark character used to enclose the value of an attribute.
3634 * Returns " or ' and -1 in case of error
3637 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3640 /* TODO maybe lookup the attribute value for " first */
3645 * xmlTextReaderXmlLang:
3646 * @reader: the xmlTextReaderPtr used
3648 * The xml:lang scope within which the node resides.
3650 * Returns the xml:lang value or NULL if none exists.,
3651 * if non NULL it need to be freed by the caller.
3654 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3657 if (reader
->node
== NULL
)
3659 return(xmlNodeGetLang(reader
->node
));
3663 * xmlTextReaderConstXmlLang:
3664 * @reader: the xmlTextReaderPtr used
3666 * The xml:lang scope within which the node resides.
3668 * Returns the xml:lang value or NULL if none exists.
3671 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3677 if (reader
->node
== NULL
)
3679 tmp
= xmlNodeGetLang(reader
->node
);
3682 ret
= CONSTSTR(tmp
);
3688 * xmlTextReaderConstString:
3689 * @reader: the xmlTextReaderPtr used
3690 * @str: the string to intern.
3692 * Get an interned string from the reader, allows for example to
3693 * speedup string name comparisons
3695 * Returns an interned copy of the string or NULL in case of error. The
3696 * string will be deallocated with the reader.
3699 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3702 return(CONSTSTR(str
));
3706 * xmlTextReaderNormalization:
3707 * @reader: the xmlTextReaderPtr used
3709 * The value indicating whether to normalize white space and attribute values.
3710 * Since attribute value and end of line normalizations are a MUST in the XML
3711 * specification only the value true is accepted. The broken bahaviour of
3712 * accepting out of range character entities like � is of course not
3715 * Returns 1 or -1 in case of error.
3718 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3724 /************************************************************************
3726 * Extensions to the base APIs *
3728 ************************************************************************/
3731 * xmlTextReaderSetParserProp:
3732 * @reader: the xmlTextReaderPtr used
3733 * @prop: the xmlParserProperties to set
3734 * @value: usually 0 or 1 to (de)activate it
3736 * Change the parser processing behaviour by changing some of its internal
3737 * properties. Note that some properties can only be changed before any
3738 * read has been done.
3740 * Returns 0 if the call was successful, or -1 in case of error
3743 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3744 xmlParserProperties p
= (xmlParserProperties
) prop
;
3745 xmlParserCtxtPtr ctxt
;
3747 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3749 ctxt
= reader
->ctxt
;
3752 case XML_PARSER_LOADDTD
:
3754 if (ctxt
->loadsubset
== 0) {
3755 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3757 ctxt
->loadsubset
= XML_DETECT_IDS
;
3760 ctxt
->loadsubset
= 0;
3763 case XML_PARSER_DEFAULTATTRS
:
3765 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3767 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3768 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3771 case XML_PARSER_VALIDATE
:
3774 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3779 case XML_PARSER_SUBST_ENTITIES
:
3781 ctxt
->replaceEntities
= 1;
3783 ctxt
->replaceEntities
= 0;
3791 * xmlTextReaderGetParserProp:
3792 * @reader: the xmlTextReaderPtr used
3793 * @prop: the xmlParserProperties to get
3795 * Read the parser internal property.
3797 * Returns the value, usually 0 or 1, or -1 in case of error.
3800 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3801 xmlParserProperties p
= (xmlParserProperties
) prop
;
3802 xmlParserCtxtPtr ctxt
;
3804 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3806 ctxt
= reader
->ctxt
;
3809 case XML_PARSER_LOADDTD
:
3810 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3813 case XML_PARSER_DEFAULTATTRS
:
3814 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3817 case XML_PARSER_VALIDATE
:
3818 return(reader
->validate
);
3819 case XML_PARSER_SUBST_ENTITIES
:
3820 return(ctxt
->replaceEntities
);
3827 * xmlTextReaderGetParserLineNumber:
3828 * @reader: the user data (XML reader context)
3830 * Provide the line number of the current parsing point.
3832 * Returns an int or 0 if not available
3835 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3837 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3838 (reader
->ctxt
->input
== NULL
)) {
3841 return (reader
->ctxt
->input
->line
);
3845 * xmlTextReaderGetParserColumnNumber:
3846 * @reader: the user data (XML reader context)
3848 * Provide the column number of the current parsing point.
3850 * Returns an int or 0 if not available
3853 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3855 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3856 (reader
->ctxt
->input
== NULL
)) {
3859 return (reader
->ctxt
->input
->col
);
3863 * xmlTextReaderCurrentNode:
3864 * @reader: the xmlTextReaderPtr used
3866 * Hacking interface allowing to get the xmlNodePtr correponding to the
3867 * current node being accessed by the xmlTextReader. This is dangerous
3868 * because the underlying node may be destroyed on the next Reads.
3870 * Returns the xmlNodePtr or NULL in case of error.
3873 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3877 if (reader
->curnode
!= NULL
)
3878 return(reader
->curnode
);
3879 return(reader
->node
);
3883 * xmlTextReaderPreserve:
3884 * @reader: the xmlTextReaderPtr used
3886 * This tells the XML Reader to preserve the current node.
3887 * The caller must also use xmlTextReaderCurrentDoc() to
3888 * keep an handle on the resulting document once parsing has finished
3890 * Returns the xmlNodePtr or NULL in case of error.
3893 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3894 xmlNodePtr cur
, parent
;
3899 if (reader
->curnode
!= NULL
)
3900 cur
= reader
->curnode
;
3906 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3907 cur
->extra
|= NODE_IS_PRESERVED
;
3908 cur
->extra
|= NODE_IS_SPRESERVED
;
3910 reader
->preserves
++;
3912 parent
= cur
->parent
;;
3913 while (parent
!= NULL
) {
3914 if (parent
->type
== XML_ELEMENT_NODE
)
3915 parent
->extra
|= NODE_IS_PRESERVED
;
3916 parent
= parent
->parent
;
3921 #ifdef LIBXML_PATTERN_ENABLED
3923 * xmlTextReaderPreservePattern:
3924 * @reader: the xmlTextReaderPtr used
3925 * @pattern: an XPath subset pattern
3926 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3928 * This tells the XML Reader to preserve all nodes matched by the
3929 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3930 * keep an handle on the resulting document once parsing has finished
3932 * Returns a positive number in case of success and -1 in case of error
3935 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3936 const xmlChar
**namespaces
)
3940 if ((reader
== NULL
) || (pattern
== NULL
))
3943 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
3947 if (reader
->patternMax
<= 0) {
3948 reader
->patternMax
= 4;
3949 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
3950 sizeof(reader
->patternTab
[0]));
3951 if (reader
->patternTab
== NULL
) {
3952 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
3956 if (reader
->patternNr
>= reader
->patternMax
) {
3958 reader
->patternMax
*= 2;
3959 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
3960 reader
->patternMax
*
3961 sizeof(reader
->patternTab
[0]));
3963 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
3964 reader
->patternMax
/= 2;
3967 reader
->patternTab
= tmp
;
3969 reader
->patternTab
[reader
->patternNr
] = comp
;
3970 return(reader
->patternNr
++);
3975 * xmlTextReaderCurrentDoc:
3976 * @reader: the xmlTextReaderPtr used
3978 * Hacking interface allowing to get the xmlDocPtr correponding to the
3979 * current document being accessed by the xmlTextReader.
3980 * NOTE: as a result of this call, the reader will not destroy the
3981 * associated XML document and calling xmlFreeDoc() on the result
3982 * is needed once the reader parsing has finished.
3984 * Returns the xmlDocPtr or NULL in case of error.
3987 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
3990 if (reader
->doc
!= NULL
)
3991 return(reader
->doc
);
3992 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
3995 reader
->preserve
= 1;
3996 return(reader
->ctxt
->myDoc
);
3999 #ifdef LIBXML_SCHEMAS_ENABLED
4000 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
);
4002 static void XMLCDECL
4003 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...);
4005 static void XMLCDECL
4006 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...);
4008 static void XMLCDECL
4009 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
4011 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4018 str
= xmlTextReaderBuildMessage(msg
, ap
);
4019 if (!reader
->errorFunc
) {
4020 xmlTextReaderValidityError(ctx
, "%s", str
);
4022 reader
->errorFunc(reader
->errorFuncArg
, str
,
4023 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4024 NULL
/* locator */ );
4031 static void XMLCDECL
4032 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4034 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4041 str
= xmlTextReaderBuildMessage(msg
, ap
);
4042 if (!reader
->errorFunc
) {
4043 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4045 reader
->errorFunc(reader
->errorFuncArg
, str
,
4046 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4047 NULL
/* locator */ );
4055 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4058 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4060 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4062 if (reader
->sErrorFunc
) {
4063 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4065 xmlTextReaderStructuredError(reader
, error
);
4069 * xmlTextReaderRelaxNGSetSchema:
4070 * @reader: the xmlTextReaderPtr used
4071 * @schema: a precompiled RelaxNG schema
4073 * Use RelaxNG to validate the document as it is processed.
4074 * Activation is only possible before the first Read().
4075 * if @schema is NULL, then RelaxNG validation is desactivated.
4076 @ The @schema should not be freed until the reader is deallocated
4077 * or its use has been deactivated.
4079 * Returns 0 in case the RelaxNG validation could be (des)activated and
4080 * -1 in case of error.
4083 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4086 if (schema
== NULL
) {
4087 if (reader
->rngSchemas
!= NULL
) {
4088 xmlRelaxNGFree(reader
->rngSchemas
);
4089 reader
->rngSchemas
= NULL
;
4091 if (reader
->rngValidCtxt
!= NULL
) {
4092 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4093 reader
->rngValidCtxt
= NULL
;
4097 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4099 if (reader
->rngSchemas
!= NULL
) {
4100 xmlRelaxNGFree(reader
->rngSchemas
);
4101 reader
->rngSchemas
= NULL
;
4103 if (reader
->rngValidCtxt
!= NULL
) {
4104 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4105 reader
->rngValidCtxt
= NULL
;
4107 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4108 if (reader
->rngValidCtxt
== NULL
)
4110 if (reader
->errorFunc
!= NULL
) {
4111 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4112 xmlTextReaderValidityErrorRelay
,
4113 xmlTextReaderValidityWarningRelay
,
4116 if (reader
->sErrorFunc
!= NULL
) {
4117 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4118 xmlTextReaderValidityStructuredRelay
,
4121 reader
->rngValidErrors
= 0;
4122 reader
->rngFullNode
= NULL
;
4123 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4128 * xmlTextReaderSetSchema:
4129 * @reader: the xmlTextReaderPtr used
4130 * @schema: a precompiled Schema schema
4132 * Use XSD Schema to validate the document as it is processed.
4133 * Activation is only possible before the first Read().
4134 * if @schema is NULL, then Schema validation is desactivated.
4135 @ The @schema should not be freed until the reader is deallocated
4136 * or its use has been deactivated.
4138 * Returns 0 in case the Schema validation could be (des)activated and
4139 * -1 in case of error.
4142 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4145 if (schema
== NULL
) {
4146 if (reader
->xsdPlug
!= NULL
) {
4147 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4148 reader
->xsdPlug
= NULL
;
4150 if (reader
->xsdValidCtxt
!= NULL
) {
4151 if (! reader
->xsdPreserveCtxt
)
4152 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4153 reader
->xsdValidCtxt
= NULL
;
4155 reader
->xsdPreserveCtxt
= 0;
4156 if (reader
->xsdSchemas
!= NULL
) {
4157 xmlSchemaFree(reader
->xsdSchemas
);
4158 reader
->xsdSchemas
= NULL
;
4162 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4164 if (reader
->xsdPlug
!= NULL
) {
4165 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4166 reader
->xsdPlug
= NULL
;
4168 if (reader
->xsdValidCtxt
!= NULL
) {
4169 if (! reader
->xsdPreserveCtxt
)
4170 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4171 reader
->xsdValidCtxt
= NULL
;
4173 reader
->xsdPreserveCtxt
= 0;
4174 if (reader
->xsdSchemas
!= NULL
) {
4175 xmlSchemaFree(reader
->xsdSchemas
);
4176 reader
->xsdSchemas
= NULL
;
4178 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4179 if (reader
->xsdValidCtxt
== NULL
) {
4180 xmlSchemaFree(reader
->xsdSchemas
);
4181 reader
->xsdSchemas
= NULL
;
4184 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4185 &(reader
->ctxt
->sax
),
4186 &(reader
->ctxt
->userData
));
4187 if (reader
->xsdPlug
== NULL
) {
4188 xmlSchemaFree(reader
->xsdSchemas
);
4189 reader
->xsdSchemas
= NULL
;
4190 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4191 reader
->xsdValidCtxt
= NULL
;
4194 if (reader
->errorFunc
!= NULL
) {
4195 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4196 xmlTextReaderValidityErrorRelay
,
4197 xmlTextReaderValidityWarningRelay
,
4200 if (reader
->sErrorFunc
!= NULL
) {
4201 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4202 xmlTextReaderValidityStructuredRelay
,
4205 reader
->xsdValidErrors
= 0;
4206 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4211 * xmlTextReaderRelaxNGValidate:
4212 * @reader: the xmlTextReaderPtr used
4213 * @rng: the path to a RelaxNG schema or NULL
4215 * Use RelaxNG to validate the document as it is processed.
4216 * Activation is only possible before the first Read().
4217 * if @rng is NULL, then RelaxNG validation is deactivated.
4219 * Returns 0 in case the RelaxNG validation could be (de)activated and
4220 * -1 in case of error.
4223 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
) {
4224 xmlRelaxNGParserCtxtPtr ctxt
;
4230 if (reader
->rngValidCtxt
!= NULL
) {
4231 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4232 reader
->rngValidCtxt
= NULL
;
4234 if (reader
->rngSchemas
!= NULL
) {
4235 xmlRelaxNGFree(reader
->rngSchemas
);
4236 reader
->rngSchemas
= NULL
;
4240 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4242 if (reader
->rngSchemas
!= NULL
) {
4243 xmlRelaxNGFree(reader
->rngSchemas
);
4244 reader
->rngSchemas
= NULL
;
4246 if (reader
->rngValidCtxt
!= NULL
) {
4247 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4248 reader
->rngValidCtxt
= NULL
;
4250 ctxt
= xmlRelaxNGNewParserCtxt(rng
);
4251 if (reader
->errorFunc
!= NULL
) {
4252 xmlRelaxNGSetParserErrors(ctxt
,
4253 xmlTextReaderValidityErrorRelay
,
4254 xmlTextReaderValidityWarningRelay
,
4257 if (reader
->sErrorFunc
!= NULL
) {
4258 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4259 xmlTextReaderValidityStructuredRelay
,
4262 reader
->rngSchemas
= xmlRelaxNGParse(ctxt
);
4263 xmlRelaxNGFreeParserCtxt(ctxt
);
4264 if (reader
->rngSchemas
== NULL
)
4266 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4267 if (reader
->rngValidCtxt
== NULL
) {
4268 xmlRelaxNGFree(reader
->rngSchemas
);
4269 reader
->rngSchemas
= NULL
;
4272 if (reader
->errorFunc
!= NULL
) {
4273 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4274 xmlTextReaderValidityErrorRelay
,
4275 xmlTextReaderValidityWarningRelay
,
4278 if (reader
->sErrorFunc
!= NULL
) {
4279 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4280 xmlTextReaderValidityStructuredRelay
,
4283 reader
->rngValidErrors
= 0;
4284 reader
->rngFullNode
= NULL
;
4285 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4290 * xmlTextReaderSchemaValidateInternal:
4291 * @reader: the xmlTextReaderPtr used
4292 * @xsd: the path to a W3C XSD schema or NULL
4293 * @ctxt: the XML Schema validation context or NULL
4294 * @options: options (not used yet)
4296 * Validate the document as it is processed using XML Schema.
4297 * Activation is only possible before the first Read().
4298 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4300 * Returns 0 in case the schemas validation could be (de)activated and
4301 * -1 in case of error.
4304 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4306 xmlSchemaValidCtxtPtr ctxt
,
4307 int options ATTRIBUTE_UNUSED
)
4312 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4315 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4316 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4317 (reader
->ctxt
== NULL
)))
4320 /* Cleanup previous validation stuff. */
4321 if (reader
->xsdPlug
!= NULL
) {
4322 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4323 reader
->xsdPlug
= NULL
;
4325 if (reader
->xsdValidCtxt
!= NULL
) {
4326 if (! reader
->xsdPreserveCtxt
)
4327 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4328 reader
->xsdValidCtxt
= NULL
;
4330 reader
->xsdPreserveCtxt
= 0;
4331 if (reader
->xsdSchemas
!= NULL
) {
4332 xmlSchemaFree(reader
->xsdSchemas
);
4333 reader
->xsdSchemas
= NULL
;
4336 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4337 /* We just want to deactivate the validation, so get out. */
4342 xmlSchemaParserCtxtPtr pctxt
;
4343 /* Parse the schema and create validation environment. */
4344 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4345 if (reader
->errorFunc
!= NULL
) {
4346 xmlSchemaSetParserErrors(pctxt
,
4347 xmlTextReaderValidityErrorRelay
,
4348 xmlTextReaderValidityWarningRelay
,
4351 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4352 xmlSchemaFreeParserCtxt(pctxt
);
4353 if (reader
->xsdSchemas
== NULL
)
4355 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4356 if (reader
->xsdValidCtxt
== NULL
) {
4357 xmlSchemaFree(reader
->xsdSchemas
);
4358 reader
->xsdSchemas
= NULL
;
4361 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4362 &(reader
->ctxt
->sax
),
4363 &(reader
->ctxt
->userData
));
4364 if (reader
->xsdPlug
== NULL
) {
4365 xmlSchemaFree(reader
->xsdSchemas
);
4366 reader
->xsdSchemas
= NULL
;
4367 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4368 reader
->xsdValidCtxt
= NULL
;
4372 /* Use the given validation context. */
4373 reader
->xsdValidCtxt
= ctxt
;
4374 reader
->xsdPreserveCtxt
= 1;
4375 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4376 &(reader
->ctxt
->sax
),
4377 &(reader
->ctxt
->userData
));
4378 if (reader
->xsdPlug
== NULL
) {
4379 reader
->xsdValidCtxt
= NULL
;
4380 reader
->xsdPreserveCtxt
= 0;
4385 * Redirect the validation context's error channels to use
4386 * the reader channels.
4387 * TODO: In case the user provides the validation context we
4388 * could make this redirection optional.
4390 if (reader
->errorFunc
!= NULL
) {
4391 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4392 xmlTextReaderValidityErrorRelay
,
4393 xmlTextReaderValidityWarningRelay
,
4396 if (reader
->sErrorFunc
!= NULL
) {
4397 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4398 xmlTextReaderValidityStructuredRelay
,
4401 reader
->xsdValidErrors
= 0;
4402 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4407 * xmlTextReaderSchemaValidateCtxt:
4408 * @reader: the xmlTextReaderPtr used
4409 * @ctxt: the XML Schema validation context or NULL
4410 * @options: options (not used yet)
4412 * Use W3C XSD schema context to validate the document as it is processed.
4413 * Activation is only possible before the first Read().
4414 * If @ctxt is NULL, then XML Schema validation is deactivated.
4416 * Returns 0 in case the schemas validation could be (de)activated and
4417 * -1 in case of error.
4420 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4421 xmlSchemaValidCtxtPtr ctxt
,
4424 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4428 * xmlTextReaderSchemaValidate:
4429 * @reader: the xmlTextReaderPtr used
4430 * @xsd: the path to a W3C XSD schema or NULL
4432 * Use W3C XSD schema to validate the document as it is processed.
4433 * Activation is only possible before the first Read().
4434 * If @xsd is NULL, then XML Schema validation is deactivated.
4436 * Returns 0 in case the schemas validation could be (de)activated and
4437 * -1 in case of error.
4440 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4442 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4447 * xmlTextReaderIsNamespaceDecl:
4448 * @reader: the xmlTextReaderPtr used
4450 * Determine whether the current node is a namespace declaration
4451 * rather than a regular attribute.
4453 * Returns 1 if the current node is a namespace declaration, 0 if it
4454 * is a regular attribute or other type of node, or -1 in case of
4458 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4462 if (reader
->node
== NULL
)
4464 if (reader
->curnode
!= NULL
)
4465 node
= reader
->curnode
;
4467 node
= reader
->node
;
4469 if (XML_NAMESPACE_DECL
== node
->type
)
4476 * xmlTextReaderConstXmlVersion:
4477 * @reader: the xmlTextReaderPtr used
4479 * Determine the XML version of the document being read.
4481 * Returns a string containing the XML version of the document or NULL
4482 * in case of error. The string is deallocated with the reader.
4485 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4486 xmlDocPtr doc
= NULL
;
4489 if (reader
->doc
!= NULL
)
4491 else if (reader
->ctxt
!= NULL
)
4492 doc
= reader
->ctxt
->myDoc
;
4496 if (doc
->version
== NULL
)
4499 return(CONSTSTR(doc
->version
));
4503 * xmlTextReaderStandalone:
4504 * @reader: the xmlTextReaderPtr used
4506 * Determine the standalone status of the document being read.
4508 * Returns 1 if the document was declared to be standalone, 0 if it
4509 * was declared to be not standalone, or -1 if the document did not
4510 * specify its standalone status or in case of error.
4513 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4514 xmlDocPtr doc
= NULL
;
4517 if (reader
->doc
!= NULL
)
4519 else if (reader
->ctxt
!= NULL
)
4520 doc
= reader
->ctxt
->myDoc
;
4524 return(doc
->standalone
);
4527 /************************************************************************
4529 * Error Handling Extensions *
4531 ************************************************************************/
4533 /* helper to build a xmlMalloc'ed string from a format and va_list */
4535 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4544 chars
= vsnprintf(str
, size
, msg
, aq
);
4547 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4552 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4554 if (chars
< MAX_ERR_MSG_SIZE
)
4557 size
= MAX_ERR_MSG_SIZE
;
4558 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4559 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4571 * xmlTextReaderLocatorLineNumber:
4572 * @locator: the xmlTextReaderLocatorPtr used
4574 * Obtain the line number for the given locator.
4576 * Returns the line number or -1 in case of error.
4579 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4580 /* we know that locator is a xmlParserCtxtPtr */
4581 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4584 if (locator
== NULL
)
4586 if (ctx
->node
!= NULL
) {
4587 ret
= xmlGetLineNo(ctx
->node
);
4590 /* inspired from error.c */
4591 xmlParserInputPtr input
;
4593 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4594 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4595 if (input
!= NULL
) {
4607 * xmlTextReaderLocatorBaseURI:
4608 * @locator: the xmlTextReaderLocatorPtr used
4610 * Obtain the base URI for the given locator.
4612 * Returns the base URI or NULL in case of error,
4613 * if non NULL it need to be freed by the caller.
4616 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4617 /* we know that locator is a xmlParserCtxtPtr */
4618 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4619 xmlChar
*ret
= NULL
;
4621 if (locator
== NULL
)
4623 if (ctx
->node
!= NULL
) {
4624 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4627 /* inspired from error.c */
4628 xmlParserInputPtr input
;
4630 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4631 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4632 if (input
!= NULL
) {
4633 ret
= xmlStrdup(BAD_CAST input
->filename
);
4644 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4647 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4649 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4652 if (reader
->errorFunc
)
4653 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4654 (xmlTextReaderLocatorPtr
) ctx
);
4660 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4662 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4664 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4666 if (error
&& reader
->sErrorFunc
) {
4667 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4671 static void XMLCDECL
4672 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4677 xmlTextReaderGenericError(ctxt
,
4678 XML_PARSER_SEVERITY_ERROR
,
4679 xmlTextReaderBuildMessage(msg
, ap
));
4684 static void XMLCDECL
4685 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4690 xmlTextReaderGenericError(ctxt
,
4691 XML_PARSER_SEVERITY_WARNING
,
4692 xmlTextReaderBuildMessage(msg
, ap
));
4696 static void XMLCDECL
4697 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4701 int len
= xmlStrlen((const xmlChar
*) msg
);
4703 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4705 * some callbacks only report locator information:
4706 * skip them (mimicking behaviour in error.c)
4709 xmlTextReaderGenericError(ctxt
,
4710 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4711 xmlTextReaderBuildMessage(msg
, ap
));
4716 static void XMLCDECL
4717 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4721 int len
= xmlStrlen((const xmlChar
*) msg
);
4723 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4725 * some callbacks only report locator information:
4726 * skip them (mimicking behaviour in error.c)
4729 xmlTextReaderGenericError(ctxt
,
4730 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4731 xmlTextReaderBuildMessage(msg
, ap
));
4737 * xmlTextReaderSetErrorHandler:
4738 * @reader: the xmlTextReaderPtr used
4739 * @f: the callback function to call on error and warnings
4740 * @arg: a user argument to pass to the callback function
4742 * Register a callback function that will be called on error and warnings.
4744 * If @f is NULL, the default error and warning handlers are restored.
4747 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4748 xmlTextReaderErrorFunc f
, void *arg
)
4751 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4752 reader
->ctxt
->sax
->serror
= NULL
;
4753 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4754 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4755 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4756 reader
->errorFunc
= f
;
4757 reader
->sErrorFunc
= NULL
;
4758 reader
->errorFuncArg
= arg
;
4759 #ifdef LIBXML_SCHEMAS_ENABLED
4760 if (reader
->rngValidCtxt
) {
4761 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4762 xmlTextReaderValidityErrorRelay
,
4763 xmlTextReaderValidityWarningRelay
,
4765 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4768 if (reader
->xsdValidCtxt
) {
4769 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4770 xmlTextReaderValidityErrorRelay
,
4771 xmlTextReaderValidityWarningRelay
,
4773 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4778 /* restore defaults */
4779 reader
->ctxt
->sax
->error
= xmlParserError
;
4780 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4781 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4782 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4783 reader
->errorFunc
= NULL
;
4784 reader
->sErrorFunc
= NULL
;
4785 reader
->errorFuncArg
= NULL
;
4786 #ifdef LIBXML_SCHEMAS_ENABLED
4787 if (reader
->rngValidCtxt
) {
4788 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4790 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4793 if (reader
->xsdValidCtxt
) {
4794 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4796 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4804 * xmlTextReaderSetStructuredErrorHandler:
4805 * @reader: the xmlTextReaderPtr used
4806 * @f: the callback function to call on error and warnings
4807 * @arg: a user argument to pass to the callback function
4809 * Register a callback function that will be called on error and warnings.
4811 * If @f is NULL, the default error and warning handlers are restored.
4814 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
4815 xmlStructuredErrorFunc f
, void *arg
)
4818 reader
->ctxt
->sax
->error
= NULL
;
4819 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
4820 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4821 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4822 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4823 reader
->sErrorFunc
= f
;
4824 reader
->errorFunc
= NULL
;
4825 reader
->errorFuncArg
= arg
;
4826 #ifdef LIBXML_SCHEMAS_ENABLED
4827 if (reader
->rngValidCtxt
) {
4828 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4830 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4831 xmlTextReaderValidityStructuredRelay
,
4834 if (reader
->xsdValidCtxt
) {
4835 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4837 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4838 xmlTextReaderValidityStructuredRelay
,
4843 /* restore defaults */
4844 reader
->ctxt
->sax
->error
= xmlParserError
;
4845 reader
->ctxt
->sax
->serror
= NULL
;
4846 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4847 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4848 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4849 reader
->errorFunc
= NULL
;
4850 reader
->sErrorFunc
= NULL
;
4851 reader
->errorFuncArg
= NULL
;
4852 #ifdef LIBXML_SCHEMAS_ENABLED
4853 if (reader
->rngValidCtxt
) {
4854 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4856 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4859 if (reader
->xsdValidCtxt
) {
4860 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4862 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4870 * xmlTextReaderIsValid:
4871 * @reader: the xmlTextReaderPtr used
4873 * Retrieve the validity status from the parser context
4875 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
4878 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
4882 #ifdef LIBXML_SCHEMAS_ENABLED
4883 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
4884 return (reader
->rngValidErrors
== 0);
4885 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
4886 return (reader
->xsdValidErrors
== 0);
4888 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
4889 return (reader
->ctxt
->valid
);
4894 * xmlTextReaderGetErrorHandler:
4895 * @reader: the xmlTextReaderPtr used
4896 * @f: the callback function or NULL is no callback has been registered
4897 * @arg: a user argument
4899 * Retrieve the error callback function and user argument.
4902 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
4903 xmlTextReaderErrorFunc
* f
, void **arg
)
4906 *f
= reader
->errorFunc
;
4908 *arg
= reader
->errorFuncArg
;
4910 /************************************************************************
4912 * New set (2.6.0) of simpler and more flexible APIs *
4914 ************************************************************************/
4917 * xmlTextReaderSetup:
4918 * @reader: an XML reader
4919 * @input: xmlParserInputBufferPtr used to feed the reader, will
4920 * be destroyed with it.
4921 * @URL: the base URL to use for the document
4922 * @encoding: the document encoding, or NULL
4923 * @options: a combination of xmlParserOption
4925 * Setup an XML reader with new options
4927 * Returns 0 in case of success and -1 in case of error.
4930 xmlTextReaderSetup(xmlTextReaderPtr reader
,
4931 xmlParserInputBufferPtr input
, const char *URL
,
4932 const char *encoding
, int options
)
4934 if (reader
== NULL
) {
4936 xmlFreeParserInputBuffer(input
);
4941 * we force the generation of compact text nodes on the reader
4942 * since usr applications should never modify the tree
4944 options
|= XML_PARSE_COMPACT
;
4948 reader
->parserFlags
= options
;
4949 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
4950 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
4951 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
4952 xmlFreeParserInputBuffer(reader
->input
);
4953 reader
->input
= NULL
;
4954 reader
->allocs
-= XML_TEXTREADER_INPUT
;
4956 if (input
!= NULL
) {
4957 reader
->input
= input
;
4958 reader
->allocs
|= XML_TEXTREADER_INPUT
;
4960 if (reader
->buffer
== NULL
)
4961 reader
->buffer
= xmlBufferCreateSize(100);
4962 if (reader
->buffer
== NULL
) {
4963 xmlGenericError(xmlGenericErrorContext
,
4964 "xmlTextReaderSetup : malloc failed\n");
4967 if (reader
->sax
== NULL
)
4968 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
4969 if (reader
->sax
== NULL
) {
4970 xmlGenericError(xmlGenericErrorContext
,
4971 "xmlTextReaderSetup : malloc failed\n");
4974 xmlSAXVersion(reader
->sax
, 2);
4975 reader
->startElement
= reader
->sax
->startElement
;
4976 reader
->sax
->startElement
= xmlTextReaderStartElement
;
4977 reader
->endElement
= reader
->sax
->endElement
;
4978 reader
->sax
->endElement
= xmlTextReaderEndElement
;
4979 #ifdef LIBXML_SAX1_ENABLED
4980 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
4981 #endif /* LIBXML_SAX1_ENABLED */
4982 reader
->startElementNs
= reader
->sax
->startElementNs
;
4983 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
4984 reader
->endElementNs
= reader
->sax
->endElementNs
;
4985 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
4986 #ifdef LIBXML_SAX1_ENABLED
4988 reader
->startElementNs
= NULL
;
4989 reader
->endElementNs
= NULL
;
4991 #endif /* LIBXML_SAX1_ENABLED */
4992 reader
->characters
= reader
->sax
->characters
;
4993 reader
->sax
->characters
= xmlTextReaderCharacters
;
4994 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
4995 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
4996 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
4998 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
4999 reader
->node
= NULL
;
5000 reader
->curnode
= NULL
;
5001 if (input
!= NULL
) {
5002 if (reader
->input
->buffer
->use
< 4) {
5003 xmlParserInputBufferRead(input
, 4);
5005 if (reader
->ctxt
== NULL
) {
5006 if (reader
->input
->buffer
->use
>= 4) {
5007 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5008 (const char *) reader
->input
->buffer
->content
, 4, URL
);
5013 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5018 xmlParserInputPtr inputStream
;
5019 xmlParserInputBufferPtr buf
;
5020 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5022 xmlCtxtReset(reader
->ctxt
);
5023 buf
= xmlAllocParserInputBuffer(enc
);
5024 if (buf
== NULL
) return(-1);
5025 inputStream
= xmlNewInputStream(reader
->ctxt
);
5026 if (inputStream
== NULL
) {
5027 xmlFreeParserInputBuffer(buf
);
5032 inputStream
->filename
= NULL
;
5034 inputStream
->filename
= (char *)
5035 xmlCanonicPath((const xmlChar
*) URL
);
5036 inputStream
->buf
= buf
;
5037 inputStream
->base
= inputStream
->buf
->buffer
->content
;
5038 inputStream
->cur
= inputStream
->buf
->buffer
->content
;
5040 &inputStream
->buf
->buffer
->content
[inputStream
->buf
->buffer
->use
];
5042 inputPush(reader
->ctxt
, inputStream
);
5045 if (reader
->ctxt
== NULL
) {
5046 xmlGenericError(xmlGenericErrorContext
,
5047 "xmlTextReaderSetup : malloc failed\n");
5051 if (reader
->dict
!= NULL
) {
5052 if (reader
->ctxt
->dict
!= NULL
) {
5053 if (reader
->dict
!= reader
->ctxt
->dict
) {
5054 xmlDictFree(reader
->dict
);
5055 reader
->dict
= reader
->ctxt
->dict
;
5058 reader
->ctxt
->dict
= reader
->dict
;
5061 if (reader
->ctxt
->dict
== NULL
)
5062 reader
->ctxt
->dict
= xmlDictCreate();
5063 reader
->dict
= reader
->ctxt
->dict
;
5065 reader
->ctxt
->_private
= reader
;
5066 reader
->ctxt
->linenumbers
= 1;
5067 reader
->ctxt
->dictNames
= 1;
5069 * use the parser dictionnary to allocate all elements and attributes names
5071 reader
->ctxt
->docdict
= 1;
5072 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5074 #ifdef LIBXML_XINCLUDE_ENABLED
5075 if (reader
->xincctxt
!= NULL
) {
5076 xmlXIncludeFreeContext(reader
->xincctxt
);
5077 reader
->xincctxt
= NULL
;
5079 if (options
& XML_PARSE_XINCLUDE
) {
5080 reader
->xinclude
= 1;
5081 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5082 options
-= XML_PARSE_XINCLUDE
;
5084 reader
->xinclude
= 0;
5085 reader
->in_xinclude
= 0;
5087 #ifdef LIBXML_PATTERN_ENABLED
5088 if (reader
->patternTab
== NULL
) {
5089 reader
->patternNr
= 0;
5090 reader
->patternMax
= 0;
5092 while (reader
->patternNr
> 0) {
5093 reader
->patternNr
--;
5094 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5095 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5096 reader
->patternTab
[reader
->patternNr
] = NULL
;
5101 if (options
& XML_PARSE_DTDVALID
)
5102 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5104 xmlCtxtUseOptions(reader
->ctxt
, options
);
5105 if (encoding
!= NULL
) {
5106 xmlCharEncodingHandlerPtr hdlr
;
5108 hdlr
= xmlFindCharEncodingHandler(encoding
);
5110 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5112 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5113 (reader
->ctxt
->input
->filename
== NULL
))
5114 reader
->ctxt
->input
->filename
= (char *)
5115 xmlStrdup((const xmlChar
*) URL
);
5123 * xmlTextReaderByteConsumed:
5124 * @reader: an XML reader
5126 * This function provides the current index of the parser used
5127 * by the reader, relative to the start of the current entity.
5128 * This function actually just wraps a call to xmlBytesConsumed()
5129 * for the parser context associated with the reader.
5130 * See xmlBytesConsumed() for more information.
5132 * Returns the index in bytes from the beginning of the entity or -1
5133 * in case the index could not be computed.
5136 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5137 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5139 return(xmlByteConsumed(reader
->ctxt
));
5145 * @doc: a preparsed document
5147 * Create an xmltextReader for a preparsed document.
5149 * Returns the new reader or NULL in case of error.
5152 xmlReaderWalker(xmlDocPtr doc
)
5154 xmlTextReaderPtr ret
;
5159 ret
= xmlMalloc(sizeof(xmlTextReader
));
5161 xmlGenericError(xmlGenericErrorContext
,
5162 "xmlNewTextReader : malloc failed\n");
5165 memset(ret
, 0, sizeof(xmlTextReader
));
5168 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5170 ret
->curnode
= NULL
;
5173 ret
->allocs
= XML_TEXTREADER_CTXT
;
5175 ret
->state
= XML_TEXTREADER_START
;
5176 ret
->dict
= xmlDictCreate();
5182 * @cur: a pointer to a zero terminated string
5183 * @URL: the base URL to use for the document
5184 * @encoding: the document encoding, or NULL
5185 * @options: a combination of xmlParserOption
5187 * Create an xmltextReader for an XML in-memory document.
5188 * The parsing flags @options are a combination of xmlParserOption.
5190 * Returns the new reader or NULL in case of error.
5193 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5200 len
= xmlStrlen(cur
);
5202 return (xmlReaderForMemory
5203 ((const char *) cur
, len
, URL
, encoding
, options
));
5208 * @filename: a file or URL
5209 * @encoding: the document encoding, or NULL
5210 * @options: a combination of xmlParserOption
5212 * parse an XML file from the filesystem or the network.
5213 * The parsing flags @options are a combination of xmlParserOption.
5215 * Returns the new reader or NULL in case of error.
5218 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5220 xmlTextReaderPtr reader
;
5222 reader
= xmlNewTextReaderFilename(filename
);
5225 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5230 * xmlReaderForMemory:
5231 * @buffer: a pointer to a char array
5232 * @size: the size of the array
5233 * @URL: the base URL to use for the document
5234 * @encoding: the document encoding, or NULL
5235 * @options: a combination of xmlParserOption
5237 * Create an xmltextReader for an XML in-memory document.
5238 * The parsing flags @options are a combination of xmlParserOption.
5240 * Returns the new reader or NULL in case of error.
5243 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5244 const char *encoding
, int options
)
5246 xmlTextReaderPtr reader
;
5247 xmlParserInputBufferPtr buf
;
5249 buf
= xmlParserInputBufferCreateStatic(buffer
, size
,
5250 XML_CHAR_ENCODING_NONE
);
5254 reader
= xmlNewTextReader(buf
, URL
);
5255 if (reader
== NULL
) {
5256 xmlFreeParserInputBuffer(buf
);
5259 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5260 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5266 * @fd: an open file descriptor
5267 * @URL: the base URL to use for the document
5268 * @encoding: the document encoding, or NULL
5269 * @options: a combination of xmlParserOption
5271 * Create an xmltextReader for an XML from a file descriptor.
5272 * The parsing flags @options are a combination of xmlParserOption.
5273 * NOTE that the file descriptor will not be closed when the
5274 * reader is closed or reset.
5276 * Returns the new reader or NULL in case of error.
5279 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5281 xmlTextReaderPtr reader
;
5282 xmlParserInputBufferPtr input
;
5287 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5290 input
->closecallback
= NULL
;
5291 reader
= xmlNewTextReader(input
, URL
);
5292 if (reader
== NULL
) {
5293 xmlFreeParserInputBuffer(input
);
5296 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5297 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5303 * @ioread: an I/O read function
5304 * @ioclose: an I/O close function
5305 * @ioctx: an I/O handler
5306 * @URL: the base URL to use for the document
5307 * @encoding: the document encoding, or NULL
5308 * @options: a combination of xmlParserOption
5310 * Create an xmltextReader for an XML document from I/O functions and source.
5311 * The parsing flags @options are a combination of xmlParserOption.
5313 * Returns the new reader or NULL in case of error.
5316 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5317 void *ioctx
, const char *URL
, const char *encoding
,
5320 xmlTextReaderPtr reader
;
5321 xmlParserInputBufferPtr input
;
5326 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5327 XML_CHAR_ENCODING_NONE
);
5330 reader
= xmlNewTextReader(input
, URL
);
5331 if (reader
== NULL
) {
5332 xmlFreeParserInputBuffer(input
);
5335 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5336 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5341 * xmlReaderNewWalker:
5342 * @reader: an XML reader
5343 * @doc: a preparsed document
5345 * Setup an xmltextReader to parse a preparsed XML document.
5346 * This reuses the existing @reader xmlTextReader.
5348 * Returns 0 in case of success and -1 in case of error
5351 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5358 if (reader
->input
!= NULL
) {
5359 xmlFreeParserInputBuffer(reader
->input
);
5361 if (reader
->ctxt
!= NULL
) {
5362 xmlCtxtReset(reader
->ctxt
);
5366 reader
->input
= NULL
;
5367 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5368 reader
->node
= NULL
;
5369 reader
->curnode
= NULL
;
5372 reader
->allocs
= XML_TEXTREADER_CTXT
;
5374 reader
->state
= XML_TEXTREADER_START
;
5375 if (reader
->dict
== NULL
) {
5376 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5377 reader
->dict
= reader
->ctxt
->dict
;
5379 reader
->dict
= xmlDictCreate();
5386 * @reader: an XML reader
5387 * @cur: a pointer to a zero terminated string
5388 * @URL: the base URL to use for the document
5389 * @encoding: the document encoding, or NULL
5390 * @options: a combination of xmlParserOption
5392 * Setup an xmltextReader to parse an XML in-memory document.
5393 * The parsing flags @options are a combination of xmlParserOption.
5394 * This reuses the existing @reader xmlTextReader.
5396 * Returns 0 in case of success and -1 in case of error
5399 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5400 const char *URL
, const char *encoding
, int options
)
5410 len
= xmlStrlen(cur
);
5411 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5412 URL
, encoding
, options
));
5417 * @reader: an XML reader
5418 * @filename: a file or URL
5419 * @encoding: the document encoding, or NULL
5420 * @options: a combination of xmlParserOption
5422 * parse an XML file from the filesystem or the network.
5423 * The parsing flags @options are a combination of xmlParserOption.
5424 * This reuses the existing @reader xmlTextReader.
5426 * Returns 0 in case of success and -1 in case of error
5429 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5430 const char *encoding
, int options
)
5432 xmlParserInputBufferPtr input
;
5434 if (filename
== NULL
)
5440 xmlParserInputBufferCreateFilename(filename
,
5441 XML_CHAR_ENCODING_NONE
);
5444 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5448 * xmlReaderNewMemory:
5449 * @reader: an XML reader
5450 * @buffer: a pointer to a char array
5451 * @size: the size of the array
5452 * @URL: the base URL to use for the document
5453 * @encoding: the document encoding, or NULL
5454 * @options: a combination of xmlParserOption
5456 * Setup an xmltextReader to parse an XML in-memory document.
5457 * The parsing flags @options are a combination of xmlParserOption.
5458 * This reuses the existing @reader xmlTextReader.
5460 * Returns 0 in case of success and -1 in case of error
5463 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5464 const char *URL
, const char *encoding
, int options
)
5466 xmlParserInputBufferPtr input
;
5473 input
= xmlParserInputBufferCreateStatic(buffer
, size
,
5474 XML_CHAR_ENCODING_NONE
);
5475 if (input
== NULL
) {
5478 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5483 * @reader: an XML reader
5484 * @fd: an open file descriptor
5485 * @URL: the base URL to use for the document
5486 * @encoding: the document encoding, or NULL
5487 * @options: a combination of xmlParserOption
5489 * Setup an xmltextReader to parse an XML from a file descriptor.
5490 * NOTE that the file descriptor will not be closed when the
5491 * reader is closed or reset.
5492 * The parsing flags @options are a combination of xmlParserOption.
5493 * This reuses the existing @reader xmlTextReader.
5495 * Returns 0 in case of success and -1 in case of error
5498 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5499 const char *URL
, const char *encoding
, int options
)
5501 xmlParserInputBufferPtr input
;
5508 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5511 input
->closecallback
= NULL
;
5512 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5517 * @reader: an XML reader
5518 * @ioread: an I/O read function
5519 * @ioclose: an I/O close function
5520 * @ioctx: an I/O handler
5521 * @URL: the base URL to use for the document
5522 * @encoding: the document encoding, or NULL
5523 * @options: a combination of xmlParserOption
5525 * Setup an xmltextReader to parse an XML document from I/O functions
5527 * The parsing flags @options are a combination of xmlParserOption.
5528 * This reuses the existing @reader xmlTextReader.
5530 * Returns 0 in case of success and -1 in case of error
5533 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5534 xmlInputCloseCallback ioclose
, void *ioctx
,
5535 const char *URL
, const char *encoding
, int options
)
5537 xmlParserInputBufferPtr input
;
5544 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5545 XML_CHAR_ENCODING_NONE
);
5548 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5550 /************************************************************************
5554 ************************************************************************/
5559 * @in: the input buffer
5560 * @inlen: the size of the input (in), the size read from it (out)
5561 * @to: the output buffer
5562 * @tolen: the size of the output (in), the size written to (out)
5564 * Base64 decoder, reads from @in and save in @to
5565 * TODO: tell jody when this is actually exported
5567 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5568 * 2 if there wasn't enough space on the output or -1 in case of error.
5571 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5572 unsigned char *to
, unsigned long *tolen
)
5574 unsigned long incur
; /* current index in in[] */
5576 unsigned long inblk
; /* last block index in in[] */
5578 unsigned long outcur
; /* current index in out[] */
5580 unsigned long inmax
; /* size of in[] */
5582 unsigned long outmax
; /* size of out[] */
5584 unsigned char cur
; /* the current value read from in[] */
5586 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5588 int nbintmp
; /* number of byte in intmp[] */
5590 int is_ignore
; /* cur should be ignored */
5592 int is_end
= 0; /* the end of the base64 was found */
5598 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5613 if ((cur
>= 'A') && (cur
<= 'Z'))
5615 else if ((cur
>= 'a') && (cur
<= 'z'))
5616 cur
= cur
- 'a' + 26;
5617 else if ((cur
>= '0') && (cur
<= '9'))
5618 cur
= cur
- '0' + 52;
5619 else if (cur
== '+')
5621 else if (cur
== '/')
5623 else if (cur
== '.')
5625 else if (cur
== '=') /*no op , end of the base64 stream */
5641 if ((nbintmp
== 1) || (nbintmp
== 2))
5648 intmp
[nbintmp
++] = cur
;
5650 * if intmp is full, push the 4byte sequence as a 3 byte
5655 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5657 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5658 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5659 if (outcur
+ 3 >= outmax
) {
5664 for (i
= 0; i
< nbouttmp
; i
++)
5665 to
[outcur
++] = outtmp
[i
];
5682 * Test routine for the xmlBase64Decode function
5686 main(int argc
, char **argv
)
5688 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5696 unsigned long inlen
= strlen(input
);
5698 unsigned long outlen
= 100;
5702 unsigned long cons
, tmp
, tmp2
, prod
;
5707 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5710 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5711 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5719 while (cons
< inlen
) {
5721 tmp2
= inlen
- cons
;
5723 printf("%ld %ld\n", cons
, prod
);
5724 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5727 printf("%ld %ld\n", cons
, prod
);
5729 output2
[outlen
] = 0;
5730 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5738 while (cons
< inlen
) {
5740 tmp2
= inlen
- cons
;
5744 printf("%ld %ld\n", cons
, prod
);
5745 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5748 printf("%ld %ld\n", cons
, prod
);
5750 output3
[outlen
] = 0;
5751 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5757 #endif /* NOT_USED_YET */
5758 #define bottom_xmlreader
5759 #include "elfgcchack.h"
5760 #endif /* LIBXML_READER_ENABLED */