1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-26 10:03:34 +03:00

added TODO for the DTD compatibility spec more bug fixes driven by the

* relaxng.c: added TODO for the DTD compatibility spec
* xinclude.c: more bug fixes driven by the testsuite
Daniel
This commit is contained in:
Daniel Veillard 2003-02-13 11:02:08 +00:00
parent d581b7edd4
commit f4b4f98839
3 changed files with 328 additions and 24 deletions

View File

@ -1,3 +1,8 @@
Thu Feb 13 12:00:30 CET 2003 Daniel Veillard <daniel@veillard.com>
* relaxng.c: added TODO for the DTD compatibility spec
* xinclude.c: more bug fixes driven by the testsuite
Tue Feb 11 19:01:02 CET 2003 Daniel Veillard <daniel@veillard.com> Tue Feb 11 19:01:02 CET 2003 Daniel Veillard <daniel@veillard.com>
* check-xinclude-test-suite.py xinclude.c: Work on the W3C/NIST * check-xinclude-test-suite.py xinclude.c: Work on the W3C/NIST

View File

@ -13,6 +13,8 @@
* - NOT_ALLOWED * - NOT_ALLOWED
* - EMPTY * - EMPTY
* - handle namespace declarations as attributes. * - handle namespace declarations as attributes.
* - add support for DTD compatibility spec
* http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
*/ */
#define IN_LIBXML #define IN_LIBXML

View File

