2 * xmlreader.c: implements the xmlTextReader streaming node API
5 * XmlTextReader.Normalization Property won't be supported, since
6 * it makes the parser non compliant to the XML recommendation
8 * See Copyright for the status of this software.
15 * - XML Schemas validation
20 #ifdef LIBXML_READER_ENABLED
21 #include <string.h> /* for memset() only ! */
31 #include <libxml/xmlmemory.h>
32 #include <libxml/xmlIO.h>
33 #include <libxml/xmlreader.h>
34 #include <libxml/parserInternals.h>
35 #ifdef LIBXML_SCHEMAS_ENABLED
36 #include <libxml/relaxng.h>
37 #include <libxml/xmlschemas.h>
39 #include <libxml/uri.h>
40 #ifdef LIBXML_XINCLUDE_ENABLED
41 #include <libxml/xinclude.h>
43 #ifdef LIBXML_PATTERN_ENABLED
44 #include <libxml/pattern.h>
49 #define MAX_ERR_MSG_SIZE 64000
52 * The following VA_COPY was coded following an example in
53 * the Samba project. It may not be sufficient for some
54 * esoteric implementations of va_list but (hopefully) will
55 * be sufficient for libxml2.
59 #define VA_COPY(dest, src) va_copy(dest, src)
62 #define VA_COPY(dest,src) __va_copy(dest, src)
64 #ifndef VA_LIST_IS_ARRAY
65 #define VA_COPY(dest,src) (dest) = (src)
68 #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
74 /* #define DEBUG_CALLBACKS */
75 /* #define DEBUG_READER */
80 * macro to flag unimplemented blocks
83 xmlGenericError(xmlGenericErrorContext, \
84 "Unimplemented block at %s:%d\n", \
88 #define DUMP_READER xmlTextReaderDebug(reader);
93 #define CHUNK_SIZE 512
94 /************************************************************************
96 * The parser: maps the Text Reader API on top of the existing *
97 * parsing routines building a tree *
99 ************************************************************************/
101 #define XML_TEXTREADER_INPUT 1
102 #define XML_TEXTREADER_CTXT 2
105 XML_TEXTREADER_NONE
= -1,
106 XML_TEXTREADER_START
= 0,
107 XML_TEXTREADER_ELEMENT
= 1,
108 XML_TEXTREADER_END
= 2,
109 XML_TEXTREADER_EMPTY
= 3,
110 XML_TEXTREADER_BACKTRACK
= 4,
111 XML_TEXTREADER_DONE
= 5,
112 XML_TEXTREADER_ERROR
= 6
113 } xmlTextReaderState
;
116 XML_TEXTREADER_NOT_VALIDATE
= 0,
117 XML_TEXTREADER_VALIDATE_DTD
= 1,
118 XML_TEXTREADER_VALIDATE_RNG
= 2,
119 XML_TEXTREADER_VALIDATE_XSD
= 4
120 } xmlTextReaderValidate
;
122 struct _xmlTextReader
{
123 int mode
; /* the parsing mode */
124 xmlDocPtr doc
; /* when walking an existing doc */
125 xmlTextReaderValidate validate
;/* is there any validation */
126 int allocs
; /* what structure were deallocated */
127 xmlTextReaderState state
;
128 xmlParserCtxtPtr ctxt
; /* the parser context */
129 xmlSAXHandlerPtr sax
; /* the parser SAX callbacks */
130 xmlParserInputBufferPtr input
; /* the input */
131 startElementSAXFunc startElement
;/* initial SAX callbacks */
132 endElementSAXFunc endElement
; /* idem */
133 startElementNsSAX2Func startElementNs
;/* idem */
134 endElementNsSAX2Func endElementNs
; /* idem */
135 charactersSAXFunc characters
;
136 cdataBlockSAXFunc cdataBlock
;
137 unsigned int base
; /* base of the segment in the input */
138 unsigned int cur
; /* current position in the input */
139 xmlNodePtr node
; /* current node */
140 xmlNodePtr curnode
;/* current attribute node */
141 int depth
; /* depth of the current node */
142 xmlNodePtr faketext
;/* fake xmlNs chld */
143 int preserve
;/* preserve the resulting document */
144 xmlBufPtr buffer
; /* used to return const xmlChar * */
145 xmlDictPtr dict
; /* the context dictionary */
147 /* entity stack when traversing entities content */
148 xmlNodePtr ent
; /* Current Entity Ref Node */
149 int entNr
; /* Depth of the entities stack */
150 int entMax
; /* Max depth of the entities stack */
151 xmlNodePtr
*entTab
; /* array of entities */
154 xmlTextReaderErrorFunc errorFunc
; /* callback function */
155 void *errorFuncArg
; /* callback function user argument */
157 #ifdef LIBXML_SCHEMAS_ENABLED
158 /* Handling of RelaxNG validation */
159 xmlRelaxNGPtr rngSchemas
; /* The Relax NG schemas */
160 xmlRelaxNGValidCtxtPtr rngValidCtxt
;/* The Relax NG validation context */
161 int rngPreserveCtxt
; /* 1 if the context was provided by the user */
162 int rngValidErrors
;/* The number of errors detected */
163 xmlNodePtr rngFullNode
; /* the node if RNG not progressive */
164 /* Handling of Schemas validation */
165 xmlSchemaPtr xsdSchemas
; /* The Schemas schemas */
166 xmlSchemaValidCtxtPtr xsdValidCtxt
;/* The Schemas validation context */
167 int xsdPreserveCtxt
; /* 1 if the context was provided by the user */
168 int xsdValidErrors
;/* The number of errors detected */
169 xmlSchemaSAXPlugPtr xsdPlug
; /* the schemas plug in SAX pipeline */
171 #ifdef LIBXML_XINCLUDE_ENABLED
172 /* Handling of XInclude processing */
173 int xinclude
; /* is xinclude asked for */
174 const xmlChar
* xinclude_name
; /* the xinclude name from dict */
175 xmlXIncludeCtxtPtr xincctxt
; /* the xinclude context */
176 int in_xinclude
; /* counts for xinclude */
178 #ifdef LIBXML_PATTERN_ENABLED
179 int patternNr
; /* number of preserve patterns */
180 int patternMax
; /* max preserve patterns */
181 xmlPatternPtr
*patternTab
; /* array of preserve patterns */
183 int preserves
; /* level of preserves */
184 int parserFlags
; /* the set of options set */
185 /* Structured error handling */
186 xmlStructuredErrorFunc sErrorFunc
; /* callback function */
189 #define NODE_IS_EMPTY 0x1
190 #define NODE_IS_PRESERVED 0x2
191 #define NODE_IS_SPRESERVED 0x4
196 * Macro used to return an interned string
198 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
199 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
201 static int xmlTextReaderReadTree(xmlTextReaderPtr reader
);
202 static int xmlTextReaderNextTree(xmlTextReaderPtr reader
);
204 /************************************************************************
206 * Our own version of the freeing routines as we recycle nodes *
208 ************************************************************************/
213 * Free a string if it is not owned by the "dict" dictionary in the
216 #define DICT_FREE(str) \
217 if ((str) && ((!dict) || \
218 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
219 xmlFree((char *)(str));
221 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
);
222 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
);
228 * Deallocate the memory used by an id definition
231 xmlFreeID(xmlIDPtr id
) {
232 xmlDictPtr dict
= NULL
;
234 if (id
== NULL
) return;
237 dict
= id
->doc
->dict
;
239 if (id
->value
!= NULL
)
245 * xmlTextReaderRemoveID:
247 * @attr: the attribute
249 * Remove the given attribute from the ID table maintained internally.
251 * Returns -1 if the lookup failed and 0 otherwise
254 xmlTextReaderRemoveID(xmlDocPtr doc
, xmlAttrPtr attr
) {
259 if (doc
== NULL
) return(-1);
260 if (attr
== NULL
) return(-1);
261 table
= (xmlIDTablePtr
) doc
->ids
;
265 ID
= xmlNodeListGetString(doc
, attr
->children
, 1);
268 id
= xmlHashLookup(table
, ID
);
270 if (id
== NULL
|| id
->attr
!= attr
) {
273 id
->name
= attr
->name
;
279 * xmlTextReaderFreeProp:
280 * @reader: the xmlTextReaderPtr used
286 xmlTextReaderFreeProp(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
289 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
290 dict
= reader
->ctxt
->dict
;
293 if (cur
== NULL
) return;
295 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
296 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
298 /* Check for ID removal -> leading to invalid references ! */
299 if ((cur
->parent
!= NULL
) && (cur
->parent
->doc
!= NULL
) &&
300 ((cur
->parent
->doc
->intSubset
!= NULL
) ||
301 (cur
->parent
->doc
->extSubset
!= NULL
))) {
302 if (xmlIsID(cur
->parent
->doc
, cur
->parent
, cur
))
303 xmlTextReaderRemoveID(cur
->parent
->doc
, cur
);
305 if (cur
->children
!= NULL
)
306 xmlTextReaderFreeNodeList(reader
, cur
->children
);
308 DICT_FREE(cur
->name
);
309 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
310 (reader
->ctxt
->freeAttrsNr
< 100)) {
311 cur
->next
= reader
->ctxt
->freeAttrs
;
312 reader
->ctxt
->freeAttrs
= cur
;
313 reader
->ctxt
->freeAttrsNr
++;
320 * xmlTextReaderFreePropList:
321 * @reader: the xmlTextReaderPtr used
322 * @cur: the first property in the list
324 * Free a property and all its siblings, all the children are freed too.
327 xmlTextReaderFreePropList(xmlTextReaderPtr reader
, xmlAttrPtr cur
) {
330 while (cur
!= NULL
) {
332 xmlTextReaderFreeProp(reader
, cur
);
338 * xmlTextReaderFreeNodeList:
339 * @reader: the xmlTextReaderPtr used
340 * @cur: the first node in the list
342 * Free a node and all its siblings, this is a recursive behaviour, all
343 * the children are freed too.
346 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
350 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
351 dict
= reader
->ctxt
->dict
;
354 if (cur
== NULL
) return;
355 if (cur
->type
== XML_NAMESPACE_DECL
) {
356 xmlFreeNsList((xmlNsPtr
) cur
);
359 if ((cur
->type
== XML_DOCUMENT_NODE
) ||
360 (cur
->type
== XML_HTML_DOCUMENT_NODE
)) {
361 xmlFreeDoc((xmlDocPtr
) cur
);
364 while (cur
!= NULL
) {
366 /* unroll to speed up freeing the document */
367 if (cur
->type
!= XML_DTD_NODE
) {
369 if ((cur
->children
!= NULL
) &&
370 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
371 if (cur
->children
->parent
== cur
)
372 xmlTextReaderFreeNodeList(reader
, cur
->children
);
373 cur
->children
= NULL
;
376 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
377 xmlDeregisterNodeDefaultValue(cur
);
379 if (((cur
->type
== XML_ELEMENT_NODE
) ||
380 (cur
->type
== XML_XINCLUDE_START
) ||
381 (cur
->type
== XML_XINCLUDE_END
)) &&
382 (cur
->properties
!= NULL
))
383 xmlTextReaderFreePropList(reader
, cur
->properties
);
384 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
385 (cur
->type
!= XML_ELEMENT_NODE
) &&
386 (cur
->type
!= XML_XINCLUDE_START
) &&
387 (cur
->type
!= XML_XINCLUDE_END
) &&
388 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
389 DICT_FREE(cur
->content
);
391 if (((cur
->type
== XML_ELEMENT_NODE
) ||
392 (cur
->type
== XML_XINCLUDE_START
) ||
393 (cur
->type
== XML_XINCLUDE_END
)) &&
394 (cur
->nsDef
!= NULL
))
395 xmlFreeNsList(cur
->nsDef
);
398 * we don't free element names here they are interned now
400 if ((cur
->type
!= XML_TEXT_NODE
) &&
401 (cur
->type
!= XML_COMMENT_NODE
))
402 DICT_FREE(cur
->name
);
403 if (((cur
->type
== XML_ELEMENT_NODE
) ||
404 (cur
->type
== XML_TEXT_NODE
)) &&
405 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
406 (reader
->ctxt
->freeElemsNr
< 100)) {
407 cur
->next
= reader
->ctxt
->freeElems
;
408 reader
->ctxt
->freeElems
= cur
;
409 reader
->ctxt
->freeElemsNr
++;
419 * xmlTextReaderFreeNode:
420 * @reader: the xmlTextReaderPtr used
423 * Free a node, this is a recursive behaviour, all the children are freed too.
424 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
427 xmlTextReaderFreeNode(xmlTextReaderPtr reader
, xmlNodePtr cur
) {
430 if ((reader
!= NULL
) && (reader
->ctxt
!= NULL
))
431 dict
= reader
->ctxt
->dict
;
434 if (cur
->type
== XML_DTD_NODE
) {
435 xmlFreeDtd((xmlDtdPtr
) cur
);
438 if (cur
->type
== XML_NAMESPACE_DECL
) {
439 xmlFreeNs((xmlNsPtr
) cur
);
442 if (cur
->type
== XML_ATTRIBUTE_NODE
) {
443 xmlTextReaderFreeProp(reader
, (xmlAttrPtr
) cur
);
447 if ((cur
->children
!= NULL
) &&
448 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
449 if (cur
->children
->parent
== cur
)
450 xmlTextReaderFreeNodeList(reader
, cur
->children
);
451 cur
->children
= NULL
;
454 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
455 xmlDeregisterNodeDefaultValue(cur
);
457 if (((cur
->type
== XML_ELEMENT_NODE
) ||
458 (cur
->type
== XML_XINCLUDE_START
) ||
459 (cur
->type
== XML_XINCLUDE_END
)) &&
460 (cur
->properties
!= NULL
))
461 xmlTextReaderFreePropList(reader
, cur
->properties
);
462 if ((cur
->content
!= (xmlChar
*) &(cur
->properties
)) &&
463 (cur
->type
!= XML_ELEMENT_NODE
) &&
464 (cur
->type
!= XML_XINCLUDE_START
) &&
465 (cur
->type
!= XML_XINCLUDE_END
) &&
466 (cur
->type
!= XML_ENTITY_REF_NODE
)) {
467 DICT_FREE(cur
->content
);
469 if (((cur
->type
== XML_ELEMENT_NODE
) ||
470 (cur
->type
== XML_XINCLUDE_START
) ||
471 (cur
->type
== XML_XINCLUDE_END
)) &&
472 (cur
->nsDef
!= NULL
))
473 xmlFreeNsList(cur
->nsDef
);
476 * we don't free names here they are interned now
478 if ((cur
->type
!= XML_TEXT_NODE
) &&
479 (cur
->type
!= XML_COMMENT_NODE
))
480 DICT_FREE(cur
->name
);
482 if (((cur
->type
== XML_ELEMENT_NODE
) ||
483 (cur
->type
== XML_TEXT_NODE
)) &&
484 (reader
!= NULL
) && (reader
->ctxt
!= NULL
) &&
485 (reader
->ctxt
->freeElemsNr
< 100)) {
486 cur
->next
= reader
->ctxt
->freeElems
;
487 reader
->ctxt
->freeElems
= cur
;
488 reader
->ctxt
->freeElemsNr
++;
495 xmlTextReaderFreeIDTableEntry(void *id
, const xmlChar
*name ATTRIBUTE_UNUSED
) {
496 xmlFreeID((xmlIDPtr
) id
);
500 * xmlTextReaderFreeIDTable:
501 * @table: An id table
503 * Deallocate the memory used by an ID hash table.
506 xmlTextReaderFreeIDTable(xmlIDTablePtr table
) {
507 xmlHashFree(table
, xmlTextReaderFreeIDTableEntry
);
511 * xmlTextReaderFreeDoc:
512 * @reader: the xmlTextReaderPtr used
513 * @cur: pointer to the document
515 * Free up all the structures used by a document, tree included.
518 xmlTextReaderFreeDoc(xmlTextReaderPtr reader
, xmlDocPtr cur
) {
519 xmlDtdPtr extSubset
, intSubset
;
521 if (cur
== NULL
) return;
523 if ((__xmlRegisterCallbacks
) && (xmlDeregisterNodeDefaultValue
))
524 xmlDeregisterNodeDefaultValue((xmlNodePtr
) cur
);
527 * Do this before freeing the children list to avoid ID lookups
529 if (cur
->ids
!= NULL
) xmlTextReaderFreeIDTable((xmlIDTablePtr
) cur
->ids
);
531 if (cur
->refs
!= NULL
) xmlFreeRefTable((xmlRefTablePtr
) cur
->refs
);
533 extSubset
= cur
->extSubset
;
534 intSubset
= cur
->intSubset
;
535 if (intSubset
== extSubset
)
537 if (extSubset
!= NULL
) {
538 xmlUnlinkNode((xmlNodePtr
) cur
->extSubset
);
539 cur
->extSubset
= NULL
;
540 xmlFreeDtd(extSubset
);
542 if (intSubset
!= NULL
) {
543 xmlUnlinkNode((xmlNodePtr
) cur
->intSubset
);
544 cur
->intSubset
= NULL
;
545 xmlFreeDtd(intSubset
);
548 if (cur
->children
!= NULL
) xmlTextReaderFreeNodeList(reader
, cur
->children
);
550 if (cur
->version
!= NULL
) xmlFree((char *) cur
->version
);
551 if (cur
->name
!= NULL
) xmlFree((char *) cur
->name
);
552 if (cur
->encoding
!= NULL
) xmlFree((char *) cur
->encoding
);
553 if (cur
->oldNs
!= NULL
) xmlFreeNsList(cur
->oldNs
);
554 if (cur
->URL
!= NULL
) xmlFree((char *) cur
->URL
);
555 if (cur
->dict
!= NULL
) xmlDictFree(cur
->dict
);
560 /************************************************************************
562 * The reader core parser *
564 ************************************************************************/
567 xmlTextReaderDebug(xmlTextReaderPtr reader
) {
568 if ((reader
== NULL
) || (reader
->ctxt
== NULL
)) {
569 fprintf(stderr
, "xmlTextReader NULL\n");
572 fprintf(stderr
, "xmlTextReader: state %d depth %d ",
573 reader
->state
, reader
->depth
);
574 if (reader
->node
== NULL
) {
575 fprintf(stderr
, "node = NULL\n");
577 fprintf(stderr
, "node %s\n", reader
->node
->name
);
579 fprintf(stderr
, " input: base %d, cur %d, depth %d: ",
580 reader
->base
, reader
->cur
, reader
->ctxt
->nodeNr
);
581 if (reader
->input
->buffer
== NULL
) {
582 fprintf(stderr
, "buffer is NULL\n");
584 #ifdef LIBXML_DEBUG_ENABLED
585 xmlDebugDumpString(stderr
,
586 &reader
->input
->buffer
->content
[reader
->cur
]);
588 fprintf(stderr
, "\n");
594 * xmlTextReaderEntPush:
595 * @reader: the xmlTextReaderPtr used
596 * @value: the entity reference node
598 * Pushes a new entity reference node on top of the entities stack
600 * Returns 0 in case of error, the index in the stack otherwise
603 xmlTextReaderEntPush(xmlTextReaderPtr reader
, xmlNodePtr value
)
605 if (reader
->entMax
<= 0) {
607 reader
->entTab
= (xmlNodePtr
*) xmlMalloc(reader
->entMax
*
608 sizeof(reader
->entTab
[0]));
609 if (reader
->entTab
== NULL
) {
610 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
614 if (reader
->entNr
>= reader
->entMax
) {
617 (xmlNodePtr
*) xmlRealloc(reader
->entTab
,
619 sizeof(reader
->entTab
[0]));
620 if (reader
->entTab
== NULL
) {
621 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
625 reader
->entTab
[reader
->entNr
] = value
;
627 return (reader
->entNr
++);
631 * xmlTextReaderEntPop:
632 * @reader: the xmlTextReaderPtr used
634 * Pops the top element entity from the entities stack
636 * Returns the entity just removed
639 xmlTextReaderEntPop(xmlTextReaderPtr reader
)
643 if (reader
->entNr
<= 0)
646 if (reader
->entNr
> 0)
647 reader
->ent
= reader
->entTab
[reader
->entNr
- 1];
650 ret
= reader
->entTab
[reader
->entNr
];
651 reader
->entTab
[reader
->entNr
] = NULL
;
656 * xmlTextReaderStartElement:
657 * @ctx: the user data (XML parser context)
658 * @fullname: The element name, including namespace prefix
659 * @atts: An array of name/value attributes pairs, NULL terminated
661 * called when an opening tag has been processed.
664 xmlTextReaderStartElement(void *ctx
, const xmlChar
*fullname
,
665 const xmlChar
**atts
) {
666 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
667 xmlTextReaderPtr reader
= ctxt
->_private
;
669 #ifdef DEBUG_CALLBACKS
670 printf("xmlTextReaderStartElement(%s)\n", fullname
);
672 if ((reader
!= NULL
) && (reader
->startElement
!= NULL
)) {
673 reader
->startElement(ctx
, fullname
, atts
);
674 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
675 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
676 (ctxt
->input
->cur
[1] == '>'))
677 ctxt
->node
->extra
= NODE_IS_EMPTY
;
680 reader
->state
= XML_TEXTREADER_ELEMENT
;
684 * xmlTextReaderEndElement:
685 * @ctx: the user data (XML parser context)
686 * @fullname: The element name, including namespace prefix
688 * called when an ending tag has been processed.
691 xmlTextReaderEndElement(void *ctx
, const xmlChar
*fullname
) {
692 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
693 xmlTextReaderPtr reader
= ctxt
->_private
;
695 #ifdef DEBUG_CALLBACKS
696 printf("xmlTextReaderEndElement(%s)\n", fullname
);
698 if ((reader
!= NULL
) && (reader
->endElement
!= NULL
)) {
699 reader
->endElement(ctx
, fullname
);
704 * xmlTextReaderStartElementNs:
705 * @ctx: the user data (XML parser context)
706 * @localname: the local name of the element
707 * @prefix: the element namespace prefix if available
708 * @URI: the element namespace name if available
709 * @nb_namespaces: number of namespace definitions on that node
710 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
711 * @nb_attributes: the number of attributes on that node
712 * nb_defaulted: the number of defaulted attributes.
713 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
716 * called when an opening tag has been processed.
719 xmlTextReaderStartElementNs(void *ctx
,
720 const xmlChar
*localname
,
721 const xmlChar
*prefix
,
724 const xmlChar
**namespaces
,
727 const xmlChar
**attributes
)
729 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
730 xmlTextReaderPtr reader
= ctxt
->_private
;
732 #ifdef DEBUG_CALLBACKS
733 printf("xmlTextReaderStartElementNs(%s)\n", localname
);
735 if ((reader
!= NULL
) && (reader
->startElementNs
!= NULL
)) {
736 reader
->startElementNs(ctx
, localname
, prefix
, URI
, nb_namespaces
,
737 namespaces
, nb_attributes
, nb_defaulted
,
739 if ((ctxt
->node
!= NULL
) && (ctxt
->input
!= NULL
) &&
740 (ctxt
->input
->cur
!= NULL
) && (ctxt
->input
->cur
[0] == '/') &&
741 (ctxt
->input
->cur
[1] == '>'))
742 ctxt
->node
->extra
= NODE_IS_EMPTY
;
745 reader
->state
= XML_TEXTREADER_ELEMENT
;
749 * xmlTextReaderEndElementNs:
750 * @ctx: the user data (XML parser context)
751 * @localname: the local name of the element
752 * @prefix: the element namespace prefix if available
753 * @URI: the element namespace name if available
755 * called when an ending tag has been processed.
758 xmlTextReaderEndElementNs(void *ctx
,
759 const xmlChar
* localname
,
760 const xmlChar
* prefix
,
763 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
764 xmlTextReaderPtr reader
= ctxt
->_private
;
766 #ifdef DEBUG_CALLBACKS
767 printf("xmlTextReaderEndElementNs(%s)\n", localname
);
769 if ((reader
!= NULL
) && (reader
->endElementNs
!= NULL
)) {
770 reader
->endElementNs(ctx
, localname
, prefix
, URI
);
776 * xmlTextReaderCharacters:
777 * @ctx: the user data (XML parser context)
778 * @ch: a xmlChar string
779 * @len: the number of xmlChar
781 * receiving some chars from the parser.
784 xmlTextReaderCharacters(void *ctx
, const xmlChar
*ch
, int len
)
786 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
787 xmlTextReaderPtr reader
= ctxt
->_private
;
789 #ifdef DEBUG_CALLBACKS
790 printf("xmlTextReaderCharacters()\n");
792 if ((reader
!= NULL
) && (reader
->characters
!= NULL
)) {
793 reader
->characters(ctx
, ch
, len
);
798 * xmlTextReaderCDataBlock:
799 * @ctx: the user data (XML parser context)
800 * @value: The pcdata content
801 * @len: the block length
803 * called when a pcdata block has been parsed
806 xmlTextReaderCDataBlock(void *ctx
, const xmlChar
*ch
, int len
)
808 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
809 xmlTextReaderPtr reader
= ctxt
->_private
;
811 #ifdef DEBUG_CALLBACKS
812 printf("xmlTextReaderCDataBlock()\n");
814 if ((reader
!= NULL
) && (reader
->cdataBlock
!= NULL
)) {
815 reader
->cdataBlock(ctx
, ch
, len
);
820 * xmlTextReaderPushData:
821 * @reader: the xmlTextReaderPtr used
823 * Push data down the progressive parser until a significant callback
826 * Returns -1 in case of failure, 0 otherwise
829 xmlTextReaderPushData(xmlTextReaderPtr reader
) {
832 xmlTextReaderState oldstate
;
835 if ((reader
->input
== NULL
) || (reader
->input
->buffer
== NULL
))
838 oldstate
= reader
->state
;
839 reader
->state
= XML_TEXTREADER_NONE
;
840 inbuf
= reader
->input
->buffer
;
841 alloc
= xmlBufGetAllocationScheme(inbuf
);
843 while (reader
->state
== XML_TEXTREADER_NONE
) {
844 if (xmlBufUse(inbuf
) < reader
->cur
+ CHUNK_SIZE
) {
846 * Refill the buffer unless we are at the end of the stream
848 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
849 val
= xmlParserInputBufferRead(reader
->input
, 4096);
851 (alloc
== XML_BUFFER_ALLOC_IMMUTABLE
)) {
852 if (xmlBufUse(inbuf
) == reader
->cur
) {
853 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
854 reader
->state
= oldstate
;
856 } else if (val
< 0) {
857 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
858 reader
->state
= oldstate
;
859 if ((oldstate
!= XML_TEXTREADER_START
) ||
860 (reader
->ctxt
->myDoc
!= NULL
))
862 } else if (val
== 0) {
863 /* mark the end of the stream and process the remains */
864 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
872 * parse by block of CHUNK_SIZE bytes, various tests show that
873 * it's the best tradeoff at least on a 1.2GH Duron
875 if (xmlBufUse(inbuf
) >= reader
->cur
+ CHUNK_SIZE
) {
876 val
= xmlParseChunk(reader
->ctxt
,
877 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
879 reader
->cur
+= CHUNK_SIZE
;
881 reader
->ctxt
->wellFormed
= 0;
882 if (reader
->ctxt
->wellFormed
== 0)
885 s
= xmlBufUse(inbuf
) - reader
->cur
;
886 val
= xmlParseChunk(reader
->ctxt
,
887 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
891 reader
->ctxt
->wellFormed
= 0;
897 * Discard the consumed input when needed and possible
899 if (reader
->mode
== XML_TEXTREADER_MODE_INTERACTIVE
) {
900 if (alloc
!= XML_BUFFER_ALLOC_IMMUTABLE
) {
901 if ((reader
->cur
>= 4096) &&
902 (xmlBufUse(inbuf
) - reader
->cur
<= CHUNK_SIZE
)) {
903 val
= xmlBufShrink(inbuf
, reader
->cur
);
912 * At the end of the stream signal that the work is done to the Push
915 else if (reader
->mode
== XML_TEXTREADER_MODE_EOF
) {
916 if (reader
->state
!= XML_TEXTREADER_DONE
) {
917 s
= xmlBufUse(inbuf
) - reader
->cur
;
918 val
= xmlParseChunk(reader
->ctxt
,
919 (const char *) xmlBufContent(inbuf
) + reader
->cur
,
921 reader
->cur
= xmlBufUse(inbuf
);
922 reader
->state
= XML_TEXTREADER_DONE
;
924 if (reader
->ctxt
->wellFormed
)
925 reader
->ctxt
->wellFormed
= 0;
931 reader
->state
= oldstate
;
932 if (reader
->ctxt
->wellFormed
== 0) {
933 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
940 #ifdef LIBXML_REGEXP_ENABLED
942 * xmlTextReaderValidatePush:
943 * @reader: the xmlTextReaderPtr used
945 * Push the current node for validation
948 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
) {
949 xmlNodePtr node
= reader
->node
;
951 #ifdef LIBXML_VALID_ENABLED
952 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
953 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
954 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
955 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
956 reader
->ctxt
->myDoc
, node
, node
->name
);
958 /* TODO use the BuildQName interface */
961 qname
= xmlStrdup(node
->ns
->prefix
);
962 qname
= xmlStrcat(qname
, BAD_CAST
":");
963 qname
= xmlStrcat(qname
, node
->name
);
964 reader
->ctxt
->valid
&= xmlValidatePushElement(&reader
->ctxt
->vctxt
,
965 reader
->ctxt
->myDoc
, node
, qname
);
970 #endif /* LIBXML_VALID_ENABLED */
971 #ifdef LIBXML_SCHEMAS_ENABLED
972 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
973 (reader
->rngValidCtxt
!= NULL
)) {
976 if (reader
->rngFullNode
!= NULL
) return;
977 ret
= xmlRelaxNGValidatePushElement(reader
->rngValidCtxt
,
982 * this element requires a full tree
984 node
= xmlTextReaderExpand(reader
);
986 printf("Expand failed !\n");
989 ret
= xmlRelaxNGValidateFullElement(reader
->rngValidCtxt
,
992 reader
->rngFullNode
= node
;
996 reader
->rngValidErrors
++;
1002 * xmlTextReaderValidateCData:
1003 * @reader: the xmlTextReaderPtr used
1004 * @data: pointer to the CData
1005 * @len: length of the CData block in bytes.
1007 * Push some CData for validation
1010 xmlTextReaderValidateCData(xmlTextReaderPtr reader
,
1011 const xmlChar
*data
, int len
) {
1012 #ifdef LIBXML_VALID_ENABLED
1013 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
1014 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
1015 reader
->ctxt
->valid
&= xmlValidatePushCData(&reader
->ctxt
->vctxt
,
1018 #endif /* LIBXML_VALID_ENABLED */
1019 #ifdef LIBXML_SCHEMAS_ENABLED
1020 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1021 (reader
->rngValidCtxt
!= NULL
)) {
1024 if (reader
->rngFullNode
!= NULL
) return;
1025 ret
= xmlRelaxNGValidatePushCData(reader
->rngValidCtxt
, data
, len
);
1027 reader
->rngValidErrors
++;
1033 * xmlTextReaderValidatePop:
1034 * @reader: the xmlTextReaderPtr used
1036 * Pop the current node from validation
1039 xmlTextReaderValidatePop(xmlTextReaderPtr reader
) {
1040 xmlNodePtr node
= reader
->node
;
1042 #ifdef LIBXML_VALID_ENABLED
1043 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_DTD
) &&
1044 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1)) {
1045 if ((node
->ns
== NULL
) || (node
->ns
->prefix
== NULL
)) {
1046 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1047 reader
->ctxt
->myDoc
, node
, node
->name
);
1049 /* TODO use the BuildQName interface */
1052 qname
= xmlStrdup(node
->ns
->prefix
);
1053 qname
= xmlStrcat(qname
, BAD_CAST
":");
1054 qname
= xmlStrcat(qname
, node
->name
);
1055 reader
->ctxt
->valid
&= xmlValidatePopElement(&reader
->ctxt
->vctxt
,
1056 reader
->ctxt
->myDoc
, node
, qname
);
1061 #endif /* LIBXML_VALID_ENABLED */
1062 #ifdef LIBXML_SCHEMAS_ENABLED
1063 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
) &&
1064 (reader
->rngValidCtxt
!= NULL
)) {
1067 if (reader
->rngFullNode
!= NULL
) {
1068 if (node
== reader
->rngFullNode
)
1069 reader
->rngFullNode
= NULL
;
1072 ret
= xmlRelaxNGValidatePopElement(reader
->rngValidCtxt
,
1073 reader
->ctxt
->myDoc
,
1076 reader
->rngValidErrors
++;
1082 * xmlTextReaderValidateEntity:
1083 * @reader: the xmlTextReaderPtr used
1085 * Handle the validation when an entity reference is encountered and
1086 * entity substitution is not activated. As a result the parser interface
1087 * must walk through the entity and do the validation calls
1090 xmlTextReaderValidateEntity(xmlTextReaderPtr reader
) {
1091 xmlNodePtr oldnode
= reader
->node
;
1092 xmlNodePtr node
= reader
->node
;
1093 xmlParserCtxtPtr ctxt
= reader
->ctxt
;
1096 if (node
->type
== XML_ENTITY_REF_NODE
) {
1098 * Case where the underlying tree is not availble, lookup the entity
1101 if ((node
->children
== NULL
) && (ctxt
->sax
!= NULL
) &&
1102 (ctxt
->sax
->getEntity
!= NULL
)) {
1103 node
->children
= (xmlNodePtr
)
1104 ctxt
->sax
->getEntity(ctxt
, node
->name
);
1107 if ((node
->children
!= NULL
) &&
1108 (node
->children
->type
== XML_ENTITY_DECL
) &&
1109 (node
->children
->children
!= NULL
)) {
1110 xmlTextReaderEntPush(reader
, node
);
1111 node
= node
->children
->children
;
1115 * The error has probably be raised already.
1117 if (node
== oldnode
)
1121 #ifdef LIBXML_REGEXP_ENABLED
1122 } else if (node
->type
== XML_ELEMENT_NODE
) {
1123 reader
->node
= node
;
1124 xmlTextReaderValidatePush(reader
);
1125 } else if ((node
->type
== XML_TEXT_NODE
) ||
1126 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1127 xmlTextReaderValidateCData(reader
, node
->content
,
1128 xmlStrlen(node
->content
));
1135 if (node
->children
!= NULL
) {
1136 node
= node
->children
;
1138 } else if (node
->type
== XML_ELEMENT_NODE
) {
1139 xmlTextReaderValidatePop(reader
);
1141 if (node
->next
!= NULL
) {
1146 node
= node
->parent
;
1147 if (node
->type
== XML_ELEMENT_NODE
) {
1149 if (reader
->entNr
== 0) {
1150 while ((tmp
= node
->last
) != NULL
) {
1151 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1153 xmlTextReaderFreeNode(reader
, tmp
);
1158 reader
->node
= node
;
1159 xmlTextReaderValidatePop(reader
);
1161 if ((node
->type
== XML_ENTITY_DECL
) &&
1162 (reader
->ent
!= NULL
) && (reader
->ent
->children
== node
)) {
1163 node
= xmlTextReaderEntPop(reader
);
1165 if (node
== oldnode
)
1167 if (node
->next
!= NULL
) {
1171 } while ((node
!= NULL
) && (node
!= oldnode
));
1172 } while ((node
!= NULL
) && (node
!= oldnode
));
1173 reader
->node
= oldnode
;
1175 #endif /* LIBXML_REGEXP_ENABLED */
1179 * xmlTextReaderGetSuccessor:
1180 * @cur: the current node
1182 * Get the successor of a node if available.
1184 * Returns the successor node or NULL
1187 xmlTextReaderGetSuccessor(xmlNodePtr cur
) {
1188 if (cur
== NULL
) return(NULL
) ; /* ERROR */
1189 if (cur
->next
!= NULL
) return(cur
->next
) ;
1192 if (cur
== NULL
) break;
1193 if (cur
->next
!= NULL
) return(cur
->next
);
1194 } while (cur
!= NULL
);
1199 * xmlTextReaderDoExpand:
1200 * @reader: the xmlTextReaderPtr used
1202 * Makes sure that the current node is fully read as well as all its
1203 * descendant. It means the full DOM subtree must be available at the
1206 * Returns 1 if the node was expanded successfully, 0 if there is no more
1207 * nodes to read, or -1 in case of error
1210 xmlTextReaderDoExpand(xmlTextReaderPtr reader
) {
1213 if ((reader
== NULL
) || (reader
->node
== NULL
) || (reader
->ctxt
== NULL
))
1216 if (reader
->ctxt
->instate
== XML_PARSER_EOF
) return(1);
1218 if (xmlTextReaderGetSuccessor(reader
->node
) != NULL
)
1220 if (reader
->ctxt
->nodeNr
< reader
->depth
)
1222 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1224 val
= xmlTextReaderPushData(reader
);
1226 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1229 } while(reader
->mode
!= XML_TEXTREADER_MODE_EOF
);
1234 * xmlTextReaderCollectSiblings:
1235 * @node: the first child
1237 * Traverse depth-first through all sibling nodes and their children
1238 * nodes and concatenate their content. This is an auxiliary function
1239 * to xmlTextReaderReadString.
1241 * Returns a string containing the content, or NULL in case of error.
1244 xmlTextReaderCollectSiblings(xmlNodePtr node
)
1246 xmlBufferPtr buffer
;
1249 if ((node
== NULL
) || (node
->type
== XML_NAMESPACE_DECL
))
1252 buffer
= xmlBufferCreate();
1256 for ( ; node
!= NULL
; node
= node
->next
) {
1257 switch (node
->type
) {
1259 case XML_CDATA_SECTION_NODE
:
1260 xmlBufferCat(buffer
, node
->content
);
1262 case XML_ELEMENT_NODE
: {
1265 tmp
= xmlTextReaderCollectSiblings(node
->children
);
1266 xmlBufferCat(buffer
, tmp
);
1274 ret
= buffer
->content
;
1275 buffer
->content
= NULL
;
1276 xmlBufferFree(buffer
);
1281 * xmlTextReaderRead:
1282 * @reader: the xmlTextReaderPtr used
1284 * Moves the position of the current instance to the next node in
1285 * the stream, exposing its properties.
1287 * Returns 1 if the node was read successfully, 0 if there is no more
1288 * nodes to read, or -1 in case of error
1291 xmlTextReaderRead(xmlTextReaderPtr reader
) {
1292 int val
, olddepth
= 0;
1293 xmlTextReaderState oldstate
= XML_TEXTREADER_START
;
1294 xmlNodePtr oldnode
= NULL
;
1299 reader
->curnode
= NULL
;
1300 if (reader
->doc
!= NULL
)
1301 return(xmlTextReaderReadTree(reader
));
1302 if (reader
->ctxt
== NULL
)
1306 fprintf(stderr
, "\nREAD ");
1309 if (reader
->mode
== XML_TEXTREADER_MODE_INITIAL
) {
1310 reader
->mode
= XML_TEXTREADER_MODE_INTERACTIVE
;
1315 val
= xmlTextReaderPushData(reader
);
1317 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1318 reader
->state
= XML_TEXTREADER_ERROR
;
1321 } while ((reader
->ctxt
->node
== NULL
) &&
1322 ((reader
->mode
!= XML_TEXTREADER_MODE_EOF
) &&
1323 (reader
->state
!= XML_TEXTREADER_DONE
)));
1324 if (reader
->ctxt
->node
== NULL
) {
1325 if (reader
->ctxt
->myDoc
!= NULL
) {
1326 reader
->node
= reader
->ctxt
->myDoc
->children
;
1328 if (reader
->node
== NULL
){
1329 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1330 reader
->state
= XML_TEXTREADER_ERROR
;
1333 reader
->state
= XML_TEXTREADER_ELEMENT
;
1335 if (reader
->ctxt
->myDoc
!= NULL
) {
1336 reader
->node
= reader
->ctxt
->myDoc
->children
;
1338 if (reader
->node
== NULL
)
1339 reader
->node
= reader
->ctxt
->nodeTab
[0];
1340 reader
->state
= XML_TEXTREADER_ELEMENT
;
1343 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
1346 oldstate
= reader
->state
;
1347 olddepth
= reader
->ctxt
->nodeNr
;
1348 oldnode
= reader
->node
;
1351 if (reader
->node
== NULL
) {
1352 if (reader
->mode
== XML_TEXTREADER_MODE_EOF
)
1359 * If we are not backtracking on ancestors or examined nodes,
1360 * that the parser didn't finished or that we arent at the end
1361 * of stream, continue processing.
1363 while ((reader
->node
!= NULL
) && (reader
->node
->next
== NULL
) &&
1364 (reader
->ctxt
->nodeNr
== olddepth
) &&
1365 ((oldstate
== XML_TEXTREADER_BACKTRACK
) ||
1366 (reader
->node
->children
== NULL
) ||
1367 (reader
->node
->type
== XML_ENTITY_REF_NODE
) ||
1368 ((reader
->node
->children
!= NULL
) &&
1369 (reader
->node
->children
->type
== XML_TEXT_NODE
) &&
1370 (reader
->node
->children
->next
== NULL
)) ||
1371 (reader
->node
->type
== XML_DTD_NODE
) ||
1372 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1373 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) &&
1374 ((reader
->ctxt
->node
== NULL
) ||
1375 (reader
->ctxt
->node
== reader
->node
) ||
1376 (reader
->ctxt
->node
== reader
->node
->parent
)) &&
1377 (reader
->ctxt
->instate
!= XML_PARSER_EOF
)) {
1378 val
= xmlTextReaderPushData(reader
);
1380 reader
->mode
= XML_TEXTREADER_MODE_ERROR
;
1381 reader
->state
= XML_TEXTREADER_ERROR
;
1384 if (reader
->node
== NULL
)
1387 if (oldstate
!= XML_TEXTREADER_BACKTRACK
) {
1388 if ((reader
->node
->children
!= NULL
) &&
1389 (reader
->node
->type
!= XML_ENTITY_REF_NODE
) &&
1390 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1391 (reader
->node
->type
!= XML_DTD_NODE
)) {
1392 reader
->node
= reader
->node
->children
;
1394 reader
->state
= XML_TEXTREADER_ELEMENT
;
1398 if (reader
->node
->next
!= NULL
) {
1399 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1400 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1401 (reader
->node
->children
== NULL
) &&
1402 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)
1403 #ifdef LIBXML_XINCLUDE_ENABLED
1404 && (reader
->in_xinclude
<= 0)
1407 reader
->state
= XML_TEXTREADER_END
;
1410 #ifdef LIBXML_REGEXP_ENABLED
1411 if ((reader
->validate
) &&
1412 (reader
->node
->type
== XML_ELEMENT_NODE
))
1413 xmlTextReaderValidatePop(reader
);
1414 #endif /* LIBXML_REGEXP_ENABLED */
1415 if ((reader
->preserves
> 0) &&
1416 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1417 reader
->preserves
--;
1418 reader
->node
= reader
->node
->next
;
1419 reader
->state
= XML_TEXTREADER_ELEMENT
;
1422 * Cleanup of the old node
1424 if ((reader
->preserves
== 0) &&
1425 #ifdef LIBXML_XINCLUDE_ENABLED
1426 (reader
->in_xinclude
== 0) &&
1428 (reader
->entNr
== 0) &&
1429 (reader
->node
->prev
!= NULL
) &&
1430 (reader
->node
->prev
->type
!= XML_DTD_NODE
)) {
1431 xmlNodePtr tmp
= reader
->node
->prev
;
1432 if ((tmp
->extra
& NODE_IS_PRESERVED
) == 0) {
1434 xmlTextReaderFreeNode(reader
, tmp
);
1440 if ((oldstate
== XML_TEXTREADER_ELEMENT
) &&
1441 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1442 (reader
->node
->children
== NULL
) &&
1443 ((reader
->node
->extra
& NODE_IS_EMPTY
) == 0)) {;
1444 reader
->state
= XML_TEXTREADER_END
;
1447 #ifdef LIBXML_REGEXP_ENABLED
1448 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
->type
== XML_ELEMENT_NODE
))
1449 xmlTextReaderValidatePop(reader
);
1450 #endif /* LIBXML_REGEXP_ENABLED */
1451 if ((reader
->preserves
> 0) &&
1452 (reader
->node
->extra
& NODE_IS_SPRESERVED
))
1453 reader
->preserves
--;
1454 reader
->node
= reader
->node
->parent
;
1455 if ((reader
->node
== NULL
) ||
1456 (reader
->node
->type
== XML_DOCUMENT_NODE
) ||
1457 #ifdef LIBXML_DOCB_ENABLED
1458 (reader
->node
->type
== XML_DOCB_DOCUMENT_NODE
) ||
1460 (reader
->node
->type
== XML_HTML_DOCUMENT_NODE
)) {
1461 if (reader
->mode
!= XML_TEXTREADER_MODE_EOF
) {
1462 val
= xmlParseChunk(reader
->ctxt
, "", 0, 1);
1463 reader
->state
= XML_TEXTREADER_DONE
;
1467 reader
->node
= NULL
;
1471 * Cleanup of the old node
1473 if ((oldnode
!= NULL
) && (reader
->preserves
== 0) &&
1474 #ifdef LIBXML_XINCLUDE_ENABLED
1475 (reader
->in_xinclude
== 0) &&
1477 (reader
->entNr
== 0) &&
1478 (oldnode
->type
!= XML_DTD_NODE
) &&
1479 ((oldnode
->extra
& NODE_IS_PRESERVED
) == 0)) {
1480 xmlUnlinkNode(oldnode
);
1481 xmlTextReaderFreeNode(reader
, oldnode
);
1486 if ((reader
->preserves
== 0) &&
1487 #ifdef LIBXML_XINCLUDE_ENABLED
1488 (reader
->in_xinclude
== 0) &&
1490 (reader
->entNr
== 0) &&
1491 (reader
->node
->last
!= NULL
) &&
1492 ((reader
->node
->last
->extra
& NODE_IS_PRESERVED
) == 0)) {
1493 xmlNodePtr tmp
= reader
->node
->last
;
1495 xmlTextReaderFreeNode(reader
, tmp
);
1498 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1504 * If we are in the middle of a piece of CDATA make sure it's finished
1506 if ((reader
->node
!= NULL
) &&
1507 (reader
->node
->next
== NULL
) &&
1508 ((reader
->node
->type
== XML_TEXT_NODE
) ||
1509 (reader
->node
->type
== XML_CDATA_SECTION_NODE
))) {
1510 if (xmlTextReaderExpand(reader
) == NULL
)
1514 #ifdef LIBXML_XINCLUDE_ENABLED
1516 * Handle XInclude if asked for
1518 if ((reader
->xinclude
) && (reader
->node
!= NULL
) &&
1519 (reader
->node
->type
== XML_ELEMENT_NODE
) &&
1520 (reader
->node
->ns
!= NULL
) &&
1521 ((xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_NS
)) ||
1522 (xmlStrEqual(reader
->node
->ns
->href
, XINCLUDE_OLD_NS
)))) {
1523 if (reader
->xincctxt
== NULL
) {
1524 reader
->xincctxt
= xmlXIncludeNewContext(reader
->ctxt
->myDoc
);
1525 xmlXIncludeSetFlags(reader
->xincctxt
,
1526 reader
->parserFlags
& (~XML_PARSE_NOXINCNODE
));
1529 * expand that node and process it
1531 if (xmlTextReaderExpand(reader
) == NULL
)
1533 xmlXIncludeProcessNode(reader
->xincctxt
, reader
->node
);
1535 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_START
)) {
1536 reader
->in_xinclude
++;
1539 if ((reader
->node
!= NULL
) && (reader
->node
->type
== XML_XINCLUDE_END
)) {
1540 reader
->in_xinclude
--;
1545 * Handle entities enter and exit when in entity replacement mode
1547 if ((reader
->node
!= NULL
) &&
1548 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1549 (reader
->ctxt
!= NULL
) && (reader
->ctxt
->replaceEntities
== 1)) {
1551 * Case where the underlying tree is not availble, lookup the entity
1554 if ((reader
->node
->children
== NULL
) && (reader
->ctxt
->sax
!= NULL
) &&
1555 (reader
->ctxt
->sax
->getEntity
!= NULL
)) {
1556 reader
->node
->children
= (xmlNodePtr
)
1557 reader
->ctxt
->sax
->getEntity(reader
->ctxt
, reader
->node
->name
);
1560 if ((reader
->node
->children
!= NULL
) &&
1561 (reader
->node
->children
->type
== XML_ENTITY_DECL
) &&
1562 (reader
->node
->children
->children
!= NULL
)) {
1563 xmlTextReaderEntPush(reader
, reader
->node
);
1564 reader
->node
= reader
->node
->children
->children
;
1566 #ifdef LIBXML_REGEXP_ENABLED
1567 } else if ((reader
->node
!= NULL
) &&
1568 (reader
->node
->type
== XML_ENTITY_REF_NODE
) &&
1569 (reader
->ctxt
!= NULL
) && (reader
->validate
)) {
1570 xmlTextReaderValidateEntity(reader
);
1571 #endif /* LIBXML_REGEXP_ENABLED */
1573 if ((reader
->node
!= NULL
) &&
1574 (reader
->node
->type
== XML_ENTITY_DECL
) &&
1575 (reader
->ent
!= NULL
) && (reader
->ent
->children
== reader
->node
)) {
1576 reader
->node
= xmlTextReaderEntPop(reader
);
1580 #ifdef LIBXML_REGEXP_ENABLED
1581 if ((reader
->validate
!= XML_TEXTREADER_NOT_VALIDATE
) && (reader
->node
!= NULL
)) {
1582 xmlNodePtr node
= reader
->node
;
1584 if ((node
->type
== XML_ELEMENT_NODE
) &&
1585 ((reader
->state
!= XML_TEXTREADER_END
) &&
1586 (reader
->state
!= XML_TEXTREADER_BACKTRACK
))) {
1587 xmlTextReaderValidatePush(reader
);
1588 } else if ((node
->type
== XML_TEXT_NODE
) ||
1589 (node
->type
== XML_CDATA_SECTION_NODE
)) {
1590 xmlTextReaderValidateCData(reader
, node
->content
,
1591 xmlStrlen(node
->content
));
1594 #endif /* LIBXML_REGEXP_ENABLED */
1595 #ifdef LIBXML_PATTERN_ENABLED
1596 if ((reader
->patternNr
> 0) && (reader
->state
!= XML_TEXTREADER_END
) &&
1597 (reader
->state
!= XML_TEXTREADER_BACKTRACK
)) {
1599 for (i
= 0;i
< reader
->patternNr
;i
++) {
1600 if (xmlPatternMatch(reader
->patternTab
[i
], reader
->node
) == 1) {
1601 xmlTextReaderPreserve(reader
);
1606 #endif /* LIBXML_PATTERN_ENABLED */
1607 #ifdef LIBXML_SCHEMAS_ENABLED
1608 if ((reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
) &&
1609 (reader
->xsdValidErrors
== 0) &&
1610 (reader
->xsdValidCtxt
!= NULL
)) {
1611 reader
->xsdValidErrors
= !xmlSchemaIsValid(reader
->xsdValidCtxt
);
1613 #endif /* LIBXML_PATTERN_ENABLED */
1616 reader
->state
= XML_TEXTREADER_DONE
;
1621 * xmlTextReaderReadState:
1622 * @reader: the xmlTextReaderPtr used
1624 * Gets the read state of the reader.
1626 * Returns the state value, or -1 in case of error
1629 xmlTextReaderReadState(xmlTextReaderPtr reader
) {
1632 return(reader
->mode
);
1636 * xmlTextReaderExpand:
1637 * @reader: the xmlTextReaderPtr used
1639 * Reads the contents of the current node and the full subtree. It then makes
1640 * the subtree available until the next xmlTextReaderRead() call
1642 * Returns a node pointer valid until the next xmlTextReaderRead() call
1643 * or NULL in case of error.
1646 xmlTextReaderExpand(xmlTextReaderPtr reader
) {
1647 if ((reader
== NULL
) || (reader
->node
== NULL
))
1649 if (reader
->doc
!= NULL
)
1650 return(reader
->node
);
1651 if (reader
->ctxt
== NULL
)
1653 if (xmlTextReaderDoExpand(reader
) < 0)
1655 return(reader
->node
);
1659 * xmlTextReaderNext:
1660 * @reader: the xmlTextReaderPtr used
1662 * Skip to the node following the current one in document order while
1663 * avoiding the subtree if any.
1665 * Returns 1 if the node was read successfully, 0 if there is no more
1666 * nodes to read, or -1 in case of error
1669 xmlTextReaderNext(xmlTextReaderPtr reader
) {
1675 if (reader
->doc
!= NULL
)
1676 return(xmlTextReaderNextTree(reader
));
1678 if ((cur
== NULL
) || (cur
->type
!= XML_ELEMENT_NODE
))
1679 return(xmlTextReaderRead(reader
));
1680 if (reader
->state
== XML_TEXTREADER_END
|| reader
->state
== XML_TEXTREADER_BACKTRACK
)
1681 return(xmlTextReaderRead(reader
));
1682 if (cur
->extra
& NODE_IS_EMPTY
)
1683 return(xmlTextReaderRead(reader
));
1685 ret
= xmlTextReaderRead(reader
);
1688 } while (reader
->node
!= cur
);
1689 return(xmlTextReaderRead(reader
));
1692 #ifdef LIBXML_WRITER_ENABLED
1694 * xmlTextReaderReadInnerXml:
1695 * @reader: the xmlTextReaderPtr used
1697 * Reads the contents of the current node, including child nodes and markup.
1699 * Returns a string containing the XML content, or NULL if the current node
1700 * is neither an element nor attribute, or has no child nodes. The
1701 * string must be deallocated by the caller.
1704 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1707 xmlNodePtr node
, cur_node
;
1708 xmlBufferPtr buff
, buff2
;
1711 if (xmlTextReaderExpand(reader
) == NULL
) {
1715 buff
= xmlBufferCreate();
1716 for (cur_node
= reader
->node
->children
; cur_node
!= NULL
;
1717 cur_node
= cur_node
->next
) {
1718 node
= xmlDocCopyNode(cur_node
, doc
, 1);
1719 buff2
= xmlBufferCreate();
1720 if (xmlNodeDump(buff2
, doc
, node
, 0, 0) == -1) {
1722 xmlBufferFree(buff2
);
1723 xmlBufferFree(buff
);
1726 xmlBufferCat(buff
, buff2
->content
);
1728 xmlBufferFree(buff2
);
1730 resbuf
= buff
->content
;
1731 buff
->content
= NULL
;
1733 xmlBufferFree(buff
);
1738 #ifdef LIBXML_WRITER_ENABLED
1740 * xmlTextReaderReadOuterXml:
1741 * @reader: the xmlTextReaderPtr used
1743 * Reads the contents of the current node, including child nodes and markup.
1745 * Returns a string containing the node and any XML content, or NULL if the
1746 * current node cannot be serialized. The string must be deallocated
1750 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED
)
1757 node
= reader
->node
;
1759 if (xmlTextReaderExpand(reader
) == NULL
) {
1762 if (node
->type
== XML_DTD_NODE
) {
1763 node
= (xmlNodePtr
) xmlCopyDtd((xmlDtdPtr
) node
);
1765 node
= xmlDocCopyNode(node
, doc
, 1);
1767 buff
= xmlBufferCreate();
1768 if (xmlNodeDump(buff
, doc
, node
, 0, 0) == -1) {
1770 xmlBufferFree(buff
);
1774 resbuf
= buff
->content
;
1775 buff
->content
= NULL
;
1778 xmlBufferFree(buff
);
1784 * xmlTextReaderReadString:
1785 * @reader: the xmlTextReaderPtr used
1787 * Reads the contents of an element or a text node as a string.
1789 * Returns a string containing the contents of the Element or Text node,
1790 * or NULL if the reader is positioned on any other type of node.
1791 * The string must be deallocated by the caller.
1794 xmlTextReaderReadString(xmlTextReaderPtr reader
)
1798 if ((reader
== NULL
) || (reader
->node
== NULL
))
1801 node
= (reader
->curnode
!= NULL
) ? reader
->curnode
: reader
->node
;
1802 switch (node
->type
) {
1804 if (node
->content
!= NULL
)
1805 return(xmlStrdup(node
->content
));
1807 case XML_ELEMENT_NODE
:
1808 if (xmlTextReaderDoExpand(reader
) != -1) {
1809 return xmlTextReaderCollectSiblings(node
->children
);
1812 case XML_ATTRIBUTE_NODE
:
1823 * xmlTextReaderReadBase64:
1824 * @reader: the xmlTextReaderPtr used
1825 * @array: a byte array to store the content.
1826 * @offset: the zero-based index into array where the method should
1828 * @len: the number of bytes to write.
1830 * Reads and decodes the Base64 encoded contents of an element and
1831 * stores the result in a byte buffer.
1833 * Returns the number of bytes written to array, or zero if the current
1834 * instance is not positioned on an element or -1 in case of error.
1837 xmlTextReaderReadBase64(xmlTextReaderPtr reader
,
1838 unsigned char *array ATTRIBUTE_UNUSED
,
1839 int offset ATTRIBUTE_UNUSED
,
1840 int len ATTRIBUTE_UNUSED
) {
1841 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1843 if (reader
->ctxt
->wellFormed
!= 1)
1846 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1853 * xmlTextReaderReadBinHex:
1854 * @reader: the xmlTextReaderPtr used
1855 * @array: a byte array to store the content.
1856 * @offset: the zero-based index into array where the method should
1858 * @len: the number of bytes to write.
1860 * Reads and decodes the BinHex encoded contents of an element and
1861 * stores the result in a byte buffer.
1863 * Returns the number of bytes written to array, or zero if the current
1864 * instance is not positioned on an element or -1 in case of error.
1867 xmlTextReaderReadBinHex(xmlTextReaderPtr reader
,
1868 unsigned char *array ATTRIBUTE_UNUSED
,
1869 int offset ATTRIBUTE_UNUSED
,
1870 int len ATTRIBUTE_UNUSED
) {
1871 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
1873 if (reader
->ctxt
->wellFormed
!= 1)
1876 if ((reader
->node
== NULL
) || (reader
->node
->type
== XML_ELEMENT_NODE
))
1883 /************************************************************************
1885 * Operating on a preparsed tree *
1887 ************************************************************************/
1889 xmlTextReaderNextTree(xmlTextReaderPtr reader
)
1894 if (reader
->state
== XML_TEXTREADER_END
)
1897 if (reader
->node
== NULL
) {
1898 if (reader
->doc
->children
== NULL
) {
1899 reader
->state
= XML_TEXTREADER_END
;
1903 reader
->node
= reader
->doc
->children
;
1904 reader
->state
= XML_TEXTREADER_START
;
1908 if (reader
->state
!= XML_TEXTREADER_BACKTRACK
) {
1909 /* Here removed traversal to child, because we want to skip the subtree,
1910 replace with traversal to sibling to skip subtree */
1911 if (reader
->node
->next
!= 0) {
1912 /* Move to sibling if present,skipping sub-tree */
1913 reader
->node
= reader
->node
->next
;
1914 reader
->state
= XML_TEXTREADER_START
;
1918 /* if reader->node->next is NULL mean no subtree for current node,
1919 so need to move to sibling of parent node if present */
1920 if ((reader
->node
->type
== XML_ELEMENT_NODE
) ||
1921 (reader
->node
->type
== XML_ATTRIBUTE_NODE
)) {
1922 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1923 /* This will move to parent if present */
1924 xmlTextReaderRead(reader
);
1928 if (reader
->node
->next
!= 0) {
1929 reader
->node
= reader
->node
->next
;
1930 reader
->state
= XML_TEXTREADER_START
;
1934 if (reader
->node
->parent
!= 0) {
1935 if (reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) {
1936 reader
->state
= XML_TEXTREADER_END
;
1940 reader
->node
= reader
->node
->parent
;
1942 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1943 /* Repeat process to move to sibling of parent node if present */
1944 xmlTextReaderNextTree(reader
);
1947 reader
->state
= XML_TEXTREADER_END
;
1953 * xmlTextReaderReadTree:
1954 * @reader: the xmlTextReaderPtr used
1956 * Moves the position of the current instance to the next node in
1957 * the stream, exposing its properties.
1959 * Returns 1 if the node was read successfully, 0 if there is no more
1960 * nodes to read, or -1 in case of error
1963 xmlTextReaderReadTree(xmlTextReaderPtr reader
) {
1964 if (reader
->state
== XML_TEXTREADER_END
)
1968 if (reader
->node
== NULL
) {
1969 if (reader
->doc
->children
== NULL
) {
1970 reader
->state
= XML_TEXTREADER_END
;
1974 reader
->node
= reader
->doc
->children
;
1975 reader
->state
= XML_TEXTREADER_START
;
1979 if ((reader
->state
!= XML_TEXTREADER_BACKTRACK
) &&
1980 (reader
->node
->type
!= XML_DTD_NODE
) &&
1981 (reader
->node
->type
!= XML_XINCLUDE_START
) &&
1982 (reader
->node
->type
!= XML_ENTITY_REF_NODE
)) {
1983 if (reader
->node
->children
!= NULL
) {
1984 reader
->node
= reader
->node
->children
;
1986 reader
->state
= XML_TEXTREADER_START
;
1990 if (reader
->node
->type
== XML_ATTRIBUTE_NODE
) {
1991 reader
->state
= XML_TEXTREADER_BACKTRACK
;
1996 if (reader
->node
->next
!= NULL
) {
1997 reader
->node
= reader
->node
->next
;
1998 reader
->state
= XML_TEXTREADER_START
;
2002 if (reader
->node
->parent
!= NULL
) {
2003 if ((reader
->node
->parent
->type
== XML_DOCUMENT_NODE
) ||
2004 (reader
->node
->parent
->type
== XML_HTML_DOCUMENT_NODE
)) {
2005 reader
->state
= XML_TEXTREADER_END
;
2009 reader
->node
= reader
->node
->parent
;
2011 reader
->state
= XML_TEXTREADER_BACKTRACK
;
2015 reader
->state
= XML_TEXTREADER_END
;
2018 if ((reader
->node
->type
== XML_XINCLUDE_START
) ||
2019 (reader
->node
->type
== XML_XINCLUDE_END
))
2026 * xmlTextReaderNextSibling:
2027 * @reader: the xmlTextReaderPtr used
2029 * Skip to the node following the current one in document order while
2030 * avoiding the subtree if any.
2031 * Currently implemented only for Readers built on a document
2033 * Returns 1 if the node was read successfully, 0 if there is no more
2034 * nodes to read, or -1 in case of error
2037 xmlTextReaderNextSibling(xmlTextReaderPtr reader
) {
2040 if (reader
->doc
== NULL
) {
2045 if (reader
->state
== XML_TEXTREADER_END
)
2048 if (reader
->node
== NULL
)
2049 return(xmlTextReaderNextTree(reader
));
2051 if (reader
->node
->next
!= NULL
) {
2052 reader
->node
= reader
->node
->next
;
2053 reader
->state
= XML_TEXTREADER_START
;
2060 /************************************************************************
2062 * Constructor and destructors *
2064 ************************************************************************/
2067 * @input: the xmlParserInputBufferPtr used to read data
2068 * @URI: the URI information for the source if available
2070 * Create an xmlTextReader structure fed with @input
2072 * Returns the new xmlTextReaderPtr or NULL in case of error
2075 xmlNewTextReader(xmlParserInputBufferPtr input
, const char *URI
) {
2076 xmlTextReaderPtr ret
;
2080 ret
= xmlMalloc(sizeof(xmlTextReader
));
2082 xmlGenericError(xmlGenericErrorContext
,
2083 "xmlNewTextReader : malloc failed\n");
2086 memset(ret
, 0, sizeof(xmlTextReader
));
2092 ret
->buffer
= xmlBufCreateSize(100);
2093 if (ret
->buffer
== NULL
) {
2095 xmlGenericError(xmlGenericErrorContext
,
2096 "xmlNewTextReader : malloc failed\n");
2099 /* no operation on a reader should require a huge buffer */
2100 xmlBufSetAllocationScheme(ret
->buffer
,
2101 XML_BUFFER_ALLOC_BOUNDED
);
2102 ret
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
2103 if (ret
->sax
== NULL
) {
2104 xmlBufFree(ret
->buffer
);
2106 xmlGenericError(xmlGenericErrorContext
,
2107 "xmlNewTextReader : malloc failed\n");
2110 xmlSAXVersion(ret
->sax
, 2);
2111 ret
->startElement
= ret
->sax
->startElement
;
2112 ret
->sax
->startElement
= xmlTextReaderStartElement
;
2113 ret
->endElement
= ret
->sax
->endElement
;
2114 ret
->sax
->endElement
= xmlTextReaderEndElement
;
2115 #ifdef LIBXML_SAX1_ENABLED
2116 if (ret
->sax
->initialized
== XML_SAX2_MAGIC
) {
2117 #endif /* LIBXML_SAX1_ENABLED */
2118 ret
->startElementNs
= ret
->sax
->startElementNs
;
2119 ret
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
2120 ret
->endElementNs
= ret
->sax
->endElementNs
;
2121 ret
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
2122 #ifdef LIBXML_SAX1_ENABLED
2124 ret
->startElementNs
= NULL
;
2125 ret
->endElementNs
= NULL
;
2127 #endif /* LIBXML_SAX1_ENABLED */
2128 ret
->characters
= ret
->sax
->characters
;
2129 ret
->sax
->characters
= xmlTextReaderCharacters
;
2130 ret
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
2131 ret
->cdataBlock
= ret
->sax
->cdataBlock
;
2132 ret
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
2134 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
2136 ret
->curnode
= NULL
;
2137 if (xmlBufUse(ret
->input
->buffer
) < 4) {
2138 xmlParserInputBufferRead(input
, 4);
2140 if (xmlBufUse(ret
->input
->buffer
) >= 4) {
2141 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
,
2142 (const char *) xmlBufContent(ret
->input
->buffer
),
2147 ret
->ctxt
= xmlCreatePushParserCtxt(ret
->sax
, NULL
, NULL
, 0, URI
);
2152 if (ret
->ctxt
== NULL
) {
2153 xmlGenericError(xmlGenericErrorContext
,
2154 "xmlNewTextReader : malloc failed\n");
2155 xmlBufFree(ret
->buffer
);
2160 ret
->ctxt
->parseMode
= XML_PARSE_READER
;
2161 ret
->ctxt
->_private
= ret
;
2162 ret
->ctxt
->linenumbers
= 1;
2163 ret
->ctxt
->dictNames
= 1;
2164 ret
->allocs
= XML_TEXTREADER_CTXT
;
2166 * use the parser dictionary to allocate all elements and attributes names
2168 ret
->ctxt
->docdict
= 1;
2169 ret
->dict
= ret
->ctxt
->dict
;
2170 #ifdef LIBXML_XINCLUDE_ENABLED
2173 #ifdef LIBXML_PATTERN_ENABLED
2174 ret
->patternMax
= 0;
2175 ret
->patternTab
= NULL
;
2181 * xmlNewTextReaderFilename:
2182 * @URI: the URI of the resource to process
2184 * Create an xmlTextReader structure fed with the resource at @URI
2186 * Returns the new xmlTextReaderPtr or NULL in case of error
2189 xmlNewTextReaderFilename(const char *URI
) {
2190 xmlParserInputBufferPtr input
;
2191 xmlTextReaderPtr ret
;
2192 char *directory
= NULL
;
2194 input
= xmlParserInputBufferCreateFilename(URI
, XML_CHAR_ENCODING_NONE
);
2197 ret
= xmlNewTextReader(input
, URI
);
2199 xmlFreeParserInputBuffer(input
);
2202 ret
->allocs
|= XML_TEXTREADER_INPUT
;
2203 if (ret
->ctxt
->directory
== NULL
)
2204 directory
= xmlParserGetDirectory(URI
);
2205 if ((ret
->ctxt
->directory
== NULL
) && (directory
!= NULL
))
2206 ret
->ctxt
->directory
= (char *) xmlStrdup((xmlChar
*) directory
);
2207 if (directory
!= NULL
)
2213 * xmlFreeTextReader:
2214 * @reader: the xmlTextReaderPtr
2216 * Deallocate all the resources associated to the reader
2219 xmlFreeTextReader(xmlTextReaderPtr reader
) {
2222 #ifdef LIBXML_SCHEMAS_ENABLED
2223 if (reader
->rngSchemas
!= NULL
) {
2224 xmlRelaxNGFree(reader
->rngSchemas
);
2225 reader
->rngSchemas
= NULL
;
2227 if (reader
->rngValidCtxt
!= NULL
) {
2228 if (! reader
->rngPreserveCtxt
)
2229 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
2230 reader
->rngValidCtxt
= NULL
;
2232 if (reader
->xsdPlug
!= NULL
) {
2233 xmlSchemaSAXUnplug(reader
->xsdPlug
);
2234 reader
->xsdPlug
= NULL
;
2236 if (reader
->xsdValidCtxt
!= NULL
) {
2237 if (! reader
->xsdPreserveCtxt
)
2238 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
2239 reader
->xsdValidCtxt
= NULL
;
2241 if (reader
->xsdSchemas
!= NULL
) {
2242 xmlSchemaFree(reader
->xsdSchemas
);
2243 reader
->xsdSchemas
= NULL
;
2246 #ifdef LIBXML_XINCLUDE_ENABLED
2247 if (reader
->xincctxt
!= NULL
)
2248 xmlXIncludeFreeContext(reader
->xincctxt
);
2250 #ifdef LIBXML_PATTERN_ENABLED
2251 if (reader
->patternTab
!= NULL
) {
2253 for (i
= 0;i
< reader
->patternNr
;i
++) {
2254 if (reader
->patternTab
[i
] != NULL
)
2255 xmlFreePattern(reader
->patternTab
[i
]);
2257 xmlFree(reader
->patternTab
);
2260 if (reader
->faketext
!= NULL
) {
2261 xmlFreeNode(reader
->faketext
);
2263 if (reader
->ctxt
!= NULL
) {
2264 if (reader
->dict
== reader
->ctxt
->dict
)
2265 reader
->dict
= NULL
;
2266 if (reader
->ctxt
->myDoc
!= NULL
) {
2267 if (reader
->preserve
== 0)
2268 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2269 reader
->ctxt
->myDoc
= NULL
;
2271 if ((reader
->ctxt
->vctxt
.vstateTab
!= NULL
) &&
2272 (reader
->ctxt
->vctxt
.vstateMax
> 0)){
2273 xmlFree(reader
->ctxt
->vctxt
.vstateTab
);
2274 reader
->ctxt
->vctxt
.vstateTab
= NULL
;
2275 reader
->ctxt
->vctxt
.vstateMax
= 0;
2277 if (reader
->allocs
& XML_TEXTREADER_CTXT
)
2278 xmlFreeParserCtxt(reader
->ctxt
);
2280 if (reader
->sax
!= NULL
)
2281 xmlFree(reader
->sax
);
2282 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
))
2283 xmlFreeParserInputBuffer(reader
->input
);
2284 if (reader
->buffer
!= NULL
)
2285 xmlBufFree(reader
->buffer
);
2286 if (reader
->entTab
!= NULL
)
2287 xmlFree(reader
->entTab
);
2288 if (reader
->dict
!= NULL
)
2289 xmlDictFree(reader
->dict
);
2293 /************************************************************************
2295 * Methods for XmlTextReader *
2297 ************************************************************************/
2299 * xmlTextReaderClose:
2300 * @reader: the xmlTextReaderPtr used
2302 * This method releases any resources allocated by the current instance
2303 * changes the state to Closed and close any underlying input.
2305 * Returns 0 or -1 in case of error
2308 xmlTextReaderClose(xmlTextReaderPtr reader
) {
2311 reader
->node
= NULL
;
2312 reader
->curnode
= NULL
;
2313 reader
->mode
= XML_TEXTREADER_MODE_CLOSED
;
2314 if (reader
->ctxt
!= NULL
) {
2315 xmlStopParser(reader
->ctxt
);
2316 if (reader
->ctxt
->myDoc
!= NULL
) {
2317 if (reader
->preserve
== 0)
2318 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2319 reader
->ctxt
->myDoc
= NULL
;
2322 if ((reader
->input
!= NULL
) && (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
2323 xmlFreeParserInputBuffer(reader
->input
);
2324 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2330 * xmlTextReaderGetAttributeNo:
2331 * @reader: the xmlTextReaderPtr used
2332 * @no: the zero-based index of the attribute relative to the containing element
2334 * Provides the value of the attribute with the specified index relative
2335 * to the containing element.
2337 * Returns a string containing the value of the specified attribute, or NULL
2338 * in case of error. The string must be deallocated by the caller.
2341 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader
, int no
) {
2349 if (reader
->node
== NULL
)
2351 if (reader
->curnode
!= NULL
)
2353 /* TODO: handle the xmlDecl */
2354 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2357 ns
= reader
->node
->nsDef
;
2358 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2362 return(xmlStrdup(ns
->href
));
2364 cur
= reader
->node
->properties
;
2372 /* TODO walk the DTD if present */
2374 ret
= xmlNodeListGetString(reader
->node
->doc
, cur
->children
, 1);
2375 if (ret
== NULL
) return(xmlStrdup((xmlChar
*)""));
2380 * xmlTextReaderGetAttribute:
2381 * @reader: the xmlTextReaderPtr used
2382 * @name: the qualified name of the attribute.
2384 * Provides the value of the attribute with the specified qualified name.
2386 * Returns a string containing the value of the specified attribute, or NULL
2387 * in case of error. The string must be deallocated by the caller.
2390 xmlTextReaderGetAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2391 xmlChar
*prefix
= NULL
;
2394 xmlChar
*ret
= NULL
;
2396 if ((reader
== NULL
) || (name
== NULL
))
2398 if (reader
->node
== NULL
)
2400 if (reader
->curnode
!= NULL
)
2403 /* TODO: handle the xmlDecl */
2404 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2407 localname
= xmlSplitQName2(name
, &prefix
);
2408 if (localname
== NULL
) {
2410 * Namespace default decl
2412 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2413 ns
= reader
->node
->nsDef
;
2414 while (ns
!= NULL
) {
2415 if (ns
->prefix
== NULL
) {
2416 return(xmlStrdup(ns
->href
));
2422 return(xmlGetNoNsProp(reader
->node
, name
));
2426 * Namespace default decl
2428 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2429 ns
= reader
->node
->nsDef
;
2430 while (ns
!= NULL
) {
2431 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2432 ret
= xmlStrdup(ns
->href
);
2438 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2440 ret
= xmlGetNsProp(reader
->node
, localname
, ns
->href
);
2451 * xmlTextReaderGetAttributeNs:
2452 * @reader: the xmlTextReaderPtr used
2453 * @localName: the local name of the attribute.
2454 * @namespaceURI: the namespace URI of the attribute.
2456 * Provides the value of the specified attribute
2458 * Returns a string containing the value of the specified attribute, or NULL
2459 * in case of error. The string must be deallocated by the caller.
2462 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader
, const xmlChar
*localName
,
2463 const xmlChar
*namespaceURI
) {
2464 xmlChar
*prefix
= NULL
;
2467 if ((reader
== NULL
) || (localName
== NULL
))
2469 if (reader
->node
== NULL
)
2471 if (reader
->curnode
!= NULL
)
2474 /* TODO: handle the xmlDecl */
2475 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2478 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2479 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2480 prefix
= BAD_CAST localName
;
2482 ns
= reader
->node
->nsDef
;
2483 while (ns
!= NULL
) {
2484 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2485 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2486 return xmlStrdup(ns
->href
);
2493 return(xmlGetNsProp(reader
->node
, localName
, namespaceURI
));
2497 * xmlTextReaderGetRemainder:
2498 * @reader: the xmlTextReaderPtr used
2500 * Method to get the remainder of the buffered XML. this method stops the
2501 * parser, set its state to End Of File and return the input stream with
2502 * what is left that the parser did not use.
2504 * The implementation is not good, the parser certainly procgressed past
2505 * what's left in reader->input, and there is an allocation problem. Best
2506 * would be to rewrite it differently.
2508 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
2511 xmlParserInputBufferPtr
2512 xmlTextReaderGetRemainder(xmlTextReaderPtr reader
) {
2513 xmlParserInputBufferPtr ret
= NULL
;
2517 if (reader
->node
== NULL
)
2520 reader
->node
= NULL
;
2521 reader
->curnode
= NULL
;
2522 reader
->mode
= XML_TEXTREADER_MODE_EOF
;
2523 if (reader
->ctxt
!= NULL
) {
2524 xmlStopParser(reader
->ctxt
);
2525 if (reader
->ctxt
->myDoc
!= NULL
) {
2526 if (reader
->preserve
== 0)
2527 xmlTextReaderFreeDoc(reader
, reader
->ctxt
->myDoc
);
2528 reader
->ctxt
->myDoc
= NULL
;
2531 if (reader
->allocs
& XML_TEXTREADER_INPUT
) {
2532 ret
= reader
->input
;
2533 reader
->input
= NULL
;
2534 reader
->allocs
-= XML_TEXTREADER_INPUT
;
2537 * Hum, one may need to duplicate the data structure because
2538 * without reference counting the input may be freed twice:
2539 * - by the layer which allocated it.
2540 * - by the layer to which would have been returned to.
2549 * xmlTextReaderLookupNamespace:
2550 * @reader: the xmlTextReaderPtr used
2551 * @prefix: the prefix whose namespace URI is to be resolved. To return
2552 * the default namespace, specify NULL
2554 * Resolves a namespace prefix in the scope of the current element.
2556 * Returns a string containing the namespace URI to which the prefix maps
2557 * or NULL in case of error. The string must be deallocated by the caller.
2560 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader
, const xmlChar
*prefix
) {
2565 if (reader
->node
== NULL
)
2568 ns
= xmlSearchNs(reader
->node
->doc
, reader
->node
, prefix
);
2571 return(xmlStrdup(ns
->href
));
2575 * xmlTextReaderMoveToAttributeNo:
2576 * @reader: the xmlTextReaderPtr used
2577 * @no: the zero-based index of the attribute relative to the containing
2580 * Moves the position of the current instance to the attribute with
2581 * the specified index relative to the containing element.
2583 * Returns 1 in case of success, -1 in case of error, 0 if not found
2586 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader
, int no
) {
2593 if (reader
->node
== NULL
)
2595 /* TODO: handle the xmlDecl */
2596 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2599 reader
->curnode
= NULL
;
2601 ns
= reader
->node
->nsDef
;
2602 for (i
= 0;(i
< no
) && (ns
!= NULL
);i
++) {
2606 reader
->curnode
= (xmlNodePtr
) ns
;
2610 cur
= reader
->node
->properties
;
2618 /* TODO walk the DTD if present */
2620 reader
->curnode
= (xmlNodePtr
) cur
;
2625 * xmlTextReaderMoveToAttribute:
2626 * @reader: the xmlTextReaderPtr used
2627 * @name: the qualified name of the attribute.
2629 * Moves the position of the current instance to the attribute with
2630 * the specified qualified name.
2632 * Returns 1 in case of success, -1 in case of error, 0 if not found
2635 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader
, const xmlChar
*name
) {
2636 xmlChar
*prefix
= NULL
;
2641 if ((reader
== NULL
) || (name
== NULL
))
2643 if (reader
->node
== NULL
)
2646 /* TODO: handle the xmlDecl */
2647 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2650 localname
= xmlSplitQName2(name
, &prefix
);
2651 if (localname
== NULL
) {
2653 * Namespace default decl
2655 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
2656 ns
= reader
->node
->nsDef
;
2657 while (ns
!= NULL
) {
2658 if (ns
->prefix
== NULL
) {
2659 reader
->curnode
= (xmlNodePtr
) ns
;
2667 prop
= reader
->node
->properties
;
2668 while (prop
!= NULL
) {
2671 * - same attribute names
2672 * - and the attribute carrying that namespace
2674 if ((xmlStrEqual(prop
->name
, name
)) &&
2675 ((prop
->ns
== NULL
) || (prop
->ns
->prefix
== NULL
))) {
2676 reader
->curnode
= (xmlNodePtr
) prop
;
2685 * Namespace default decl
2687 if (xmlStrEqual(prefix
, BAD_CAST
"xmlns")) {
2688 ns
= reader
->node
->nsDef
;
2689 while (ns
!= NULL
) {
2690 if ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localname
))) {
2691 reader
->curnode
= (xmlNodePtr
) ns
;
2698 prop
= reader
->node
->properties
;
2699 while (prop
!= NULL
) {
2702 * - same attribute names
2703 * - and the attribute carrying that namespace
2705 if ((xmlStrEqual(prop
->name
, localname
)) &&
2706 (prop
->ns
!= NULL
) && (xmlStrEqual(prop
->ns
->prefix
, prefix
))) {
2707 reader
->curnode
= (xmlNodePtr
) prop
;
2713 if (localname
!= NULL
)
2720 if (localname
!= NULL
)
2728 * xmlTextReaderMoveToAttributeNs:
2729 * @reader: the xmlTextReaderPtr used
2730 * @localName: the local name of the attribute.
2731 * @namespaceURI: the namespace URI of the attribute.
2733 * Moves the position of the current instance to the attribute with the
2734 * specified local name and namespace URI.
2736 * Returns 1 in case of success, -1 in case of error, 0 if not found
2739 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader
,
2740 const xmlChar
*localName
, const xmlChar
*namespaceURI
) {
2744 xmlChar
*prefix
= NULL
;
2746 if ((reader
== NULL
) || (localName
== NULL
) || (namespaceURI
== NULL
))
2748 if (reader
->node
== NULL
)
2750 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2752 node
= reader
->node
;
2754 if (xmlStrEqual(namespaceURI
, BAD_CAST
"http://www.w3.org/2000/xmlns/")) {
2755 if (! xmlStrEqual(localName
, BAD_CAST
"xmlns")) {
2756 prefix
= BAD_CAST localName
;
2758 ns
= reader
->node
->nsDef
;
2759 while (ns
!= NULL
) {
2760 if ((prefix
== NULL
&& ns
->prefix
== NULL
) ||
2761 ((ns
->prefix
!= NULL
) && (xmlStrEqual(ns
->prefix
, localName
)))) {
2762 reader
->curnode
= (xmlNodePtr
) ns
;
2770 prop
= node
->properties
;
2771 while (prop
!= NULL
) {
2774 * - same attribute names
2775 * - and the attribute carrying that namespace
2777 if (xmlStrEqual(prop
->name
, localName
) &&
2778 ((prop
->ns
!= NULL
) &&
2779 (xmlStrEqual(prop
->ns
->href
, namespaceURI
)))) {
2780 reader
->curnode
= (xmlNodePtr
) prop
;
2789 * xmlTextReaderMoveToFirstAttribute:
2790 * @reader: the xmlTextReaderPtr used
2792 * Moves the position of the current instance to the first attribute
2793 * associated with the current node.
2795 * Returns 1 in case of success, -1 in case of error, 0 if not found
2798 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader
) {
2801 if (reader
->node
== NULL
)
2803 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2806 if (reader
->node
->nsDef
!= NULL
) {
2807 reader
->curnode
= (xmlNodePtr
) reader
->node
->nsDef
;
2810 if (reader
->node
->properties
!= NULL
) {
2811 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2818 * xmlTextReaderMoveToNextAttribute:
2819 * @reader: the xmlTextReaderPtr used
2821 * Moves the position of the current instance to the next attribute
2822 * associated with the current node.
2824 * Returns 1 in case of success, -1 in case of error, 0 if not found
2827 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader
) {
2830 if (reader
->node
== NULL
)
2832 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2834 if (reader
->curnode
== NULL
)
2835 return(xmlTextReaderMoveToFirstAttribute(reader
));
2837 if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2838 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2839 if (ns
->next
!= NULL
) {
2840 reader
->curnode
= (xmlNodePtr
) ns
->next
;
2843 if (reader
->node
->properties
!= NULL
) {
2844 reader
->curnode
= (xmlNodePtr
) reader
->node
->properties
;
2848 } else if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) &&
2849 (reader
->curnode
->next
!= NULL
)) {
2850 reader
->curnode
= reader
->curnode
->next
;
2857 * xmlTextReaderMoveToElement:
2858 * @reader: the xmlTextReaderPtr used
2860 * Moves the position of the current instance to the node that
2861 * contains the current Attribute node.
2863 * Returns 1 in case of success, -1 in case of error, 0 if not moved
2866 xmlTextReaderMoveToElement(xmlTextReaderPtr reader
) {
2869 if (reader
->node
== NULL
)
2871 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
2873 if (reader
->curnode
!= NULL
) {
2874 reader
->curnode
= NULL
;
2881 * xmlTextReaderReadAttributeValue:
2882 * @reader: the xmlTextReaderPtr used
2884 * Parses an attribute value into one or more Text and EntityReference nodes.
2886 * Returns 1 in case of success, 0 if the reader was not positionned on an
2887 * ttribute node or all the attribute values have been read, or -1
2891 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader
) {
2894 if (reader
->node
== NULL
)
2896 if (reader
->curnode
== NULL
)
2898 if (reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) {
2899 if (reader
->curnode
->children
== NULL
)
2901 reader
->curnode
= reader
->curnode
->children
;
2902 } else if (reader
->curnode
->type
== XML_NAMESPACE_DECL
) {
2903 xmlNsPtr ns
= (xmlNsPtr
) reader
->curnode
;
2905 if (reader
->faketext
== NULL
) {
2906 reader
->faketext
= xmlNewDocText(reader
->node
->doc
,
2909 if ((reader
->faketext
->content
!= NULL
) &&
2910 (reader
->faketext
->content
!=
2911 (xmlChar
*) &(reader
->faketext
->properties
)))
2912 xmlFree(reader
->faketext
->content
);
2913 reader
->faketext
->content
= xmlStrdup(ns
->href
);
2915 reader
->curnode
= reader
->faketext
;
2917 if (reader
->curnode
->next
== NULL
)
2919 reader
->curnode
= reader
->curnode
->next
;
2925 * xmlTextReaderConstEncoding:
2926 * @reader: the xmlTextReaderPtr used
2928 * Determine the encoding of the document being read.
2930 * Returns a string containing the encoding of the document or NULL in
2931 * case of error. The string is deallocated with the reader.
2934 xmlTextReaderConstEncoding(xmlTextReaderPtr reader
) {
2935 xmlDocPtr doc
= NULL
;
2938 if (reader
->doc
!= NULL
)
2940 else if (reader
->ctxt
!= NULL
)
2941 doc
= reader
->ctxt
->myDoc
;
2945 if (doc
->encoding
== NULL
)
2948 return(CONSTSTR(doc
->encoding
));
2952 /************************************************************************
2954 * Acces API to the current node *
2956 ************************************************************************/
2958 * xmlTextReaderAttributeCount:
2959 * @reader: the xmlTextReaderPtr used
2961 * Provides the number of attributes of the current node
2963 * Returns 0 i no attributes, -1 in case of error or the attribute count
2966 xmlTextReaderAttributeCount(xmlTextReaderPtr reader
) {
2974 if (reader
->node
== NULL
)
2977 if (reader
->curnode
!= NULL
)
2978 node
= reader
->curnode
;
2980 node
= reader
->node
;
2982 if (node
->type
!= XML_ELEMENT_NODE
)
2984 if ((reader
->state
== XML_TEXTREADER_END
) ||
2985 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
2988 attr
= node
->properties
;
2989 while (attr
!= NULL
) {
2994 while (ns
!= NULL
) {
3002 * xmlTextReaderNodeType:
3003 * @reader: the xmlTextReaderPtr used
3005 * Get the node type of the current node
3007 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
3009 * Returns the xmlNodeType of the current node or -1 in case of error
3012 xmlTextReaderNodeType(xmlTextReaderPtr reader
) {
3017 if (reader
->node
== NULL
)
3018 return(XML_READER_TYPE_NONE
);
3019 if (reader
->curnode
!= NULL
)
3020 node
= reader
->curnode
;
3022 node
= reader
->node
;
3023 switch (node
->type
) {
3024 case XML_ELEMENT_NODE
:
3025 if ((reader
->state
== XML_TEXTREADER_END
) ||
3026 (reader
->state
== XML_TEXTREADER_BACKTRACK
))
3027 return(XML_READER_TYPE_END_ELEMENT
);
3028 return(XML_READER_TYPE_ELEMENT
);
3029 case XML_NAMESPACE_DECL
:
3030 case XML_ATTRIBUTE_NODE
:
3031 return(XML_READER_TYPE_ATTRIBUTE
);
3033 if (xmlIsBlankNode(reader
->node
)) {
3034 if (xmlNodeGetSpacePreserve(reader
->node
))
3035 return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE
);
3037 return(XML_READER_TYPE_WHITESPACE
);
3039 return(XML_READER_TYPE_TEXT
);
3041 case XML_CDATA_SECTION_NODE
:
3042 return(XML_READER_TYPE_CDATA
);
3043 case XML_ENTITY_REF_NODE
:
3044 return(XML_READER_TYPE_ENTITY_REFERENCE
);
3045 case XML_ENTITY_NODE
:
3046 return(XML_READER_TYPE_ENTITY
);
3048 return(XML_READER_TYPE_PROCESSING_INSTRUCTION
);
3049 case XML_COMMENT_NODE
:
3050 return(XML_READER_TYPE_COMMENT
);
3051 case XML_DOCUMENT_NODE
:
3052 case XML_HTML_DOCUMENT_NODE
:
3053 #ifdef LIBXML_DOCB_ENABLED
3054 case XML_DOCB_DOCUMENT_NODE
:
3056 return(XML_READER_TYPE_DOCUMENT
);
3057 case XML_DOCUMENT_FRAG_NODE
:
3058 return(XML_READER_TYPE_DOCUMENT_FRAGMENT
);
3059 case XML_NOTATION_NODE
:
3060 return(XML_READER_TYPE_NOTATION
);
3061 case XML_DOCUMENT_TYPE_NODE
:
3063 return(XML_READER_TYPE_DOCUMENT_TYPE
);
3065 case XML_ELEMENT_DECL
:
3066 case XML_ATTRIBUTE_DECL
:
3067 case XML_ENTITY_DECL
:
3068 case XML_XINCLUDE_START
:
3069 case XML_XINCLUDE_END
:
3070 return(XML_READER_TYPE_NONE
);
3076 * xmlTextReaderIsEmptyElement:
3077 * @reader: the xmlTextReaderPtr used
3079 * Check if the current node is empty
3081 * Returns 1 if empty, 0 if not and -1 in case of error
3084 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader
) {
3085 if ((reader
== NULL
) || (reader
->node
== NULL
))
3087 if (reader
->node
->type
!= XML_ELEMENT_NODE
)
3089 if (reader
->curnode
!= NULL
)
3091 if (reader
->node
->children
!= NULL
)
3093 if (reader
->state
== XML_TEXTREADER_END
)
3095 if (reader
->doc
!= NULL
)
3097 #ifdef LIBXML_XINCLUDE_ENABLED
3098 if (reader
->in_xinclude
> 0)
3101 return((reader
->node
->extra
& NODE_IS_EMPTY
) != 0);
3105 * xmlTextReaderLocalName:
3106 * @reader: the xmlTextReaderPtr used
3108 * The local name of the node.
3110 * Returns the local name or NULL if not available,
3111 * if non NULL it need to be freed by the caller.
3114 xmlTextReaderLocalName(xmlTextReaderPtr reader
) {
3116 if ((reader
== NULL
) || (reader
->node
== NULL
))
3118 if (reader
->curnode
!= NULL
)
3119 node
= reader
->curnode
;
3121 node
= reader
->node
;
3122 if (node
->type
== XML_NAMESPACE_DECL
) {
3123 xmlNsPtr ns
= (xmlNsPtr
) node
;
3124 if (ns
->prefix
== NULL
)
3125 return(xmlStrdup(BAD_CAST
"xmlns"));
3127 return(xmlStrdup(ns
->prefix
));
3129 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3130 (node
->type
!= XML_ATTRIBUTE_NODE
))
3131 return(xmlTextReaderName(reader
));
3132 return(xmlStrdup(node
->name
));
3136 * xmlTextReaderConstLocalName:
3137 * @reader: the xmlTextReaderPtr used
3139 * The local name of the node.
3141 * Returns the local name or NULL if not available, the
3142 * string will be deallocated with the reader.
3145 xmlTextReaderConstLocalName(xmlTextReaderPtr reader
) {
3147 if ((reader
== NULL
) || (reader
->node
== NULL
))
3149 if (reader
->curnode
!= NULL
)
3150 node
= reader
->curnode
;
3152 node
= reader
->node
;
3153 if (node
->type
== XML_NAMESPACE_DECL
) {
3154 xmlNsPtr ns
= (xmlNsPtr
) node
;
3155 if (ns
->prefix
== NULL
)
3156 return(CONSTSTR(BAD_CAST
"xmlns"));
3160 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3161 (node
->type
!= XML_ATTRIBUTE_NODE
))
3162 return(xmlTextReaderConstName(reader
));
3167 * xmlTextReaderName:
3168 * @reader: the xmlTextReaderPtr used
3170 * The qualified name of the node, equal to Prefix :LocalName.
3172 * Returns the local name or NULL if not available,
3173 * if non NULL it need to be freed by the caller.
3176 xmlTextReaderName(xmlTextReaderPtr reader
) {
3180 if ((reader
== NULL
) || (reader
->node
== NULL
))
3182 if (reader
->curnode
!= NULL
)
3183 node
= reader
->curnode
;
3185 node
= reader
->node
;
3186 switch (node
->type
) {
3187 case XML_ELEMENT_NODE
:
3188 case XML_ATTRIBUTE_NODE
:
3189 if ((node
->ns
== NULL
) ||
3190 (node
->ns
->prefix
== NULL
))
3191 return(xmlStrdup(node
->name
));
3193 ret
= xmlStrdup(node
->ns
->prefix
);
3194 ret
= xmlStrcat(ret
, BAD_CAST
":");
3195 ret
= xmlStrcat(ret
, node
->name
);
3198 return(xmlStrdup(BAD_CAST
"#text"));
3199 case XML_CDATA_SECTION_NODE
:
3200 return(xmlStrdup(BAD_CAST
"#cdata-section"));
3201 case XML_ENTITY_NODE
:
3202 case XML_ENTITY_REF_NODE
:
3203 return(xmlStrdup(node
->name
));
3205 return(xmlStrdup(node
->name
));
3206 case XML_COMMENT_NODE
:
3207 return(xmlStrdup(BAD_CAST
"#comment"));
3208 case XML_DOCUMENT_NODE
:
3209 case XML_HTML_DOCUMENT_NODE
:
3210 #ifdef LIBXML_DOCB_ENABLED
3211 case XML_DOCB_DOCUMENT_NODE
:
3213 return(xmlStrdup(BAD_CAST
"#document"));
3214 case XML_DOCUMENT_FRAG_NODE
:
3215 return(xmlStrdup(BAD_CAST
"#document-fragment"));
3216 case XML_NOTATION_NODE
:
3217 return(xmlStrdup(node
->name
));
3218 case XML_DOCUMENT_TYPE_NODE
:
3220 return(xmlStrdup(node
->name
));
3221 case XML_NAMESPACE_DECL
: {
3222 xmlNsPtr ns
= (xmlNsPtr
) node
;
3224 ret
= xmlStrdup(BAD_CAST
"xmlns");
3225 if (ns
->prefix
== NULL
)
3227 ret
= xmlStrcat(ret
, BAD_CAST
":");
3228 ret
= xmlStrcat(ret
, ns
->prefix
);
3232 case XML_ELEMENT_DECL
:
3233 case XML_ATTRIBUTE_DECL
:
3234 case XML_ENTITY_DECL
:
3235 case XML_XINCLUDE_START
:
3236 case XML_XINCLUDE_END
:
3243 * xmlTextReaderConstName:
3244 * @reader: the xmlTextReaderPtr used
3246 * The qualified name of the node, equal to Prefix :LocalName.
3248 * Returns the local name or NULL if not available, the string is
3249 * deallocated with the reader.
3252 xmlTextReaderConstName(xmlTextReaderPtr reader
) {
3255 if ((reader
== NULL
) || (reader
->node
== NULL
))
3257 if (reader
->curnode
!= NULL
)
3258 node
= reader
->curnode
;
3260 node
= reader
->node
;
3261 switch (node
->type
) {
3262 case XML_ELEMENT_NODE
:
3263 case XML_ATTRIBUTE_NODE
:
3264 if ((node
->ns
== NULL
) ||
3265 (node
->ns
->prefix
== NULL
))
3267 return(CONSTQSTR(node
->ns
->prefix
, node
->name
));
3269 return(CONSTSTR(BAD_CAST
"#text"));
3270 case XML_CDATA_SECTION_NODE
:
3271 return(CONSTSTR(BAD_CAST
"#cdata-section"));
3272 case XML_ENTITY_NODE
:
3273 case XML_ENTITY_REF_NODE
:
3274 return(CONSTSTR(node
->name
));
3276 return(CONSTSTR(node
->name
));
3277 case XML_COMMENT_NODE
:
3278 return(CONSTSTR(BAD_CAST
"#comment"));
3279 case XML_DOCUMENT_NODE
:
3280 case XML_HTML_DOCUMENT_NODE
:
3281 #ifdef LIBXML_DOCB_ENABLED
3282 case XML_DOCB_DOCUMENT_NODE
:
3284 return(CONSTSTR(BAD_CAST
"#document"));
3285 case XML_DOCUMENT_FRAG_NODE
:
3286 return(CONSTSTR(BAD_CAST
"#document-fragment"));
3287 case XML_NOTATION_NODE
:
3288 return(CONSTSTR(node
->name
));
3289 case XML_DOCUMENT_TYPE_NODE
:
3291 return(CONSTSTR(node
->name
));
3292 case XML_NAMESPACE_DECL
: {
3293 xmlNsPtr ns
= (xmlNsPtr
) node
;
3295 if (ns
->prefix
== NULL
)
3296 return(CONSTSTR(BAD_CAST
"xmlns"));
3297 return(CONSTQSTR(BAD_CAST
"xmlns", ns
->prefix
));
3300 case XML_ELEMENT_DECL
:
3301 case XML_ATTRIBUTE_DECL
:
3302 case XML_ENTITY_DECL
:
3303 case XML_XINCLUDE_START
:
3304 case XML_XINCLUDE_END
:
3311 * xmlTextReaderPrefix:
3312 * @reader: the xmlTextReaderPtr used
3314 * A shorthand reference to the namespace associated with the node.
3316 * Returns the prefix or NULL if not available,
3317 * if non NULL it need to be freed by the caller.
3320 xmlTextReaderPrefix(xmlTextReaderPtr reader
) {
3322 if ((reader
== NULL
) || (reader
->node
== NULL
))
3324 if (reader
->curnode
!= NULL
)
3325 node
= reader
->curnode
;
3327 node
= reader
->node
;
3328 if (node
->type
== XML_NAMESPACE_DECL
) {
3329 xmlNsPtr ns
= (xmlNsPtr
) node
;
3330 if (ns
->prefix
== NULL
)
3332 return(xmlStrdup(BAD_CAST
"xmlns"));
3334 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3335 (node
->type
!= XML_ATTRIBUTE_NODE
))
3337 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3338 return(xmlStrdup(node
->ns
->prefix
));
3343 * xmlTextReaderConstPrefix:
3344 * @reader: the xmlTextReaderPtr used
3346 * A shorthand reference to the namespace associated with the node.
3348 * Returns the prefix or NULL if not available, the string is deallocated
3352 xmlTextReaderConstPrefix(xmlTextReaderPtr reader
) {
3354 if ((reader
== NULL
) || (reader
->node
== NULL
))
3356 if (reader
->curnode
!= NULL
)
3357 node
= reader
->curnode
;
3359 node
= reader
->node
;
3360 if (node
->type
== XML_NAMESPACE_DECL
) {
3361 xmlNsPtr ns
= (xmlNsPtr
) node
;
3362 if (ns
->prefix
== NULL
)
3364 return(CONSTSTR(BAD_CAST
"xmlns"));
3366 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3367 (node
->type
!= XML_ATTRIBUTE_NODE
))
3369 if ((node
->ns
!= NULL
) && (node
->ns
->prefix
!= NULL
))
3370 return(CONSTSTR(node
->ns
->prefix
));
3375 * xmlTextReaderNamespaceUri:
3376 * @reader: the xmlTextReaderPtr used
3378 * The URI defining the namespace associated with the node.
3380 * Returns the namespace URI or NULL if not available,
3381 * if non NULL it need to be freed by the caller.
3384 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader
) {
3386 if ((reader
== NULL
) || (reader
->node
== NULL
))
3388 if (reader
->curnode
!= NULL
)
3389 node
= reader
->curnode
;
3391 node
= reader
->node
;
3392 if (node
->type
== XML_NAMESPACE_DECL
)
3393 return(xmlStrdup(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3394 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3395 (node
->type
!= XML_ATTRIBUTE_NODE
))
3397 if (node
->ns
!= NULL
)
3398 return(xmlStrdup(node
->ns
->href
));
3403 * xmlTextReaderConstNamespaceUri:
3404 * @reader: the xmlTextReaderPtr used
3406 * The URI defining the namespace associated with the node.
3408 * Returns the namespace URI or NULL if not available, the string
3409 * will be deallocated with the reader
3412 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader
) {
3414 if ((reader
== NULL
) || (reader
->node
== NULL
))
3416 if (reader
->curnode
!= NULL
)
3417 node
= reader
->curnode
;
3419 node
= reader
->node
;
3420 if (node
->type
== XML_NAMESPACE_DECL
)
3421 return(CONSTSTR(BAD_CAST
"http://www.w3.org/2000/xmlns/"));
3422 if ((node
->type
!= XML_ELEMENT_NODE
) &&
3423 (node
->type
!= XML_ATTRIBUTE_NODE
))
3425 if (node
->ns
!= NULL
)
3426 return(CONSTSTR(node
->ns
->href
));
3431 * xmlTextReaderBaseUri:
3432 * @reader: the xmlTextReaderPtr used
3434 * The base URI of the node.
3436 * Returns the base URI or NULL if not available,
3437 * if non NULL it need to be freed by the caller.
3440 xmlTextReaderBaseUri(xmlTextReaderPtr reader
) {
3441 if ((reader
== NULL
) || (reader
->node
== NULL
))
3443 return(xmlNodeGetBase(NULL
, reader
->node
));
3447 * xmlTextReaderConstBaseUri:
3448 * @reader: the xmlTextReaderPtr used
3450 * The base URI of the node.
3452 * Returns the base URI or NULL if not available, the string
3453 * will be deallocated with the reader
3456 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader
) {
3460 if ((reader
== NULL
) || (reader
->node
== NULL
))
3462 tmp
= xmlNodeGetBase(NULL
, reader
->node
);
3465 ret
= CONSTSTR(tmp
);
3471 * xmlTextReaderDepth:
3472 * @reader: the xmlTextReaderPtr used
3474 * The depth of the node in the tree.
3476 * Returns the depth or -1 in case of error
3479 xmlTextReaderDepth(xmlTextReaderPtr reader
) {
3482 if (reader
->node
== NULL
)
3485 if (reader
->curnode
!= NULL
) {
3486 if ((reader
->curnode
->type
== XML_ATTRIBUTE_NODE
) ||
3487 (reader
->curnode
->type
== XML_NAMESPACE_DECL
))
3488 return(reader
->depth
+ 1);
3489 return(reader
->depth
+ 2);
3491 return(reader
->depth
);
3495 * xmlTextReaderHasAttributes:
3496 * @reader: the xmlTextReaderPtr used
3498 * Whether the node has attributes.
3500 * Returns 1 if true, 0 if false, and -1 in case or error
3503 xmlTextReaderHasAttributes(xmlTextReaderPtr reader
) {
3507 if (reader
->node
== NULL
)
3509 if (reader
->curnode
!= NULL
)
3510 node
= reader
->curnode
;
3512 node
= reader
->node
;
3514 if ((node
->type
== XML_ELEMENT_NODE
) &&
3515 ((node
->properties
!= NULL
) || (node
->nsDef
!= NULL
)))
3517 /* TODO: handle the xmlDecl */
3522 * xmlTextReaderHasValue:
3523 * @reader: the xmlTextReaderPtr used
3525 * Whether the node can have a text value.
3527 * Returns 1 if true, 0 if false, and -1 in case or error
3530 xmlTextReaderHasValue(xmlTextReaderPtr reader
) {
3534 if (reader
->node
== NULL
)
3536 if (reader
->curnode
!= NULL
)
3537 node
= reader
->curnode
;
3539 node
= reader
->node
;
3541 switch (node
->type
) {
3542 case XML_ATTRIBUTE_NODE
:
3544 case XML_CDATA_SECTION_NODE
:
3546 case XML_COMMENT_NODE
:
3547 case XML_NAMESPACE_DECL
:
3556 * xmlTextReaderValue:
3557 * @reader: the xmlTextReaderPtr used
3559 * Provides the text value of the node if present
3561 * Returns the string or NULL if not available. The result must be deallocated
3565 xmlTextReaderValue(xmlTextReaderPtr reader
) {
3569 if (reader
->node
== NULL
)
3571 if (reader
->curnode
!= NULL
)
3572 node
= reader
->curnode
;
3574 node
= reader
->node
;
3576 switch (node
->type
) {
3577 case XML_NAMESPACE_DECL
:
3578 return(xmlStrdup(((xmlNsPtr
) node
)->href
));
3579 case XML_ATTRIBUTE_NODE
:{
3580 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3582 if (attr
->parent
!= NULL
)
3583 return (xmlNodeListGetString
3584 (attr
->parent
->doc
, attr
->children
, 1));
3586 return (xmlNodeListGetString(NULL
, attr
->children
, 1));
3590 case XML_CDATA_SECTION_NODE
:
3592 case XML_COMMENT_NODE
:
3593 if (node
->content
!= NULL
)
3594 return (xmlStrdup(node
->content
));
3602 * xmlTextReaderConstValue:
3603 * @reader: the xmlTextReaderPtr used
3605 * Provides the text value of the node if present
3607 * Returns the string or NULL if not available. The result will be
3608 * deallocated on the next Read() operation.
3611 xmlTextReaderConstValue(xmlTextReaderPtr reader
) {
3615 if (reader
->node
== NULL
)
3617 if (reader
->curnode
!= NULL
)
3618 node
= reader
->curnode
;
3620 node
= reader
->node
;
3622 switch (node
->type
) {
3623 case XML_NAMESPACE_DECL
:
3624 return(((xmlNsPtr
) node
)->href
);
3625 case XML_ATTRIBUTE_NODE
:{
3626 xmlAttrPtr attr
= (xmlAttrPtr
) node
;
3629 if ((attr
->children
!= NULL
) &&
3630 (attr
->children
->type
== XML_TEXT_NODE
) &&
3631 (attr
->children
->next
== NULL
))
3632 return(attr
->children
->content
);
3634 if (reader
->buffer
== NULL
) {
3635 reader
->buffer
= xmlBufCreateSize(100);
3636 if (reader
->buffer
== NULL
) {
3637 xmlGenericError(xmlGenericErrorContext
,
3638 "xmlTextReaderSetup : malloc failed\n");
3641 xmlBufSetAllocationScheme(reader
->buffer
,
3642 XML_BUFFER_ALLOC_BOUNDED
);
3644 xmlBufEmpty(reader
->buffer
);
3645 xmlBufGetNodeContent(reader
->buffer
, node
);
3646 ret
= xmlBufContent(reader
->buffer
);
3648 /* error on the buffer best to reallocate */
3649 xmlBufFree(reader
->buffer
);
3650 reader
->buffer
= xmlBufCreateSize(100);
3651 xmlBufSetAllocationScheme(reader
->buffer
,
3652 XML_BUFFER_ALLOC_BOUNDED
);
3660 case XML_CDATA_SECTION_NODE
:
3662 case XML_COMMENT_NODE
:
3663 return(node
->content
);
3671 * xmlTextReaderIsDefault:
3672 * @reader: the xmlTextReaderPtr used
3674 * Whether an Attribute node was generated from the default value
3675 * defined in the DTD or schema.
3677 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
3680 xmlTextReaderIsDefault(xmlTextReaderPtr reader
) {
3687 * xmlTextReaderQuoteChar:
3688 * @reader: the xmlTextReaderPtr used
3690 * The quotation mark character used to enclose the value of an attribute.
3692 * Returns " or ' and -1 in case of error
3695 xmlTextReaderQuoteChar(xmlTextReaderPtr reader
) {
3698 /* TODO maybe lookup the attribute value for " first */
3703 * xmlTextReaderXmlLang:
3704 * @reader: the xmlTextReaderPtr used
3706 * The xml:lang scope within which the node resides.
3708 * Returns the xml:lang value or NULL if none exists.,
3709 * if non NULL it need to be freed by the caller.
3712 xmlTextReaderXmlLang(xmlTextReaderPtr reader
) {
3715 if (reader
->node
== NULL
)
3717 return(xmlNodeGetLang(reader
->node
));
3721 * xmlTextReaderConstXmlLang:
3722 * @reader: the xmlTextReaderPtr used
3724 * The xml:lang scope within which the node resides.
3726 * Returns the xml:lang value or NULL if none exists.
3729 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader
) {
3735 if (reader
->node
== NULL
)
3737 tmp
= xmlNodeGetLang(reader
->node
);
3740 ret
= CONSTSTR(tmp
);
3746 * xmlTextReaderConstString:
3747 * @reader: the xmlTextReaderPtr used
3748 * @str: the string to intern.
3750 * Get an interned string from the reader, allows for example to
3751 * speedup string name comparisons
3753 * Returns an interned copy of the string or NULL in case of error. The
3754 * string will be deallocated with the reader.
3757 xmlTextReaderConstString(xmlTextReaderPtr reader
, const xmlChar
*str
) {
3760 return(CONSTSTR(str
));
3764 * xmlTextReaderNormalization:
3765 * @reader: the xmlTextReaderPtr used
3767 * The value indicating whether to normalize white space and attribute values.
3768 * Since attribute value and end of line normalizations are a MUST in the XML
3769 * specification only the value true is accepted. The broken bahaviour of
3770 * accepting out of range character entities like � is of course not
3773 * Returns 1 or -1 in case of error.
3776 xmlTextReaderNormalization(xmlTextReaderPtr reader
) {
3782 /************************************************************************
3784 * Extensions to the base APIs *
3786 ************************************************************************/
3789 * xmlTextReaderSetParserProp:
3790 * @reader: the xmlTextReaderPtr used
3791 * @prop: the xmlParserProperties to set
3792 * @value: usually 0 or 1 to (de)activate it
3794 * Change the parser processing behaviour by changing some of its internal
3795 * properties. Note that some properties can only be changed before any
3796 * read has been done.
3798 * Returns 0 if the call was successful, or -1 in case of error
3801 xmlTextReaderSetParserProp(xmlTextReaderPtr reader
, int prop
, int value
) {
3802 xmlParserProperties p
= (xmlParserProperties
) prop
;
3803 xmlParserCtxtPtr ctxt
;
3805 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3807 ctxt
= reader
->ctxt
;
3810 case XML_PARSER_LOADDTD
:
3812 if (ctxt
->loadsubset
== 0) {
3813 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
3815 ctxt
->loadsubset
= XML_DETECT_IDS
;
3818 ctxt
->loadsubset
= 0;
3821 case XML_PARSER_DEFAULTATTRS
:
3823 ctxt
->loadsubset
|= XML_COMPLETE_ATTRS
;
3825 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3826 ctxt
->loadsubset
-= XML_COMPLETE_ATTRS
;
3829 case XML_PARSER_VALIDATE
:
3832 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
3837 case XML_PARSER_SUBST_ENTITIES
:
3839 ctxt
->replaceEntities
= 1;
3841 ctxt
->replaceEntities
= 0;
3849 * xmlTextReaderGetParserProp:
3850 * @reader: the xmlTextReaderPtr used
3851 * @prop: the xmlParserProperties to get
3853 * Read the parser internal property.
3855 * Returns the value, usually 0 or 1, or -1 in case of error.
3858 xmlTextReaderGetParserProp(xmlTextReaderPtr reader
, int prop
) {
3859 xmlParserProperties p
= (xmlParserProperties
) prop
;
3860 xmlParserCtxtPtr ctxt
;
3862 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
3864 ctxt
= reader
->ctxt
;
3867 case XML_PARSER_LOADDTD
:
3868 if ((ctxt
->loadsubset
!= 0) || (ctxt
->validate
!= 0))
3871 case XML_PARSER_DEFAULTATTRS
:
3872 if (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)
3875 case XML_PARSER_VALIDATE
:
3876 return(reader
->validate
);
3877 case XML_PARSER_SUBST_ENTITIES
:
3878 return(ctxt
->replaceEntities
);
3885 * xmlTextReaderGetParserLineNumber:
3886 * @reader: the user data (XML reader context)
3888 * Provide the line number of the current parsing point.
3890 * Returns an int or 0 if not available
3893 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader
)
3895 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3896 (reader
->ctxt
->input
== NULL
)) {
3899 return (reader
->ctxt
->input
->line
);
3903 * xmlTextReaderGetParserColumnNumber:
3904 * @reader: the user data (XML reader context)
3906 * Provide the column number of the current parsing point.
3908 * Returns an int or 0 if not available
3911 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader
)
3913 if ((reader
== NULL
) || (reader
->ctxt
== NULL
) ||
3914 (reader
->ctxt
->input
== NULL
)) {
3917 return (reader
->ctxt
->input
->col
);
3921 * xmlTextReaderCurrentNode:
3922 * @reader: the xmlTextReaderPtr used
3924 * Hacking interface allowing to get the xmlNodePtr correponding to the
3925 * current node being accessed by the xmlTextReader. This is dangerous
3926 * because the underlying node may be destroyed on the next Reads.
3928 * Returns the xmlNodePtr or NULL in case of error.
3931 xmlTextReaderCurrentNode(xmlTextReaderPtr reader
) {
3935 if (reader
->curnode
!= NULL
)
3936 return(reader
->curnode
);
3937 return(reader
->node
);
3941 * xmlTextReaderPreserve:
3942 * @reader: the xmlTextReaderPtr used
3944 * This tells the XML Reader to preserve the current node.
3945 * The caller must also use xmlTextReaderCurrentDoc() to
3946 * keep an handle on the resulting document once parsing has finished
3948 * Returns the xmlNodePtr or NULL in case of error.
3951 xmlTextReaderPreserve(xmlTextReaderPtr reader
) {
3952 xmlNodePtr cur
, parent
;
3957 if (reader
->curnode
!= NULL
)
3958 cur
= reader
->curnode
;
3964 if ((cur
->type
!= XML_DOCUMENT_NODE
) && (cur
->type
!= XML_DTD_NODE
)) {
3965 cur
->extra
|= NODE_IS_PRESERVED
;
3966 cur
->extra
|= NODE_IS_SPRESERVED
;
3968 reader
->preserves
++;
3970 parent
= cur
->parent
;;
3971 while (parent
!= NULL
) {
3972 if (parent
->type
== XML_ELEMENT_NODE
)
3973 parent
->extra
|= NODE_IS_PRESERVED
;
3974 parent
= parent
->parent
;
3979 #ifdef LIBXML_PATTERN_ENABLED
3981 * xmlTextReaderPreservePattern:
3982 * @reader: the xmlTextReaderPtr used
3983 * @pattern: an XPath subset pattern
3984 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
3986 * This tells the XML Reader to preserve all nodes matched by the
3987 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
3988 * keep an handle on the resulting document once parsing has finished
3990 * Returns a non-negative number in case of success and -1 in case of error
3993 xmlTextReaderPreservePattern(xmlTextReaderPtr reader
, const xmlChar
*pattern
,
3994 const xmlChar
**namespaces
)
3998 if ((reader
== NULL
) || (pattern
== NULL
))
4001 comp
= xmlPatterncompile(pattern
, reader
->dict
, 0, namespaces
);
4005 if (reader
->patternMax
<= 0) {
4006 reader
->patternMax
= 4;
4007 reader
->patternTab
= (xmlPatternPtr
*) xmlMalloc(reader
->patternMax
*
4008 sizeof(reader
->patternTab
[0]));
4009 if (reader
->patternTab
== NULL
) {
4010 xmlGenericError(xmlGenericErrorContext
, "xmlMalloc failed !\n");
4014 if (reader
->patternNr
>= reader
->patternMax
) {
4016 reader
->patternMax
*= 2;
4017 tmp
= (xmlPatternPtr
*) xmlRealloc(reader
->patternTab
,
4018 reader
->patternMax
*
4019 sizeof(reader
->patternTab
[0]));
4021 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4022 reader
->patternMax
/= 2;
4025 reader
->patternTab
= tmp
;
4027 reader
->patternTab
[reader
->patternNr
] = comp
;
4028 return(reader
->patternNr
++);
4033 * xmlTextReaderCurrentDoc:
4034 * @reader: the xmlTextReaderPtr used
4036 * Hacking interface allowing to get the xmlDocPtr correponding to the
4037 * current document being accessed by the xmlTextReader.
4038 * NOTE: as a result of this call, the reader will not destroy the
4039 * associated XML document and calling xmlFreeDoc() on the result
4040 * is needed once the reader parsing has finished.
4042 * Returns the xmlDocPtr or NULL in case of error.
4045 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader
) {
4048 if (reader
->doc
!= NULL
)
4049 return(reader
->doc
);
4050 if ((reader
->ctxt
== NULL
) || (reader
->ctxt
->myDoc
== NULL
))
4053 reader
->preserve
= 1;
4054 return(reader
->ctxt
->myDoc
);
4057 #ifdef LIBXML_SCHEMAS_ENABLED
4058 static char *xmlTextReaderBuildMessage(const char *msg
, va_list ap
) LIBXML_ATTR_FORMAT(1,0);
4060 static void XMLCDECL
4061 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
4063 static void XMLCDECL
4064 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
4066 static void XMLCDECL
4067 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
4069 static void XMLCDECL
4070 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...) LIBXML_ATTR_FORMAT(2,3);
4072 static void XMLCDECL
4073 xmlTextReaderValidityErrorRelay(void *ctx
, const char *msg
, ...)
4075 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4082 str
= xmlTextReaderBuildMessage(msg
, ap
);
4083 if (!reader
->errorFunc
) {
4084 xmlTextReaderValidityError(ctx
, "%s", str
);
4086 reader
->errorFunc(reader
->errorFuncArg
, str
,
4087 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4088 NULL
/* locator */ );
4095 static void XMLCDECL
4096 xmlTextReaderValidityWarningRelay(void *ctx
, const char *msg
, ...)
4098 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
;
4105 str
= xmlTextReaderBuildMessage(msg
, ap
);
4106 if (!reader
->errorFunc
) {
4107 xmlTextReaderValidityWarning(ctx
, "%s", str
);
4109 reader
->errorFunc(reader
->errorFuncArg
, str
,
4110 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4111 NULL
/* locator */ );
4119 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
);
4122 xmlTextReaderValidityStructuredRelay(void *userData
, xmlErrorPtr error
)
4124 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) userData
;
4126 if (reader
->sErrorFunc
) {
4127 reader
->sErrorFunc(reader
->errorFuncArg
, error
);
4129 xmlTextReaderStructuredError(reader
, error
);
4133 * xmlTextReaderRelaxNGSetSchema:
4134 * @reader: the xmlTextReaderPtr used
4135 * @schema: a precompiled RelaxNG schema
4137 * Use RelaxNG to validate the document as it is processed.
4138 * Activation is only possible before the first Read().
4139 * if @schema is NULL, then RelaxNG validation is desactivated.
4140 @ The @schema should not be freed until the reader is deallocated
4141 * or its use has been deactivated.
4143 * Returns 0 in case the RelaxNG validation could be (des)activated and
4144 * -1 in case of error.
4147 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader
, xmlRelaxNGPtr schema
) {
4150 if (schema
== NULL
) {
4151 if (reader
->rngSchemas
!= NULL
) {
4152 xmlRelaxNGFree(reader
->rngSchemas
);
4153 reader
->rngSchemas
= NULL
;
4155 if (reader
->rngValidCtxt
!= NULL
) {
4156 if (! reader
->rngPreserveCtxt
)
4157 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4158 reader
->rngValidCtxt
= NULL
;
4160 reader
->rngPreserveCtxt
= 0;
4163 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4165 if (reader
->rngSchemas
!= NULL
) {
4166 xmlRelaxNGFree(reader
->rngSchemas
);
4167 reader
->rngSchemas
= NULL
;
4169 if (reader
->rngValidCtxt
!= NULL
) {
4170 if (! reader
->rngPreserveCtxt
)
4171 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4172 reader
->rngValidCtxt
= NULL
;
4174 reader
->rngPreserveCtxt
= 0;
4175 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(schema
);
4176 if (reader
->rngValidCtxt
== NULL
)
4178 if (reader
->errorFunc
!= NULL
) {
4179 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4180 xmlTextReaderValidityErrorRelay
,
4181 xmlTextReaderValidityWarningRelay
,
4184 if (reader
->sErrorFunc
!= NULL
) {
4185 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4186 xmlTextReaderValidityStructuredRelay
,
4189 reader
->rngValidErrors
= 0;
4190 reader
->rngFullNode
= NULL
;
4191 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4196 * xmlTextReaderLocator:
4197 * @ctx: the xmlTextReaderPtr used
4198 * @file: returned file information
4199 * @line: returned line information
4201 * Internal locator function for the readers
4203 * Returns 0 in case the Schema validation could be (des)activated and
4204 * -1 in case of error.
4207 xmlTextReaderLocator(void *ctx
, const char **file
, unsigned long *line
) {
4208 xmlTextReaderPtr reader
;
4210 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
4218 reader
= (xmlTextReaderPtr
) ctx
;
4219 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->input
!= NULL
)) {
4221 *file
= reader
->ctxt
->input
->filename
;
4223 *line
= reader
->ctxt
->input
->line
;
4226 if (reader
->node
!= NULL
) {
4231 res
= xmlGetLineNo(reader
->node
);
4233 *line
= (unsigned long) res
;
4238 xmlDocPtr doc
= reader
->node
->doc
;
4239 if ((doc
!= NULL
) && (doc
->URL
!= NULL
))
4240 *file
= (const char *) doc
->URL
;
4250 * xmlTextReaderSetSchema:
4251 * @reader: the xmlTextReaderPtr used
4252 * @schema: a precompiled Schema schema
4254 * Use XSD Schema to validate the document as it is processed.
4255 * Activation is only possible before the first Read().
4256 * if @schema is NULL, then Schema validation is desactivated.
4257 @ The @schema should not be freed until the reader is deallocated
4258 * or its use has been deactivated.
4260 * Returns 0 in case the Schema validation could be (des)activated and
4261 * -1 in case of error.
4264 xmlTextReaderSetSchema(xmlTextReaderPtr reader
, xmlSchemaPtr schema
) {
4267 if (schema
== NULL
) {
4268 if (reader
->xsdPlug
!= NULL
) {
4269 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4270 reader
->xsdPlug
= NULL
;
4272 if (reader
->xsdValidCtxt
!= NULL
) {
4273 if (! reader
->xsdPreserveCtxt
)
4274 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4275 reader
->xsdValidCtxt
= NULL
;
4277 reader
->xsdPreserveCtxt
= 0;
4278 if (reader
->xsdSchemas
!= NULL
) {
4279 xmlSchemaFree(reader
->xsdSchemas
);
4280 reader
->xsdSchemas
= NULL
;
4284 if (reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
)
4286 if (reader
->xsdPlug
!= NULL
) {
4287 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4288 reader
->xsdPlug
= NULL
;
4290 if (reader
->xsdValidCtxt
!= NULL
) {
4291 if (! reader
->xsdPreserveCtxt
)
4292 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4293 reader
->xsdValidCtxt
= NULL
;
4295 reader
->xsdPreserveCtxt
= 0;
4296 if (reader
->xsdSchemas
!= NULL
) {
4297 xmlSchemaFree(reader
->xsdSchemas
);
4298 reader
->xsdSchemas
= NULL
;
4300 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(schema
);
4301 if (reader
->xsdValidCtxt
== NULL
) {
4302 xmlSchemaFree(reader
->xsdSchemas
);
4303 reader
->xsdSchemas
= NULL
;
4306 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4307 &(reader
->ctxt
->sax
),
4308 &(reader
->ctxt
->userData
));
4309 if (reader
->xsdPlug
== NULL
) {
4310 xmlSchemaFree(reader
->xsdSchemas
);
4311 reader
->xsdSchemas
= NULL
;
4312 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4313 reader
->xsdValidCtxt
= NULL
;
4316 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4317 xmlTextReaderLocator
,
4320 if (reader
->errorFunc
!= NULL
) {
4321 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4322 xmlTextReaderValidityErrorRelay
,
4323 xmlTextReaderValidityWarningRelay
,
4326 if (reader
->sErrorFunc
!= NULL
) {
4327 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4328 xmlTextReaderValidityStructuredRelay
,
4331 reader
->xsdValidErrors
= 0;
4332 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4337 * xmlTextReaderRelaxNGValidateInternal:
4338 * @reader: the xmlTextReaderPtr used
4339 * @rng: the path to a RelaxNG schema or NULL
4340 * @ctxt: the RelaxNG schema validation context or NULL
4341 * @options: options (not yet used)
4343 * Use RelaxNG to validate the document as it is processed.
4344 * Activation is only possible before the first Read().
4345 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
4347 * Returns 0 in case the RelaxNG validation could be (de)activated and
4348 * -1 in case of error.
4351 xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader
,
4353 xmlRelaxNGValidCtxtPtr ctxt
,
4354 int options ATTRIBUTE_UNUSED
)
4359 if ((rng
!= NULL
) && (ctxt
!= NULL
))
4362 if (((rng
!= NULL
) || (ctxt
!= NULL
)) &&
4363 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4364 (reader
->ctxt
== NULL
)))
4367 /* Cleanup previous validation stuff. */
4368 if (reader
->rngValidCtxt
!= NULL
) {
4369 if ( !reader
->rngPreserveCtxt
)
4370 xmlRelaxNGFreeValidCtxt(reader
->rngValidCtxt
);
4371 reader
->rngValidCtxt
= NULL
;
4373 reader
->rngPreserveCtxt
= 0;
4374 if (reader
->rngSchemas
!= NULL
) {
4375 xmlRelaxNGFree(reader
->rngSchemas
);
4376 reader
->rngSchemas
= NULL
;
4379 if ((rng
== NULL
) && (ctxt
== NULL
)) {
4380 /* We just want to deactivate the validation, so get out. */
4386 xmlRelaxNGParserCtxtPtr pctxt
;
4387 /* Parse the schema and create validation environment. */
4389 pctxt
= xmlRelaxNGNewParserCtxt(rng
);
4390 if (reader
->errorFunc
!= NULL
) {
4391 xmlRelaxNGSetParserErrors(pctxt
,
4392 xmlTextReaderValidityErrorRelay
,
4393 xmlTextReaderValidityWarningRelay
,
4396 if (reader
->sErrorFunc
!= NULL
) {
4397 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4398 xmlTextReaderValidityStructuredRelay
,
4401 reader
->rngSchemas
= xmlRelaxNGParse(pctxt
);
4402 xmlRelaxNGFreeParserCtxt(pctxt
);
4403 if (reader
->rngSchemas
== NULL
)
4405 reader
->rngValidCtxt
= xmlRelaxNGNewValidCtxt(reader
->rngSchemas
);
4406 if (reader
->rngValidCtxt
== NULL
) {
4407 xmlRelaxNGFree(reader
->rngSchemas
);
4408 reader
->rngSchemas
= NULL
;
4412 /* Use the given validation context. */
4413 reader
->rngValidCtxt
= ctxt
;
4414 reader
->rngPreserveCtxt
= 1;
4417 * Redirect the validation context's error channels to use
4418 * the reader channels.
4419 * TODO: In case the user provides the validation context we
4420 * could make this redirection optional.
4422 if (reader
->errorFunc
!= NULL
) {
4423 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4424 xmlTextReaderValidityErrorRelay
,
4425 xmlTextReaderValidityWarningRelay
,
4428 if (reader
->sErrorFunc
!= NULL
) {
4429 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
4430 xmlTextReaderValidityStructuredRelay
,
4433 reader
->rngValidErrors
= 0;
4434 reader
->rngFullNode
= NULL
;
4435 reader
->validate
= XML_TEXTREADER_VALIDATE_RNG
;
4440 * xmlTextReaderSchemaValidateInternal:
4441 * @reader: the xmlTextReaderPtr used
4442 * @xsd: the path to a W3C XSD schema or NULL
4443 * @ctxt: the XML Schema validation context or NULL
4444 * @options: options (not used yet)
4446 * Validate the document as it is processed using XML Schema.
4447 * Activation is only possible before the first Read().
4448 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
4450 * Returns 0 in case the schemas validation could be (de)activated and
4451 * -1 in case of error.
4454 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader
,
4456 xmlSchemaValidCtxtPtr ctxt
,
4457 int options ATTRIBUTE_UNUSED
)
4462 if ((xsd
!= NULL
) && (ctxt
!= NULL
))
4465 if (((xsd
!= NULL
) || (ctxt
!= NULL
)) &&
4466 ((reader
->mode
!= XML_TEXTREADER_MODE_INITIAL
) ||
4467 (reader
->ctxt
== NULL
)))
4470 /* Cleanup previous validation stuff. */
4471 if (reader
->xsdPlug
!= NULL
) {
4472 xmlSchemaSAXUnplug(reader
->xsdPlug
);
4473 reader
->xsdPlug
= NULL
;
4475 if (reader
->xsdValidCtxt
!= NULL
) {
4476 if (! reader
->xsdPreserveCtxt
)
4477 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4478 reader
->xsdValidCtxt
= NULL
;
4480 reader
->xsdPreserveCtxt
= 0;
4481 if (reader
->xsdSchemas
!= NULL
) {
4482 xmlSchemaFree(reader
->xsdSchemas
);
4483 reader
->xsdSchemas
= NULL
;
4486 if ((xsd
== NULL
) && (ctxt
== NULL
)) {
4487 /* We just want to deactivate the validation, so get out. */
4492 xmlSchemaParserCtxtPtr pctxt
;
4493 /* Parse the schema and create validation environment. */
4494 pctxt
= xmlSchemaNewParserCtxt(xsd
);
4495 if (reader
->errorFunc
!= NULL
) {
4496 xmlSchemaSetParserErrors(pctxt
,
4497 xmlTextReaderValidityErrorRelay
,
4498 xmlTextReaderValidityWarningRelay
,
4501 reader
->xsdSchemas
= xmlSchemaParse(pctxt
);
4502 xmlSchemaFreeParserCtxt(pctxt
);
4503 if (reader
->xsdSchemas
== NULL
)
4505 reader
->xsdValidCtxt
= xmlSchemaNewValidCtxt(reader
->xsdSchemas
);
4506 if (reader
->xsdValidCtxt
== NULL
) {
4507 xmlSchemaFree(reader
->xsdSchemas
);
4508 reader
->xsdSchemas
= NULL
;
4511 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4512 &(reader
->ctxt
->sax
),
4513 &(reader
->ctxt
->userData
));
4514 if (reader
->xsdPlug
== NULL
) {
4515 xmlSchemaFree(reader
->xsdSchemas
);
4516 reader
->xsdSchemas
= NULL
;
4517 xmlSchemaFreeValidCtxt(reader
->xsdValidCtxt
);
4518 reader
->xsdValidCtxt
= NULL
;
4522 /* Use the given validation context. */
4523 reader
->xsdValidCtxt
= ctxt
;
4524 reader
->xsdPreserveCtxt
= 1;
4525 reader
->xsdPlug
= xmlSchemaSAXPlug(reader
->xsdValidCtxt
,
4526 &(reader
->ctxt
->sax
),
4527 &(reader
->ctxt
->userData
));
4528 if (reader
->xsdPlug
== NULL
) {
4529 reader
->xsdValidCtxt
= NULL
;
4530 reader
->xsdPreserveCtxt
= 0;
4534 xmlSchemaValidateSetLocator(reader
->xsdValidCtxt
,
4535 xmlTextReaderLocator
,
4538 * Redirect the validation context's error channels to use
4539 * the reader channels.
4540 * TODO: In case the user provides the validation context we
4541 * could make this redirection optional.
4543 if (reader
->errorFunc
!= NULL
) {
4544 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4545 xmlTextReaderValidityErrorRelay
,
4546 xmlTextReaderValidityWarningRelay
,
4549 if (reader
->sErrorFunc
!= NULL
) {
4550 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
4551 xmlTextReaderValidityStructuredRelay
,
4554 reader
->xsdValidErrors
= 0;
4555 reader
->validate
= XML_TEXTREADER_VALIDATE_XSD
;
4560 * xmlTextReaderSchemaValidateCtxt:
4561 * @reader: the xmlTextReaderPtr used
4562 * @ctxt: the XML Schema validation context or NULL
4563 * @options: options (not used yet)
4565 * Use W3C XSD schema context to validate the document as it is processed.
4566 * Activation is only possible before the first Read().
4567 * If @ctxt is NULL, then XML Schema validation is deactivated.
4569 * Returns 0 in case the schemas validation could be (de)activated and
4570 * -1 in case of error.
4573 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader
,
4574 xmlSchemaValidCtxtPtr ctxt
,
4577 return(xmlTextReaderSchemaValidateInternal(reader
, NULL
, ctxt
, options
));
4581 * xmlTextReaderSchemaValidate:
4582 * @reader: the xmlTextReaderPtr used
4583 * @xsd: the path to a W3C XSD schema or NULL
4585 * Use W3C XSD schema to validate the document as it is processed.
4586 * Activation is only possible before the first Read().
4587 * If @xsd is NULL, then XML Schema validation is deactivated.
4589 * Returns 0 in case the schemas validation could be (de)activated and
4590 * -1 in case of error.
4593 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader
, const char *xsd
)
4595 return(xmlTextReaderSchemaValidateInternal(reader
, xsd
, NULL
, 0));
4599 * xmlTextReaderRelaxNGValidateCtxt:
4600 * @reader: the xmlTextReaderPtr used
4601 * @ctxt: the RelaxNG schema validation context or NULL
4602 * @options: options (not used yet)
4604 * Use RelaxNG schema context to validate the document as it is processed.
4605 * Activation is only possible before the first Read().
4606 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
4608 * Returns 0 in case the schemas validation could be (de)activated and
4609 * -1 in case of error.
4612 xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader
,
4613 xmlRelaxNGValidCtxtPtr ctxt
,
4616 return(xmlTextReaderRelaxNGValidateInternal(reader
, NULL
, ctxt
, options
));
4620 * xmlTextReaderRelaxNGValidate:
4621 * @reader: the xmlTextReaderPtr used
4622 * @rng: the path to a RelaxNG schema or NULL
4624 * Use RelaxNG schema to validate the document as it is processed.
4625 * Activation is only possible before the first Read().
4626 * If @rng is NULL, then RelaxNG schema validation is deactivated.
4628 * Returns 0 in case the schemas validation could be (de)activated and
4629 * -1 in case of error.
4632 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader
, const char *rng
)
4634 return(xmlTextReaderRelaxNGValidateInternal(reader
, rng
, NULL
, 0));
4640 * xmlTextReaderIsNamespaceDecl:
4641 * @reader: the xmlTextReaderPtr used
4643 * Determine whether the current node is a namespace declaration
4644 * rather than a regular attribute.
4646 * Returns 1 if the current node is a namespace declaration, 0 if it
4647 * is a regular attribute or other type of node, or -1 in case of
4651 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader
) {
4655 if (reader
->node
== NULL
)
4657 if (reader
->curnode
!= NULL
)
4658 node
= reader
->curnode
;
4660 node
= reader
->node
;
4662 if (XML_NAMESPACE_DECL
== node
->type
)
4669 * xmlTextReaderConstXmlVersion:
4670 * @reader: the xmlTextReaderPtr used
4672 * Determine the XML version of the document being read.
4674 * Returns a string containing the XML version of the document or NULL
4675 * in case of error. The string is deallocated with the reader.
4678 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader
) {
4679 xmlDocPtr doc
= NULL
;
4682 if (reader
->doc
!= NULL
)
4684 else if (reader
->ctxt
!= NULL
)
4685 doc
= reader
->ctxt
->myDoc
;
4689 if (doc
->version
== NULL
)
4692 return(CONSTSTR(doc
->version
));
4696 * xmlTextReaderStandalone:
4697 * @reader: the xmlTextReaderPtr used
4699 * Determine the standalone status of the document being read.
4701 * Returns 1 if the document was declared to be standalone, 0 if it
4702 * was declared to be not standalone, or -1 if the document did not
4703 * specify its standalone status or in case of error.
4706 xmlTextReaderStandalone(xmlTextReaderPtr reader
) {
4707 xmlDocPtr doc
= NULL
;
4710 if (reader
->doc
!= NULL
)
4712 else if (reader
->ctxt
!= NULL
)
4713 doc
= reader
->ctxt
->myDoc
;
4717 return(doc
->standalone
);
4720 /************************************************************************
4722 * Error Handling Extensions *
4724 ************************************************************************/
4726 /* helper to build a xmlMalloc'ed string from a format and va_list */
4728 xmlTextReaderBuildMessage(const char *msg
, va_list ap
) {
4737 chars
= vsnprintf(str
, size
, msg
, aq
);
4740 xmlGenericError(xmlGenericErrorContext
, "vsnprintf failed !\n");
4745 if ((chars
< size
) || (size
== MAX_ERR_MSG_SIZE
))
4747 if (chars
< MAX_ERR_MSG_SIZE
)
4750 size
= MAX_ERR_MSG_SIZE
;
4751 if ((larger
= (char *) xmlRealloc(str
, size
)) == NULL
) {
4752 xmlGenericError(xmlGenericErrorContext
, "xmlRealloc failed !\n");
4764 * xmlTextReaderLocatorLineNumber:
4765 * @locator: the xmlTextReaderLocatorPtr used
4767 * Obtain the line number for the given locator.
4769 * Returns the line number or -1 in case of error.
4772 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator
) {
4773 /* we know that locator is a xmlParserCtxtPtr */
4774 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4777 if (locator
== NULL
)
4779 if (ctx
->node
!= NULL
) {
4780 ret
= xmlGetLineNo(ctx
->node
);
4783 /* inspired from error.c */
4784 xmlParserInputPtr input
;
4786 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4787 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4788 if (input
!= NULL
) {
4800 * xmlTextReaderLocatorBaseURI:
4801 * @locator: the xmlTextReaderLocatorPtr used
4803 * Obtain the base URI for the given locator.
4805 * Returns the base URI or NULL in case of error,
4806 * if non NULL it need to be freed by the caller.
4809 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator
) {
4810 /* we know that locator is a xmlParserCtxtPtr */
4811 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
)locator
;
4812 xmlChar
*ret
= NULL
;
4814 if (locator
== NULL
)
4816 if (ctx
->node
!= NULL
) {
4817 ret
= xmlNodeGetBase(NULL
,ctx
->node
);
4820 /* inspired from error.c */
4821 xmlParserInputPtr input
;
4823 if ((input
->filename
== NULL
) && (ctx
->inputNr
> 1))
4824 input
= ctx
->inputTab
[ctx
->inputNr
- 2];
4825 if (input
!= NULL
) {
4826 ret
= xmlStrdup(BAD_CAST input
->filename
);
4837 xmlTextReaderGenericError(void *ctxt
, xmlParserSeverities severity
,
4840 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4842 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4845 if (reader
->errorFunc
)
4846 reader
->errorFunc(reader
->errorFuncArg
, str
, severity
,
4847 (xmlTextReaderLocatorPtr
) ctx
);
4853 xmlTextReaderStructuredError(void *ctxt
, xmlErrorPtr error
)
4855 xmlParserCtxtPtr ctx
= (xmlParserCtxtPtr
) ctxt
;
4857 xmlTextReaderPtr reader
= (xmlTextReaderPtr
) ctx
->_private
;
4859 if (error
&& reader
->sErrorFunc
) {
4860 reader
->sErrorFunc(reader
->errorFuncArg
, (xmlErrorPtr
) error
);
4864 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4865 xmlTextReaderError(void *ctxt
, const char *msg
, ...)
4870 xmlTextReaderGenericError(ctxt
,
4871 XML_PARSER_SEVERITY_ERROR
,
4872 xmlTextReaderBuildMessage(msg
, ap
));
4877 static void XMLCDECL
LIBXML_ATTR_FORMAT(2,3)
4878 xmlTextReaderWarning(void *ctxt
, const char *msg
, ...)
4883 xmlTextReaderGenericError(ctxt
,
4884 XML_PARSER_SEVERITY_WARNING
,
4885 xmlTextReaderBuildMessage(msg
, ap
));
4889 static void XMLCDECL
4890 xmlTextReaderValidityError(void *ctxt
, const char *msg
, ...)
4894 int len
= xmlStrlen((const xmlChar
*) msg
);
4896 if ((len
> 1) && (msg
[len
- 2] != ':')) {
4898 * some callbacks only report locator information:
4899 * skip them (mimicking behaviour in error.c)
4902 xmlTextReaderGenericError(ctxt
,
4903 XML_PARSER_SEVERITY_VALIDITY_ERROR
,
4904 xmlTextReaderBuildMessage(msg
, ap
));
4909 static void XMLCDECL
4910 xmlTextReaderValidityWarning(void *ctxt
, const char *msg
, ...)
4914 int len
= xmlStrlen((const xmlChar
*) msg
);
4916 if ((len
!= 0) && (msg
[len
- 1] != ':')) {
4918 * some callbacks only report locator information:
4919 * skip them (mimicking behaviour in error.c)
4922 xmlTextReaderGenericError(ctxt
,
4923 XML_PARSER_SEVERITY_VALIDITY_WARNING
,
4924 xmlTextReaderBuildMessage(msg
, ap
));
4930 * xmlTextReaderSetErrorHandler:
4931 * @reader: the xmlTextReaderPtr used
4932 * @f: the callback function to call on error and warnings
4933 * @arg: a user argument to pass to the callback function
4935 * Register a callback function that will be called on error and warnings.
4937 * If @f is NULL, the default error and warning handlers are restored.
4940 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader
,
4941 xmlTextReaderErrorFunc f
, void *arg
)
4944 reader
->ctxt
->sax
->error
= xmlTextReaderError
;
4945 reader
->ctxt
->sax
->serror
= NULL
;
4946 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
4947 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
4948 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
4949 reader
->errorFunc
= f
;
4950 reader
->sErrorFunc
= NULL
;
4951 reader
->errorFuncArg
= arg
;
4952 #ifdef LIBXML_SCHEMAS_ENABLED
4953 if (reader
->rngValidCtxt
) {
4954 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
,
4955 xmlTextReaderValidityErrorRelay
,
4956 xmlTextReaderValidityWarningRelay
,
4958 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4961 if (reader
->xsdValidCtxt
) {
4962 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
,
4963 xmlTextReaderValidityErrorRelay
,
4964 xmlTextReaderValidityWarningRelay
,
4966 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4971 /* restore defaults */
4972 reader
->ctxt
->sax
->error
= xmlParserError
;
4973 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
4974 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
4975 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
4976 reader
->errorFunc
= NULL
;
4977 reader
->sErrorFunc
= NULL
;
4978 reader
->errorFuncArg
= NULL
;
4979 #ifdef LIBXML_SCHEMAS_ENABLED
4980 if (reader
->rngValidCtxt
) {
4981 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
4983 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
4986 if (reader
->xsdValidCtxt
) {
4987 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
4989 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
4997 * xmlTextReaderSetStructuredErrorHandler:
4998 * @reader: the xmlTextReaderPtr used
4999 * @f: the callback function to call on error and warnings
5000 * @arg: a user argument to pass to the callback function
5002 * Register a callback function that will be called on error and warnings.
5004 * If @f is NULL, the default error and warning handlers are restored.
5007 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader
,
5008 xmlStructuredErrorFunc f
, void *arg
)
5011 reader
->ctxt
->sax
->error
= NULL
;
5012 reader
->ctxt
->sax
->serror
= xmlTextReaderStructuredError
;
5013 reader
->ctxt
->vctxt
.error
= xmlTextReaderValidityError
;
5014 reader
->ctxt
->sax
->warning
= xmlTextReaderWarning
;
5015 reader
->ctxt
->vctxt
.warning
= xmlTextReaderValidityWarning
;
5016 reader
->sErrorFunc
= f
;
5017 reader
->errorFunc
= NULL
;
5018 reader
->errorFuncArg
= arg
;
5019 #ifdef LIBXML_SCHEMAS_ENABLED
5020 if (reader
->rngValidCtxt
) {
5021 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
5023 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
,
5024 xmlTextReaderValidityStructuredRelay
,
5027 if (reader
->xsdValidCtxt
) {
5028 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
5030 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
,
5031 xmlTextReaderValidityStructuredRelay
,
5036 /* restore defaults */
5037 reader
->ctxt
->sax
->error
= xmlParserError
;
5038 reader
->ctxt
->sax
->serror
= NULL
;
5039 reader
->ctxt
->vctxt
.error
= xmlParserValidityError
;
5040 reader
->ctxt
->sax
->warning
= xmlParserWarning
;
5041 reader
->ctxt
->vctxt
.warning
= xmlParserValidityWarning
;
5042 reader
->errorFunc
= NULL
;
5043 reader
->sErrorFunc
= NULL
;
5044 reader
->errorFuncArg
= NULL
;
5045 #ifdef LIBXML_SCHEMAS_ENABLED
5046 if (reader
->rngValidCtxt
) {
5047 xmlRelaxNGSetValidErrors(reader
->rngValidCtxt
, NULL
, NULL
,
5049 xmlRelaxNGSetValidStructuredErrors(reader
->rngValidCtxt
, NULL
,
5052 if (reader
->xsdValidCtxt
) {
5053 xmlSchemaSetValidErrors(reader
->xsdValidCtxt
, NULL
, NULL
,
5055 xmlSchemaSetValidStructuredErrors(reader
->xsdValidCtxt
, NULL
,
5063 * xmlTextReaderIsValid:
5064 * @reader: the xmlTextReaderPtr used
5066 * Retrieve the validity status from the parser context
5068 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
5071 xmlTextReaderIsValid(xmlTextReaderPtr reader
)
5075 #ifdef LIBXML_SCHEMAS_ENABLED
5076 if (reader
->validate
== XML_TEXTREADER_VALIDATE_RNG
)
5077 return (reader
->rngValidErrors
== 0);
5078 if (reader
->validate
== XML_TEXTREADER_VALIDATE_XSD
)
5079 return (reader
->xsdValidErrors
== 0);
5081 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->validate
== 1))
5082 return (reader
->ctxt
->valid
);
5087 * xmlTextReaderGetErrorHandler:
5088 * @reader: the xmlTextReaderPtr used
5089 * @f: the callback function or NULL is no callback has been registered
5090 * @arg: a user argument
5092 * Retrieve the error callback function and user argument.
5095 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader
,
5096 xmlTextReaderErrorFunc
* f
, void **arg
)
5099 *f
= reader
->errorFunc
;
5101 *arg
= reader
->errorFuncArg
;
5103 /************************************************************************
5105 * New set (2.6.0) of simpler and more flexible APIs *
5107 ************************************************************************/
5110 * xmlTextReaderSetup:
5111 * @reader: an XML reader
5112 * @input: xmlParserInputBufferPtr used to feed the reader, will
5113 * be destroyed with it.
5114 * @URL: the base URL to use for the document
5115 * @encoding: the document encoding, or NULL
5116 * @options: a combination of xmlParserOption
5118 * Setup an XML reader with new options
5120 * Returns 0 in case of success and -1 in case of error.
5123 xmlTextReaderSetup(xmlTextReaderPtr reader
,
5124 xmlParserInputBufferPtr input
, const char *URL
,
5125 const char *encoding
, int options
)
5127 if (reader
== NULL
) {
5129 xmlFreeParserInputBuffer(input
);
5134 * we force the generation of compact text nodes on the reader
5135 * since usr applications should never modify the tree
5137 options
|= XML_PARSE_COMPACT
;
5141 reader
->parserFlags
= options
;
5142 reader
->validate
= XML_TEXTREADER_NOT_VALIDATE
;
5143 if ((input
!= NULL
) && (reader
->input
!= NULL
) &&
5144 (reader
->allocs
& XML_TEXTREADER_INPUT
)) {
5145 xmlFreeParserInputBuffer(reader
->input
);
5146 reader
->input
= NULL
;
5147 reader
->allocs
-= XML_TEXTREADER_INPUT
;
5149 if (input
!= NULL
) {
5150 reader
->input
= input
;
5151 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5153 if (reader
->buffer
== NULL
)
5154 reader
->buffer
= xmlBufCreateSize(100);
5155 if (reader
->buffer
== NULL
) {
5156 xmlGenericError(xmlGenericErrorContext
,
5157 "xmlTextReaderSetup : malloc failed\n");
5160 /* no operation on a reader should require a huge buffer */
5161 xmlBufSetAllocationScheme(reader
->buffer
,
5162 XML_BUFFER_ALLOC_BOUNDED
);
5163 if (reader
->sax
== NULL
)
5164 reader
->sax
= (xmlSAXHandler
*) xmlMalloc(sizeof(xmlSAXHandler
));
5165 if (reader
->sax
== NULL
) {
5166 xmlGenericError(xmlGenericErrorContext
,
5167 "xmlTextReaderSetup : malloc failed\n");
5170 xmlSAXVersion(reader
->sax
, 2);
5171 reader
->startElement
= reader
->sax
->startElement
;
5172 reader
->sax
->startElement
= xmlTextReaderStartElement
;
5173 reader
->endElement
= reader
->sax
->endElement
;
5174 reader
->sax
->endElement
= xmlTextReaderEndElement
;
5175 #ifdef LIBXML_SAX1_ENABLED
5176 if (reader
->sax
->initialized
== XML_SAX2_MAGIC
) {
5177 #endif /* LIBXML_SAX1_ENABLED */
5178 reader
->startElementNs
= reader
->sax
->startElementNs
;
5179 reader
->sax
->startElementNs
= xmlTextReaderStartElementNs
;
5180 reader
->endElementNs
= reader
->sax
->endElementNs
;
5181 reader
->sax
->endElementNs
= xmlTextReaderEndElementNs
;
5182 #ifdef LIBXML_SAX1_ENABLED
5184 reader
->startElementNs
= NULL
;
5185 reader
->endElementNs
= NULL
;
5187 #endif /* LIBXML_SAX1_ENABLED */
5188 reader
->characters
= reader
->sax
->characters
;
5189 reader
->sax
->characters
= xmlTextReaderCharacters
;
5190 reader
->sax
->ignorableWhitespace
= xmlTextReaderCharacters
;
5191 reader
->cdataBlock
= reader
->sax
->cdataBlock
;
5192 reader
->sax
->cdataBlock
= xmlTextReaderCDataBlock
;
5194 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5195 reader
->node
= NULL
;
5196 reader
->curnode
= NULL
;
5197 if (input
!= NULL
) {
5198 if (xmlBufUse(reader
->input
->buffer
) < 4) {
5199 xmlParserInputBufferRead(input
, 4);
5201 if (reader
->ctxt
== NULL
) {
5202 if (xmlBufUse(reader
->input
->buffer
) >= 4) {
5203 reader
->ctxt
= xmlCreatePushParserCtxt(reader
->sax
, NULL
,
5204 (const char *) xmlBufContent(reader
->input
->buffer
),
5210 xmlCreatePushParserCtxt(reader
->sax
, NULL
, NULL
, 0, URL
);
5215 xmlParserInputPtr inputStream
;
5216 xmlParserInputBufferPtr buf
;
5217 xmlCharEncoding enc
= XML_CHAR_ENCODING_NONE
;
5219 xmlCtxtReset(reader
->ctxt
);
5220 buf
= xmlAllocParserInputBuffer(enc
);
5221 if (buf
== NULL
) return(-1);
5222 inputStream
= xmlNewInputStream(reader
->ctxt
);
5223 if (inputStream
== NULL
) {
5224 xmlFreeParserInputBuffer(buf
);
5229 inputStream
->filename
= NULL
;
5231 inputStream
->filename
= (char *)
5232 xmlCanonicPath((const xmlChar
*) URL
);
5233 inputStream
->buf
= buf
;
5234 xmlBufResetInput(buf
->buffer
, inputStream
);
5236 inputPush(reader
->ctxt
, inputStream
);
5239 if (reader
->ctxt
== NULL
) {
5240 xmlGenericError(xmlGenericErrorContext
,
5241 "xmlTextReaderSetup : malloc failed\n");
5245 if (reader
->dict
!= NULL
) {
5246 if (reader
->ctxt
->dict
!= NULL
) {
5247 if (reader
->dict
!= reader
->ctxt
->dict
) {
5248 xmlDictFree(reader
->dict
);
5249 reader
->dict
= reader
->ctxt
->dict
;
5252 reader
->ctxt
->dict
= reader
->dict
;
5255 if (reader
->ctxt
->dict
== NULL
)
5256 reader
->ctxt
->dict
= xmlDictCreate();
5257 reader
->dict
= reader
->ctxt
->dict
;
5259 reader
->ctxt
->_private
= reader
;
5260 reader
->ctxt
->linenumbers
= 1;
5261 reader
->ctxt
->dictNames
= 1;
5263 * use the parser dictionary to allocate all elements and attributes names
5265 reader
->ctxt
->docdict
= 1;
5266 reader
->ctxt
->parseMode
= XML_PARSE_READER
;
5268 #ifdef LIBXML_XINCLUDE_ENABLED
5269 if (reader
->xincctxt
!= NULL
) {
5270 xmlXIncludeFreeContext(reader
->xincctxt
);
5271 reader
->xincctxt
= NULL
;
5273 if (options
& XML_PARSE_XINCLUDE
) {
5274 reader
->xinclude
= 1;
5275 reader
->xinclude_name
= xmlDictLookup(reader
->dict
, XINCLUDE_NODE
, -1);
5276 options
-= XML_PARSE_XINCLUDE
;
5278 reader
->xinclude
= 0;
5279 reader
->in_xinclude
= 0;
5281 #ifdef LIBXML_PATTERN_ENABLED
5282 if (reader
->patternTab
== NULL
) {
5283 reader
->patternNr
= 0;
5284 reader
->patternMax
= 0;
5286 while (reader
->patternNr
> 0) {
5287 reader
->patternNr
--;
5288 if (reader
->patternTab
[reader
->patternNr
] != NULL
) {
5289 xmlFreePattern(reader
->patternTab
[reader
->patternNr
]);
5290 reader
->patternTab
[reader
->patternNr
] = NULL
;
5295 if (options
& XML_PARSE_DTDVALID
)
5296 reader
->validate
= XML_TEXTREADER_VALIDATE_DTD
;
5298 xmlCtxtUseOptions(reader
->ctxt
, options
);
5299 if (encoding
!= NULL
) {
5300 xmlCharEncodingHandlerPtr hdlr
;
5302 hdlr
= xmlFindCharEncodingHandler(encoding
);
5304 xmlSwitchToEncoding(reader
->ctxt
, hdlr
);
5306 if ((URL
!= NULL
) && (reader
->ctxt
->input
!= NULL
) &&
5307 (reader
->ctxt
->input
->filename
== NULL
))
5308 reader
->ctxt
->input
->filename
= (char *)
5309 xmlStrdup((const xmlChar
*) URL
);
5317 * xmlTextReaderByteConsumed:
5318 * @reader: an XML reader
5320 * This function provides the current index of the parser used
5321 * by the reader, relative to the start of the current entity.
5322 * This function actually just wraps a call to xmlBytesConsumed()
5323 * for the parser context associated with the reader.
5324 * See xmlBytesConsumed() for more information.
5326 * Returns the index in bytes from the beginning of the entity or -1
5327 * in case the index could not be computed.
5330 xmlTextReaderByteConsumed(xmlTextReaderPtr reader
) {
5331 if ((reader
== NULL
) || (reader
->ctxt
== NULL
))
5333 return(xmlByteConsumed(reader
->ctxt
));
5339 * @doc: a preparsed document
5341 * Create an xmltextReader for a preparsed document.
5343 * Returns the new reader or NULL in case of error.
5346 xmlReaderWalker(xmlDocPtr doc
)
5348 xmlTextReaderPtr ret
;
5353 ret
= xmlMalloc(sizeof(xmlTextReader
));
5355 xmlGenericError(xmlGenericErrorContext
,
5356 "xmlNewTextReader : malloc failed\n");
5359 memset(ret
, 0, sizeof(xmlTextReader
));
5362 ret
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5364 ret
->curnode
= NULL
;
5367 ret
->allocs
= XML_TEXTREADER_CTXT
;
5369 ret
->state
= XML_TEXTREADER_START
;
5370 ret
->dict
= xmlDictCreate();
5376 * @cur: a pointer to a zero terminated string
5377 * @URL: the base URL to use for the document
5378 * @encoding: the document encoding, or NULL
5379 * @options: a combination of xmlParserOption
5381 * Create an xmltextReader for an XML in-memory document.
5382 * The parsing flags @options are a combination of xmlParserOption.
5384 * Returns the new reader or NULL in case of error.
5387 xmlReaderForDoc(const xmlChar
* cur
, const char *URL
, const char *encoding
,
5394 len
= xmlStrlen(cur
);
5396 return (xmlReaderForMemory
5397 ((const char *) cur
, len
, URL
, encoding
, options
));
5402 * @filename: a file or URL
5403 * @encoding: the document encoding, or NULL
5404 * @options: a combination of xmlParserOption
5406 * parse an XML file from the filesystem or the network.
5407 * The parsing flags @options are a combination of xmlParserOption.
5409 * Returns the new reader or NULL in case of error.
5412 xmlReaderForFile(const char *filename
, const char *encoding
, int options
)
5414 xmlTextReaderPtr reader
;
5416 reader
= xmlNewTextReaderFilename(filename
);
5419 xmlTextReaderSetup(reader
, NULL
, NULL
, encoding
, options
);
5424 * xmlReaderForMemory:
5425 * @buffer: a pointer to a char array
5426 * @size: the size of the array
5427 * @URL: the base URL to use for the document
5428 * @encoding: the document encoding, or NULL
5429 * @options: a combination of xmlParserOption
5431 * Create an xmltextReader for an XML in-memory document.
5432 * The parsing flags @options are a combination of xmlParserOption.
5434 * Returns the new reader or NULL in case of error.
5437 xmlReaderForMemory(const char *buffer
, int size
, const char *URL
,
5438 const char *encoding
, int options
)
5440 xmlTextReaderPtr reader
;
5441 xmlParserInputBufferPtr buf
;
5443 buf
= xmlParserInputBufferCreateStatic(buffer
, size
,
5444 XML_CHAR_ENCODING_NONE
);
5448 reader
= xmlNewTextReader(buf
, URL
);
5449 if (reader
== NULL
) {
5450 xmlFreeParserInputBuffer(buf
);
5453 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5454 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5460 * @fd: an open file descriptor
5461 * @URL: the base URL to use for the document
5462 * @encoding: the document encoding, or NULL
5463 * @options: a combination of xmlParserOption
5465 * Create an xmltextReader for an XML from a file descriptor.
5466 * The parsing flags @options are a combination of xmlParserOption.
5467 * NOTE that the file descriptor will not be closed when the
5468 * reader is closed or reset.
5470 * Returns the new reader or NULL in case of error.
5473 xmlReaderForFd(int fd
, const char *URL
, const char *encoding
, int options
)
5475 xmlTextReaderPtr reader
;
5476 xmlParserInputBufferPtr input
;
5481 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5484 input
->closecallback
= NULL
;
5485 reader
= xmlNewTextReader(input
, URL
);
5486 if (reader
== NULL
) {
5487 xmlFreeParserInputBuffer(input
);
5490 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5491 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5497 * @ioread: an I/O read function
5498 * @ioclose: an I/O close function
5499 * @ioctx: an I/O handler
5500 * @URL: the base URL to use for the document
5501 * @encoding: the document encoding, or NULL
5502 * @options: a combination of xmlParserOption
5504 * Create an xmltextReader for an XML document from I/O functions and source.
5505 * The parsing flags @options are a combination of xmlParserOption.
5507 * Returns the new reader or NULL in case of error.
5510 xmlReaderForIO(xmlInputReadCallback ioread
, xmlInputCloseCallback ioclose
,
5511 void *ioctx
, const char *URL
, const char *encoding
,
5514 xmlTextReaderPtr reader
;
5515 xmlParserInputBufferPtr input
;
5520 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5521 XML_CHAR_ENCODING_NONE
);
5522 if (input
== NULL
) {
5523 if (ioclose
!= NULL
)
5527 reader
= xmlNewTextReader(input
, URL
);
5528 if (reader
== NULL
) {
5529 xmlFreeParserInputBuffer(input
);
5532 reader
->allocs
|= XML_TEXTREADER_INPUT
;
5533 xmlTextReaderSetup(reader
, NULL
, URL
, encoding
, options
);
5538 * xmlReaderNewWalker:
5539 * @reader: an XML reader
5540 * @doc: a preparsed document
5542 * Setup an xmltextReader to parse a preparsed XML document.
5543 * This reuses the existing @reader xmlTextReader.
5545 * Returns 0 in case of success and -1 in case of error
5548 xmlReaderNewWalker(xmlTextReaderPtr reader
, xmlDocPtr doc
)
5555 if (reader
->input
!= NULL
) {
5556 xmlFreeParserInputBuffer(reader
->input
);
5558 if (reader
->ctxt
!= NULL
) {
5559 xmlCtxtReset(reader
->ctxt
);
5563 reader
->input
= NULL
;
5564 reader
->mode
= XML_TEXTREADER_MODE_INITIAL
;
5565 reader
->node
= NULL
;
5566 reader
->curnode
= NULL
;
5569 reader
->allocs
= XML_TEXTREADER_CTXT
;
5571 reader
->state
= XML_TEXTREADER_START
;
5572 if (reader
->dict
== NULL
) {
5573 if ((reader
->ctxt
!= NULL
) && (reader
->ctxt
->dict
!= NULL
))
5574 reader
->dict
= reader
->ctxt
->dict
;
5576 reader
->dict
= xmlDictCreate();
5583 * @reader: an XML reader
5584 * @cur: a pointer to a zero terminated string
5585 * @URL: the base URL to use for the document
5586 * @encoding: the document encoding, or NULL
5587 * @options: a combination of xmlParserOption
5589 * Setup an xmltextReader to parse an XML in-memory document.
5590 * The parsing flags @options are a combination of xmlParserOption.
5591 * This reuses the existing @reader xmlTextReader.
5593 * Returns 0 in case of success and -1 in case of error
5596 xmlReaderNewDoc(xmlTextReaderPtr reader
, const xmlChar
* cur
,
5597 const char *URL
, const char *encoding
, int options
)
5607 len
= xmlStrlen(cur
);
5608 return (xmlReaderNewMemory(reader
, (const char *)cur
, len
,
5609 URL
, encoding
, options
));
5614 * @reader: an XML reader
5615 * @filename: a file or URL
5616 * @encoding: the document encoding, or NULL
5617 * @options: a combination of xmlParserOption
5619 * parse an XML file from the filesystem or the network.
5620 * The parsing flags @options are a combination of xmlParserOption.
5621 * This reuses the existing @reader xmlTextReader.
5623 * Returns 0 in case of success and -1 in case of error
5626 xmlReaderNewFile(xmlTextReaderPtr reader
, const char *filename
,
5627 const char *encoding
, int options
)
5629 xmlParserInputBufferPtr input
;
5631 if (filename
== NULL
)
5637 xmlParserInputBufferCreateFilename(filename
,
5638 XML_CHAR_ENCODING_NONE
);
5641 return (xmlTextReaderSetup(reader
, input
, filename
, encoding
, options
));
5645 * xmlReaderNewMemory:
5646 * @reader: an XML reader
5647 * @buffer: a pointer to a char array
5648 * @size: the size of the array
5649 * @URL: the base URL to use for the document
5650 * @encoding: the document encoding, or NULL
5651 * @options: a combination of xmlParserOption
5653 * Setup an xmltextReader to parse an XML in-memory document.
5654 * The parsing flags @options are a combination of xmlParserOption.
5655 * This reuses the existing @reader xmlTextReader.
5657 * Returns 0 in case of success and -1 in case of error
5660 xmlReaderNewMemory(xmlTextReaderPtr reader
, const char *buffer
, int size
,
5661 const char *URL
, const char *encoding
, int options
)
5663 xmlParserInputBufferPtr input
;
5670 input
= xmlParserInputBufferCreateStatic(buffer
, size
,
5671 XML_CHAR_ENCODING_NONE
);
5672 if (input
== NULL
) {
5675 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5680 * @reader: an XML reader
5681 * @fd: an open file descriptor
5682 * @URL: the base URL to use for the document
5683 * @encoding: the document encoding, or NULL
5684 * @options: a combination of xmlParserOption
5686 * Setup an xmltextReader to parse an XML from a file descriptor.
5687 * NOTE that the file descriptor will not be closed when the
5688 * reader is closed or reset.
5689 * The parsing flags @options are a combination of xmlParserOption.
5690 * This reuses the existing @reader xmlTextReader.
5692 * Returns 0 in case of success and -1 in case of error
5695 xmlReaderNewFd(xmlTextReaderPtr reader
, int fd
,
5696 const char *URL
, const char *encoding
, int options
)
5698 xmlParserInputBufferPtr input
;
5705 input
= xmlParserInputBufferCreateFd(fd
, XML_CHAR_ENCODING_NONE
);
5708 input
->closecallback
= NULL
;
5709 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5714 * @reader: an XML reader
5715 * @ioread: an I/O read function
5716 * @ioclose: an I/O close function
5717 * @ioctx: an I/O handler
5718 * @URL: the base URL to use for the document
5719 * @encoding: the document encoding, or NULL
5720 * @options: a combination of xmlParserOption
5722 * Setup an xmltextReader to parse an XML document from I/O functions
5724 * The parsing flags @options are a combination of xmlParserOption.
5725 * This reuses the existing @reader xmlTextReader.
5727 * Returns 0 in case of success and -1 in case of error
5730 xmlReaderNewIO(xmlTextReaderPtr reader
, xmlInputReadCallback ioread
,
5731 xmlInputCloseCallback ioclose
, void *ioctx
,
5732 const char *URL
, const char *encoding
, int options
)
5734 xmlParserInputBufferPtr input
;
5741 input
= xmlParserInputBufferCreateIO(ioread
, ioclose
, ioctx
,
5742 XML_CHAR_ENCODING_NONE
);
5743 if (input
== NULL
) {
5744 if (ioclose
!= NULL
)
5748 return (xmlTextReaderSetup(reader
, input
, URL
, encoding
, options
));
5751 /************************************************************************
5755 ************************************************************************/
5760 * @in: the input buffer
5761 * @inlen: the size of the input (in), the size read from it (out)
5762 * @to: the output buffer
5763 * @tolen: the size of the output (in), the size written to (out)
5765 * Base64 decoder, reads from @in and save in @to
5766 * TODO: tell jody when this is actually exported
5768 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
5769 * 2 if there wasn't enough space on the output or -1 in case of error.
5772 xmlBase64Decode(const unsigned char *in
, unsigned long *inlen
,
5773 unsigned char *to
, unsigned long *tolen
)
5775 unsigned long incur
; /* current index in in[] */
5777 unsigned long inblk
; /* last block index in in[] */
5779 unsigned long outcur
; /* current index in out[] */
5781 unsigned long inmax
; /* size of in[] */
5783 unsigned long outmax
; /* size of out[] */
5785 unsigned char cur
; /* the current value read from in[] */
5787 unsigned char intmp
[4], outtmp
[4]; /* temporary buffers for the convert */
5789 int nbintmp
; /* number of byte in intmp[] */
5791 int is_ignore
; /* cur should be ignored */
5793 int is_end
= 0; /* the end of the base64 was found */
5799 if ((in
== NULL
) || (inlen
== NULL
) || (to
== NULL
) || (tolen
== NULL
))
5814 if ((cur
>= 'A') && (cur
<= 'Z'))
5816 else if ((cur
>= 'a') && (cur
<= 'z'))
5817 cur
= cur
- 'a' + 26;
5818 else if ((cur
>= '0') && (cur
<= '9'))
5819 cur
= cur
- '0' + 52;
5820 else if (cur
== '+')
5822 else if (cur
== '/')
5824 else if (cur
== '.')
5826 else if (cur
== '=') /*no op , end of the base64 stream */
5842 if ((nbintmp
== 1) || (nbintmp
== 2))
5849 intmp
[nbintmp
++] = cur
;
5851 * if intmp is full, push the 4byte sequence as a 3 byte
5856 outtmp
[0] = (intmp
[0] << 2) | ((intmp
[1] & 0x30) >> 4);
5858 ((intmp
[1] & 0x0F) << 4) | ((intmp
[2] & 0x3C) >> 2);
5859 outtmp
[2] = ((intmp
[2] & 0x03) << 6) | (intmp
[3] & 0x3F);
5860 if (outcur
+ 3 >= outmax
) {
5865 for (i
= 0; i
< nbouttmp
; i
++)
5866 to
[outcur
++] = outtmp
[i
];
5883 * Test routine for the xmlBase64Decode function
5887 main(int argc
, char **argv
)
5889 char *input
= " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
5897 unsigned long inlen
= strlen(input
);
5899 unsigned long outlen
= 100;
5903 unsigned long cons
, tmp
, tmp2
, prod
;
5908 ret
= xmlBase64Decode(input
, &inlen
, output
, &outlen
);
5911 printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret
, inlen
,
5912 outlen
, output
)indent
: Standard input
:179: Error
:Unmatched
#endif
5920 while (cons
< inlen
) {
5922 tmp2
= inlen
- cons
;
5924 printf("%ld %ld\n", cons
, prod
);
5925 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output2
[prod
], &tmp
);
5928 printf("%ld %ld\n", cons
, prod
);
5930 output2
[outlen
] = 0;
5931 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5939 while (cons
< inlen
) {
5941 tmp2
= inlen
- cons
;
5945 printf("%ld %ld\n", cons
, prod
);
5946 ret
= xmlBase64Decode(&input
[cons
], &tmp2
, &output3
[prod
], &tmp
);
5949 printf("%ld %ld\n", cons
, prod
);
5951 output3
[outlen
] = 0;
5952 printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret
, cons
,
5958 #endif /* NOT_USED_YET */
5959 #define bottom_xmlreader
5960 #include "elfgcchack.h"
5961 #endif /* LIBXML_READER_ENABLED */