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:
parent
d581b7edd4
commit
f4b4f98839
@ -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
|
||||||
|
@ -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
|
||||||
|
345
xinclude.c
345
xinclude.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user