@ -40,6 +40,8 @@
#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text" #define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding" #define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding"
#define XINCLUDE_MAX_DEPTH 40
/* #define DEBUG_XINCLUDE */ /* #define DEBUG_XINCLUDE */
#ifdef DEBUG_XINCLUDE #ifdef DEBUG_XINCLUDE
#ifdef LIBXML_DEBUG_ENABLED #ifdef LIBXML_DEBUG_ENABLED
@ -68,6 +70,7 @@ struct _xmlXIncludeRef {
xmlNodePtr inc; /* the included copy */ xmlNodePtr inc; /* the included copy */
int xml; /* xml or txt */ int xml; /* xml or txt */
int count; /* how many refs use that specific doc */ int count; /* how many refs use that specific doc */
xmlXPathObjectPtr xptr; /* the xpointer if needed */
}; };
typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt; typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
@ -84,6 +87,11 @@ struct _xmlXIncludeCtxt {
xmlNodePtr *txtTab; /* array of unparsed text nodes */ xmlNodePtr *txtTab; /* array of unparsed text nodes */
xmlURL *txturlTab; /* array of unparsed txtuments URLs */ xmlURL *txturlTab; /* array of unparsed txtuments URLs */
xmlChar * url; /* the current URL processed */
int urlNr; /* number of url stacked */
int urlMax; /* size of url stack */
xmlChar * *urlTab; /* url stack */
int nbErrors; /* the number of errors detected */ int nbErrors; /* the number of errors detected */
}; };
@ -113,6 +121,8 @@ xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
xmlFree(ref->URI); xmlFree(ref->URI);
if (ref->fragment != NULL) if (ref->fragment != NULL)
xmlFree(ref->fragment); xmlFree(ref->fragment);
if (ref->xptr != NULL)
xmlXPathFreeObject(ref->xptr);
xmlFree(ref); xmlFree(ref);
} }
@ -204,6 +214,75 @@ xmlXIncludeNewContext(xmlDocPtr doc) {
return(ret); return(ret);
} }
/**
* xmlXIncludeURLPush:
* @ctxt: the parser context
* @value: the url
*
* Pushes a new url on top of the url stack
*
* Returns -1 in case of error, the index in the stack otherwise
*/
static int
xmlXIncludeURLPush(xmlXIncludeCtxtPtr ctxt,
const xmlChar *value)
{
if (ctxt->urlNr > XINCLUDE_MAX_DEPTH) {
xmlGenericError(xmlGenericErrorContext,
"XInclude: detected a recursion in %s\n",
value);
ctxt->nbErrors++;
return(-1);
}
if (ctxt->urlTab == NULL) {
ctxt->urlMax = 4;
ctxt->urlNr = 0;
ctxt->urlTab = (xmlChar * *) xmlMalloc(
ctxt->urlMax * sizeof(ctxt->urlTab[0]));
if (ctxt->urlTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
return (-1);
}
}
if (ctxt->urlNr >= ctxt->urlMax) {
ctxt->urlMax *= 2;
ctxt->urlTab =
(xmlChar * *) xmlRealloc(ctxt->urlTab,
ctxt->urlMax *
sizeof(ctxt->urlTab[0]));
if (ctxt->urlTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (-1);
}
}
ctxt->url = ctxt->urlTab[ctxt->urlNr] = xmlStrdup(value);
return (ctxt->urlNr++);
}
/**
* xmlXIncludeURLPop:
* @ctxt: the parser context
*
* Pops the top url from the url stack
*/
static void
xmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt)
{
xmlChar * ret;
if (ctxt->urlNr <= 0)
return;
ctxt->urlNr--;
if (ctxt->urlNr > 0)
ctxt->url = ctxt->urlTab[ctxt->urlNr - 1];
else
ctxt->url = NULL;
ret = ctxt->urlTab[ctxt->urlNr];
ctxt->urlTab[ctxt->urlNr] = 0;
if (ret != NULL)
xmlFree(ret);
}
/** /**
* xmlXIncludeFreeContext: * xmlXIncludeFreeContext:
* @ctxt: the XInclude context * @ctxt: the XInclude context
@ -219,6 +298,10 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
#endif #endif
if (ctxt == NULL) if (ctxt == NULL)
return; return;
while (ctxt->urlNr > 0)
xmlXIncludeURLPop(ctxt);
if (ctxt->urlTab != NULL)
xmlFree(ctxt->urlTab);
for (i = 0;i < ctxt->incNr;i++) { for (i = 0;i < ctxt->incNr;i++) {
if (ctxt->incTab[i] != NULL) if (ctxt->incTab[i] != NULL)
xmlXIncludeFreeRef(ctxt->incTab[i]); xmlXIncludeFreeRef(ctxt->incTab[i]);
@ -253,7 +336,8 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
xmlChar *parse; xmlChar *parse;
xmlChar *base; xmlChar *base;
xmlChar *URI; xmlChar *URI;
int xml = 1; /* default Issue 64 */ int xml = 1, i; /* default Issue 64 */
int local = 0;
if (ctxt == NULL) if (ctxt == NULL)
@ -276,6 +360,8 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
return(-1); return(-1);
} }
} }
if (href[0] == '#')
local = 1;
parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE); parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
if (parse == NULL) { if (parse == NULL) {
parse = xmlGetProp(cur, XINCLUDE_PARSE); parse = xmlGetProp(cur, XINCLUDE_PARSE);
@ -359,6 +445,21 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
return(-1); return(-1);
} }
/*
* Check the URL against the stack for recursions
*/
if (!local) {
for (i = 0;i < ctxt->urlNr;i++) {
if (xmlStrEqual(URL, ctxt->urlTab[i])) {
xmlGenericError(xmlGenericErrorContext,
"XInclude: detected a recursion in %s\n",
URL);
ctxt->nbErrors++;
return(-1);
}
}
}
ref = xmlXIncludeNewRef(ctxt, URL, cur); ref = xmlXIncludeNewRef(ctxt, URL, cur);
if (ref == NULL) { if (ref == NULL) {
return(-1); return(-1);
@ -385,6 +486,14 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
xmlXIncludeCtxtPtr newctxt; xmlXIncludeCtxtPtr newctxt;
int i; int i;
/*
* Avoid recursion in already substitued resources
for (i = 0;i < ctxt->urlNr;i++) {
if (xmlStrEqual(doc->URL, ctxt->urlTab[i]))
return;
}
*/
#ifdef DEBUG_XINCLUDE #ifdef DEBUG_XINCLUDE
xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL); xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL);
#endif #endif
@ -408,6 +517,12 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
xmlFree(newctxt); xmlFree(newctxt);
return; return;
} }
/*
* copy the urlTab
*/
newctxt->urlMax = ctxt->urlMax;
newctxt->urlNr = ctxt->urlNr;
newctxt->urlTab = ctxt->urlTab;
/* /*
* Inherit the documents already in use by others includes * Inherit the documents already in use by others includes
@ -423,6 +538,10 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
newctxt->incTab[i]->count--; newctxt->incTab[i]->count--;
newctxt->incTab[i] = NULL; newctxt->incTab[i] = NULL;
} }
newctxt->urlMax = 0;
newctxt->urlNr = 0;
newctxt->urlTab = NULL;
xmlXIncludeFreeContext(newctxt); xmlXIncludeFreeContext(newctxt);
} }
#ifdef DEBUG_XINCLUDE #ifdef DEBUG_XINCLUDE
@ -771,6 +890,8 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
xmlNodePtr list = NULL, last = NULL; xmlNodePtr list = NULL, last = NULL;
int i; int i;
if (source == NULL)
source = ctxt->doc;
if ((ctxt == NULL) || (target == NULL) || (source == NULL) || if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
(obj == NULL)) (obj == NULL))
return(NULL); return(NULL);
@ -795,9 +916,38 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
#ifdef LIBXML_DOCB_ENABLED #ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE: case XML_DOCB_DOCUMENT_NODE:
#endif #endif
case XML_XINCLUDE_START:
case XML_XINCLUDE_END: case XML_XINCLUDE_END:
break; break;
case XML_XINCLUDE_START: {
xmlNodePtr tmp, cur = set->nodeTab[i];
cur = cur->next;
while (cur != NULL) {
switch(cur->type) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ELEMENT_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
tmp = xmlXIncludeCopyNode(ctxt, target,
source, cur);
if (last == NULL) {
list = last = tmp;
} else {
xmlAddNextSibling(last, tmp);
last = tmp;
}
cur = cur->next;
continue;
default:
break;
}
break;
}
continue;
}
case XML_ATTRIBUTE_NODE: case XML_ATTRIBUTE_NODE:
case XML_NAMESPACE_DECL: case XML_NAMESPACE_DECL:
case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_TYPE_NODE:
@ -857,6 +1007,13 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
* * * *
************************************************************************/ ************************************************************************/
typedef struct _xmlXIncludeMergeData xmlXIncludeMergeData;
typedef xmlXIncludeMergeData *xmlXIncludeMergeDataPtr;
struct _xmlXIncludeMergeData {
xmlDocPtr doc;
xmlXIncludeCtxtPtr ctxt;
};
/** /**
* xmlXIncludeMergeOneEntity: * xmlXIncludeMergeOneEntity:
* @ent: the entity * @ent: the entity
@ -866,18 +1023,56 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
* Inplements the merge of one entity * Inplements the merge of one entity
*/ */
static void static void
xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlDocPtr doc, xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data,
xmlChar *name ATTRIBUTE_UNUSED) { xmlChar *name ATTRIBUTE_UNUSED) {
xmlEntityPtr ret; xmlEntityPtr ret, prev;
xmlDocPtr doc;
xmlXIncludeCtxtPtr ctxt;
if ((ent == NULL) || (doc == NULL)) if ((ent == NULL) || (data == NULL))
return; return;
ctxt = data->ctxt;
doc = data->doc;
if ((ctxt == NULL) || (doc == NULL))
return;
switch (ent->etype) {
case XML_INTERNAL_PARAMETER_ENTITY:
case XML_EXTERNAL_PARAMETER_ENTITY:
case XML_INTERNAL_PREDEFINED_ENTITY:
return;
case XML_INTERNAL_GENERAL_ENTITY:
case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
break;
}
ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID, ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
ent->SystemID, ent->content); ent->SystemID, ent->content);
if (ret != NULL) { if (ret != NULL) {
if (ent->URI != NULL) if (ent->URI != NULL)
ret->URI = xmlStrdup(ent->URI); ret->URI = xmlStrdup(ent->URI);
} else {
prev = xmlGetDocEntity(doc, ent->name);
if (prev != NULL) {
if (ent->etype != prev->etype)
goto error;
if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
if (!xmlStrEqual(ent->SystemID, prev->SystemID))
goto error;
} else if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
goto error;
} else {
goto error;
}
}
} }
return;
error:
xmlGenericError(xmlGenericErrorContext,
"XInclude: mismatch in redefinition of entity %s\n", ent->name);
ctxt->nbErrors++;
} }
/** /**
@ -914,18 +1109,28 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
source = from->intSubset; source = from->intSubset;
if ((source != NULL) && (source->entities != NULL)) { if ((source != NULL) && (source->entities != NULL)) {
xmlXIncludeMergeData data;
data.ctxt = ctxt;
data.doc = doc;
xmlHashScan((xmlHashTablePtr) source->entities, xmlHashScan((xmlHashTablePtr) source->entities,
(xmlHashScanner) xmlXIncludeMergeEntity, doc); (xmlHashScanner) xmlXIncludeMergeEntity, &data);
} }
source = from->extSubset; source = from->extSubset;
if ((source != NULL) && (source->entities != NULL)) { if ((source != NULL) && (source->entities != NULL)) {
xmlXIncludeMergeData data;
data.ctxt = ctxt;
data.doc = doc;
/* /*
* don't duplicate existing stuff when external subsets are the same * don't duplicate existing stuff when external subsets are the same
*/ */
if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) && if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) &&
(!xmlStrEqual(target->SystemID, source->SystemID))) { (!xmlStrEqual(target->SystemID, source->SystemID))) {
xmlHashScan((xmlHashTablePtr) source->entities, xmlHashScan((xmlHashTablePtr) source->entities,
(xmlHashScanner) xmlXIncludeMergeEntity, doc); (xmlHashScanner) xmlXIncludeMergeEntity, &data);
} }
} }
return(0); return(0);
@ -981,7 +1186,8 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
* Handling of references to the local document are done * Handling of references to the local document are done
* directly through ctxt->doc. * directly through ctxt->doc.
*/ */
if ((URL[0] == 0) || (URL[0] == '#')) { if ((URL[0] == 0) || (URL[0] == '#') ||
((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) {
doc = NULL; doc = NULL;
goto loaded; goto loaded;
} }
@ -1156,9 +1362,14 @@ loaded:
} }
} }
} }
ctxt->incTab[nr]->inc = if (doc == NULL) {
xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr); ctxt->incTab[nr]->xptr = xptr;
xmlXPathFreeObject(xptr); ctxt->incTab[nr]->inc = NULL;
} else {
ctxt->incTab[nr]->inc =
xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
xmlXPathFreeObject(xptr);
}
xmlXPathFreeContext(xptrctxt); xmlXPathFreeContext(xptrctxt);
xmlFree(fragment); xmlFree(fragment);
} }
@ -1677,7 +1888,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
*/ */
static int static int
xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
xmlNodePtr cur, end, list; xmlNodePtr cur, end, list, tmp;
if (ctxt == NULL) if (ctxt == NULL)
return(-1); return(-1);
@ -1687,6 +1898,41 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
if (cur == NULL) if (cur == NULL)
return(-1); return(-1);
/*
* If we stored an XPointer a late computation may be needed
*/
if ((ctxt->incTab[nr]->inc == NULL) &&
(ctxt->incTab[nr]->xptr != NULL)) {
ctxt->incTab[nr]->inc =
xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc,
ctxt->incTab[nr]->xptr);
xmlXPathFreeObject(ctxt->incTab[nr]->xptr);
ctxt->incTab[nr]->xptr = NULL;
}
list = ctxt->incTab[nr]->inc;
ctxt->incTab[nr]->inc = NULL;
/*
* Check against the risk of generating a multi-rooted document
*/
if ((cur->parent != NULL) &&
(cur->parent->type != XML_ELEMENT_NODE)) {
int nb_elem = 0;
tmp = list;
while (tmp != NULL) {
if (tmp->type == XML_ELEMENT_NODE)
nb_elem++;
tmp = tmp->next;
}
if (nb_elem > 1) {
xmlGenericError(xmlGenericErrorContext,
"XInclude error: would result in multiple root nodes\n");
ctxt->nbErrors++;
return(-1);
}
}
/* /*
* Change the current node as an XInclude start one, and add an * Change the current node as an XInclude start one, and add an
* entity end one * entity end one
@ -1705,8 +1951,6 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
/* /*
* Add the list of nodes * Add the list of nodes
*/ */
list = ctxt->incTab[nr]->inc;
ctxt->incTab[nr]->inc = NULL;
while (list != NULL) { while (list != NULL) {
cur = list; cur = list;
list = list->next; list = list->next;
@ -1720,6 +1964,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
/** /**
* xmlXIncludeTestNode: * xmlXIncludeTestNode:
* @ctxt: the XInclude processing context
* @node: an XInclude node * @node: an XInclude node
* *
* test if the node is an XInclude node * test if the node is an XInclude node
@ -1727,19 +1972,61 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
* Returns 1 true, 0 otherwise * Returns 1 true, 0 otherwise
*/ */
static int static int
xmlXIncludeTestNode(xmlNodePtr node) { xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
if (node == NULL) if (node == NULL)
return(0); return(0);
if (node->ns == NULL) if (node->ns == NULL)
return(0); return(0);
if ((xmlStrEqual(node->name, XINCLUDE_NODE)) && if (xmlStrEqual(node->ns->href, XINCLUDE_NS)) {
(xmlStrEqual(node->ns->href, XINCLUDE_NS))) return(1); if (xmlStrEqual(node->name, XINCLUDE_NODE)) {
xmlNodePtr child = node->children;
int nb_fallback = 0;
while (child != NULL) {
if ((child->type == XML_ELEMENT_NODE) &&
(child->ns != NULL) &&
(xmlStrEqual(child->ns->href, XINCLUDE_NS))) {
if (xmlStrEqual(child->name, XINCLUDE_NODE)) {
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s has an %s child\n",
XINCLUDE_NODE, XINCLUDE_NODE);
ctxt->nbErrors++;
return(0);
}
if (xmlStrEqual(child->name, XINCLUDE_FALLBACK)) {
nb_fallback++;
}
}
child = child->next;
}
if (nb_fallback > 1) {
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s has %d %s children\n",
XINCLUDE_NODE, nb_fallback, XINCLUDE_FALLBACK);
ctxt->nbErrors++;
return(0);
}
return(1);
}
if (xmlStrEqual(node->name, XINCLUDE_FALLBACK)) {
if ((node->parent == NULL) ||
(node->parent->type != XML_ELEMENT_NODE) ||
(node->parent->ns == NULL) ||
(!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) ||
(!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s is not the child of an %s\n",
XINCLUDE_FALLBACK, XINCLUDE_NODE);
ctxt->nbErrors++;
}
}
}
return(0); return(0);
} }
/** /**
* xmlXIncludeDoProcess: * xmlXIncludeDoProcess:
* @ctxt: * @ctxt: the XInclude processing context
* @doc: an XML document * @doc: an XML document
* *
* Implement the XInclude substitution on the XML document @doc * Implement the XInclude substitution on the XML document @doc
@ -1758,22 +2045,28 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
if (ctxt == NULL) if (ctxt == NULL)
return(-1); return(-1);
if (doc->URL != NULL) {
ret = xmlXIncludeURLPush(ctxt, doc->URL);
if (ret < 0)
return(-1);
}
/* /*
* First phase: lookup the elements in the document * First phase: lookup the elements in the document
*/ */
cur = xmlDocGetRootElement(doc); cur = xmlDocGetRootElement(doc);
if (xmlXIncludeTestNode(cur)) if (xmlXIncludeTestNode(ctxt, cur) == 1)
xmlXIncludePreProcessNode(ctxt, cur); xmlXIncludePreProcessNode(ctxt, cur);
while (cur != NULL) { while (cur != NULL) {
/* TODO: need to work on entities -> stack */ /* TODO: need to work on entities -> stack */
if ((cur->children != NULL) && if ((cur->children != NULL) &&
(cur->children->type != XML_ENTITY_DECL)) { (cur->children->type != XML_ENTITY_DECL)) {
cur = cur->children; cur = cur->children;
if (xmlXIncludeTestNode(cur)) if (xmlXIncludeTestNode(ctxt, cur))
xmlXIncludePreProcessNode(ctxt, cur); xmlXIncludePreProcessNode(ctxt, cur);
} else if (cur->next != NULL) { } else if (cur->next != NULL) {
cur = cur->next; cur = cur->next;
if (xmlXIncludeTestNode(cur)) if (xmlXIncludeTestNode(ctxt, cur))
xmlXIncludePreProcessNode(ctxt, cur); xmlXIncludePreProcessNode(ctxt, cur);
} else { } else {
do { do {
@ -1781,7 +2074,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
if (cur == NULL) break; /* do */ if (cur == NULL) break; /* do */
if (cur->next != NULL) { if (cur->next != NULL) {
cur = cur->next; cur = cur->next;
if (xmlXIncludeTestNode(cur)) if (xmlXIncludeTestNode(ctxt, cur))
xmlXIncludePreProcessNode(ctxt, cur); xmlXIncludePreProcessNode(ctxt, cur);
break; /* do */ break; /* do */
} }
@ -1800,10 +2093,14 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
/* /*
* Third phase: extend the original document infoset. * Third phase: extend the original document infoset.
*/ */
for (i = ctxt->incBase;i < ctxt->incNr; i++) { if (ctxt->nbErrors == 0) {
xmlXIncludeIncludeNode(ctxt, i); for (i = ctxt->incBase;i < ctxt->incNr; i++) {
xmlXIncludeIncludeNode(ctxt, i);
}
} }
if (doc->URL != NULL)
xmlXIncludeURLPop(ctxt);
return(ret); return(ret);
} }