* daniel@veillard.com
*/
-/*
- * TODO: compute XPointers nodesets
- * TODO: add an node intermediate API and handle recursion at this level
- */
-
#define IN_LIBXML
#include "libxml.h"
#define XINCLUDE_MAX_DEPTH 40
-/* #define DEBUG_XINCLUDE */
+/* #define DEBUG_XINCLUDE */
#ifdef DEBUG_XINCLUDE
#ifdef LIBXML_DEBUG_ENABLED
#include <libxml/debugXML.h>
};
static int
-xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc);
+xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree);
+
+
+/**
+ * xmlXIncludeErrorContext:
+ * @ctxt: the XInclude context
+ * @node: the node
+ *
+ * Dump informations about the kocation of the error in the instance
+ */
+static void
+xmlXIncludeErrorContext(xmlXIncludeCtxtPtr ctxt ATTRIBUTE_UNUSED,
+ xmlNodePtr node)
+{
+ int line = 0;
+ const xmlChar *file = NULL;
+ const xmlChar *name = NULL;
+ const char *type = "error";
+
+ if (node == NULL) {
+ return;
+ }
+ if (node != NULL) {
+ if ((node->type == XML_DOCUMENT_NODE) ||
+ (node->type == XML_HTML_DOCUMENT_NODE)) {
+ xmlDocPtr doc = (xmlDocPtr) node;
+
+ file = doc->URL;
+ } else {
+ /*
+ * Try to find contextual informations to report
+ */
+ if (node->type == XML_ELEMENT_NODE) {
+ line = (long) node->content;
+ } else if ((node->prev != NULL) &&
+ (node->prev->type == XML_ELEMENT_NODE)) {
+ line = (long) node->prev->content;
+ } else if ((node->parent != NULL) &&
+ (node->parent->type == XML_ELEMENT_NODE)) {
+ line = (long) node->parent->content;
+ }
+ if ((node->doc != NULL) && (node->doc->URL != NULL))
+ file = node->doc->URL;
+ if (node->name != NULL)
+ name = node->name;
+ }
+ }
+
+ type = "XInclude :";
+
+ if ((file != NULL) && (line != 0) && (name != NULL))
+ xmlGenericError(xmlGenericErrorContext,
+ "%s: file %s line %d element %s\n", type, file,
+ line, name);
+ else if ((file != NULL) && (name != NULL))
+ xmlGenericError(xmlGenericErrorContext, "%s: file %s element %s\n",
+ type, file, name);
+ else if ((file != NULL) && (line != 0))
+ xmlGenericError(xmlGenericErrorContext, "%s: file %s line %d\n",
+ type, file, line);
+ else if (file != NULL)
+ xmlGenericError(xmlGenericErrorContext, "%s: file %s\n", type,
+ file);
+ else if (name != NULL)
+ xmlGenericError(xmlGenericErrorContext, "%s: element %s\n", type,
+ name);
+ else
+ xmlGenericError(xmlGenericErrorContext, "%s\n", type);
+}
/**
* xmlXIncludeFreeRef:
ctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(ctxt->incMax *
sizeof(ctxt->incTab[0]));
if (ctxt->incTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"malloc failed !\n");
ctxt->nbErrors++;
ctxt->incTab = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
ctxt->incMax * sizeof(ctxt->incTab[0]));
if (ctxt->incTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"realloc failed !\n");
xmlXIncludeFreeRef(ret);
const xmlChar *value)
{
if (ctxt->urlNr > XINCLUDE_MAX_DEPTH) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"XInclude: detected a recursion in %s\n",
value);
ctxt->urlTab = (xmlChar * *) xmlMalloc(
ctxt->urlMax * sizeof(ctxt->urlTab[0]));
if (ctxt->urlTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
return (-1);
}
ctxt->urlMax *
sizeof(ctxt->urlTab[0]));
if (ctxt->urlTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (-1);
}
}
/**
+ * xmlXIncludeParseFile:
+ * @ctxt: the XInclude context
+ * @URL: the URL or file path
+ *
+ * parse an document for XInclude
+ */
+static xmlDocPtr
+xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt ATTRIBUTE_UNUSED, const char *URL) {
+ xmlDocPtr ret;
+ xmlParserCtxtPtr pctxt;
+ char *directory = NULL;
+
+ xmlInitParser();
+
+ pctxt = xmlCreateFileParserCtxt(URL);
+ if (pctxt == NULL) {
+ return(NULL);
+ }
+
+ if ((pctxt->directory == NULL) && (directory == NULL))
+ directory = xmlParserGetDirectory(URL);
+ if ((pctxt->directory == NULL) && (directory != NULL))
+ pctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
+
+ pctxt->loadsubset = XML_DETECT_IDS;
+
+ xmlParseDocument(pctxt);
+
+ if (pctxt->wellFormed)
+ ret = pctxt->myDoc;
+ else {
+ ret = NULL;
+ xmlFreeDoc(pctxt->myDoc);
+ pctxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(pctxt);
+
+ return(ret);
+}
+
+/**
* xmlXIncludeAddNode:
* @ctxt: the XInclude context
* @cur: the new node
if (href == NULL) {
href = xmlGetProp(cur, XINCLUDE_HREF);
if (href == NULL) {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
ctxt->nbErrors++;
return(-1);
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
xml = 0;
else {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value %s for %s\n",
parse, XINCLUDE_PARSE);
if (base != NULL)
xmlFree(base);
if (URI == NULL) {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
ctxt->nbErrors++;
return(-1);
*/
uri = xmlParseURI((const char *)URI);
if (uri == NULL) {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", URI);
ctxt->nbErrors++;
xmlFreeURI(uri);
xmlFree(URI);
if (URL == NULL) {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", URI);
ctxt->nbErrors++;
if (!local) {
for (i = 0;i < ctxt->urlNr;i++) {
if (xmlStrEqual(URL, ctxt->urlTab[i])) {
+ xmlXIncludeErrorContext(ctxt, cur);
xmlGenericError(xmlGenericErrorContext,
"XInclude: detected a recursion in %s\n",
URL);
newctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(newctxt->incMax *
sizeof(newctxt->incTab[0]));
if (newctxt->incTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"malloc failed !\n");
ctxt->nbErrors++;
newctxt->incTab[i]->count++; /* prevent the recursion from
freeing it */
}
- xmlXIncludeDoProcess(newctxt, doc);
+ xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc));
for (i = 0;i < ctxt->incNr;i++) {
newctxt->incTab[i]->count--;
newctxt->incTab[i] = NULL;
}
+
+ /* urlTab may have been reallocated */
+ ctxt->urlTab = newctxt->urlTab;
+ ctxt->urlMax = newctxt->urlMax;
+
newctxt->urlMax = 0;
newctxt->urlNr = 0;
newctxt->urlTab = NULL;
ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
sizeof(ctxt->txtTab[0]));
if (ctxt->txtTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"malloc failed !\n");
ctxt->nbErrors++;
ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax *
sizeof(ctxt->txturlTab[0]));
if (ctxt->txturlTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"malloc failed !\n");
ctxt->nbErrors++;
ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
ctxt->txtMax * sizeof(ctxt->txtTab[0]));
if (ctxt->txtTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"realloc failed !\n");
ctxt->nbErrors++;
ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab,
ctxt->txtMax * sizeof(ctxt->txturlTab[0]));
if (ctxt->txturlTab == NULL) {
+ xmlXIncludeErrorContext(ctxt, NULL);
xmlGenericError(xmlGenericErrorContext,
"realloc failed !\n");
ctxt->nbErrors++;
if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
if (!xmlStrEqual(ent->SystemID, prev->SystemID))
goto error;
- } else if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
+ } else if ((ent->ExternalID != NULL) &&
+ (prev->ExternalID != NULL)) {
if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
goto error;
} else if ((ent->content != NULL) && (prev->content != NULL)) {
}
return;
error:
+ switch (ent->etype) {
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ case XML_EXTERNAL_PARAMETER_ENTITY:
+ case XML_INTERNAL_PREDEFINED_ENTITY:
+ case XML_INTERNAL_GENERAL_ENTITY:
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+ return;
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+ break;
+ }
+ xmlXIncludeErrorContext(ctxt, (xmlNodePtr) ent);
xmlGenericError(xmlGenericErrorContext,
"XInclude: mismatch in redefinition of entity %s\n", ent->name);
ctxt->nbErrors++;
*/
uri = xmlParseURI((const char *)url);
if (uri == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", url);
ctxt->nbErrors++;
URL = xmlSaveUri(uri);
xmlFreeURI(uri);
if (URL == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", url);
ctxt->nbErrors++;
#ifdef DEBUG_XINCLUDE
printf("loading %s\n", URL);
#endif
- doc = xmlParseFile((const char *)URL);
+ doc = xmlXIncludeParseFile(ctxt, (const char *)URL);
if (doc == NULL) {
xmlFree(URL);
if (fragment != NULL)
return(-1);
}
ctxt->incTab[nr]->doc = doc;
+ for (i = nr + 1; i < ctxt->incNr; i++) {
+ if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) {
+ ctxt->incTab[nr]->count++;
+#ifdef DEBUG_XINCLUDE
+ printf("Increasing %s count since reused\n", URL);
+#endif
+ break;
+ }
+ }
/*
* Make sure we have all entities fixed up
xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
}
if (xptrctxt == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: could create XPointer context\n");
ctxt->nbErrors++;
}
xptr = xmlXPtrEval(fragment, xptrctxt);
if (xptr == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: XPointer evaluation failed: #%s\n",
fragment);
case XPATH_POINT:
case XPATH_USERS:
case XPATH_XSLT_TREE:
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: XPointer is not a range: #%s\n",
fragment);
#endif
continue;
case XML_ATTRIBUTE_NODE:
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: XPointer selects an attribute: #%s\n",
fragment);
set->nodeTab[i] = NULL;
continue;
case XML_NAMESPACE_DECL:
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: XPointer selects a namespace: #%s\n",
fragment);
case XML_ENTITY_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: XPointer selects unexpected nodes: #%s\n",
fragment);
xmlChar *URL;
int i;
xmlChar *encoding = NULL;
- xmlCharEncoding enc = 0;
+ xmlCharEncoding enc = (xmlCharEncoding) 0;
/*
* Check the URL and remove any fragment identifier
*/
uri = xmlParseURI((const char *)url);
if (uri == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", url);
ctxt->nbErrors++;
return(-1);
}
if (uri->fragment != NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: fragment identifier forbidden for text: %s\n",
uri->fragment);
URL = xmlSaveUri(uri);
xmlFreeURI(uri);
if (URL == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value URI %s\n", url);
ctxt->nbErrors++;
* directly through ctxt->doc.
*/
if (URL[0] == 0) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: text serialization of document not available\n");
ctxt->nbErrors++;
*/
enc = xmlParseCharEncoding((const char *) encoding);
if (enc == XML_CHAR_ENCODING_ERROR) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: encoding %s not supported\n", encoding);
ctxt->nbErrors++;
cur = xmlStringCurrentChar(NULL, &content[i], &l);
if (!IS_CHAR(cur)) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s contains invalid char %d\n", URL, cur);
ctxt->nbErrors++;
return(0);
}
-#if 0
-/**
- * xmlXIncludePreloadNode:
- * @ctxt: an XInclude context
- * @nr: the node number
- *
- * Do some precomputations and preload shared documents
- *
- * Returns 0 if substitution succeeded, -1 if some processing failed
- */
-static int
-xmlXIncludePreloadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
- xmlNodePtr cur;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *URI;
- int xml = 1; /* default Issue 64 */
- xmlURIPtr uri;
- xmlChar *URL;
- xmlChar *fragment = NULL;
- int i;
-
-
- if (ctxt == NULL)
- return(-1);
- if ((nr < 0) || (nr >= ctxt->incNr))
- return(-1);
- cur = ctxt->incTab[nr]->ref;
- if (cur == NULL)
- return(-1);
-
- /*
- * read the attributes
- */
- href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
- if (href == NULL) {
- href = xmlGetProp(cur, XINCLUDE_HREF);
- if (href == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
- return(-1);
- }
- }
- parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
- if (parse == NULL) {
- parse = xmlGetProp(cur, XINCLUDE_PARSE);
- }
- if (parse != NULL) {
- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
- xml = 1;
- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
- xml = 0;
- else {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value %s for %s\n",
- parse, XINCLUDE_PARSE);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(-1);
- }
- }
-
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
- ctxt->nbErrors++;
- return(-1);
- }
-
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)URI);
- if (uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- ctxt->nbErrors++;
- xmlFree(URI);
- return(-1);
- }
- if (uri->fragment != NULL) {
- fragment = (xmlChar *) uri->fragment;
- uri->fragment = NULL;
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- ctxt->nbErrors++;
- if (fragment != NULL)
- xmlFree(fragment);
- xmlFree(URI);
- return(-1);
- }
- xmlFree(URI);
- if (fragment != NULL)
- xmlFree(fragment);
-
- for (i = 0; i < nr; i++) {
- if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) {
-#ifdef DEBUG_XINCLUDE
- printf("Incrementing count for %d : %s\n", i, ctxt->incTab[i]->URI);
-#endif
- ctxt->incTab[i]->count++;
- break;
- }
- }
- xmlFree(URL);
- return(0);
-}
-#endif
-
/**
* xmlXIncludeLoadNode:
* @ctxt: an XInclude context
if (href == NULL) {
href = xmlGetProp(cur, XINCLUDE_HREF);
if (href == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
ctxt->nbErrors++;
return(-1);
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
xml = 0;
else {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: invalid value %s for %s\n",
parse, XINCLUDE_PARSE);
xmlFree(eschref);
}
if (URI == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
ctxt->nbErrors++;
if (parse != NULL)
}
}
if (ret < 0) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: could not load %s, and no fallback was found\n",
URI);
tmp = tmp->next;
}
if (nb_elem > 1) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude error: would result in multiple root nodes\n");
ctxt->nbErrors++;
cur->type = XML_XINCLUDE_START;
end = xmlNewNode(cur->ns, cur->name);
if (end == NULL) {
+ xmlXIncludeErrorContext(ctxt, ctxt->incTab[nr]->ref);
xmlGenericError(xmlGenericErrorContext,
"XInclude: failed to build node\n");
ctxt->nbErrors++;
xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
if (node == NULL)
return(0);
+ if (node->type != XML_ELEMENT_NODE)
+ return(0);
if (node->ns == NULL)
return(0);
if (xmlStrEqual(node->ns->href, XINCLUDE_NS)) {
(child->ns != NULL) &&
(xmlStrEqual(child->ns->href, XINCLUDE_NS))) {
if (xmlStrEqual(child->name, XINCLUDE_NODE)) {
+ xmlXIncludeErrorContext(ctxt, node);
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s has an %s child\n",
XINCLUDE_NODE, XINCLUDE_NODE);
child = child->next;
}
if (nb_fallback > 1) {
+ xmlXIncludeErrorContext(ctxt, node);
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s has %d %s children\n",
XINCLUDE_NODE, nb_fallback, XINCLUDE_FALLBACK);
(node->parent->ns == NULL) ||
(!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) ||
(!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {
+ xmlXIncludeErrorContext(ctxt, node);
xmlGenericError(xmlGenericErrorContext,
"XInclude: %s is not the child of an %s\n",
XINCLUDE_FALLBACK, XINCLUDE_NODE);
* xmlXIncludeDoProcess:
* @ctxt: the XInclude processing context
* @doc: an XML document
+ * @tree: the top of the tree to process
*
* Implement the XInclude substitution on the XML document @doc
*
* or the number of substitutions done.
*/
static int
-xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
+xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
xmlNodePtr cur;
int ret = 0;
int i;
- if (doc == NULL)
+ if ((doc == NULL) || (tree == NULL))
return(-1);
if (ctxt == NULL)
return(-1);
/*
* First phase: lookup the elements in the document
*/
- cur = xmlDocGetRootElement(doc);
+ cur = tree;
if (xmlXIncludeTestNode(ctxt, cur) == 1)
xmlXIncludePreProcessNode(ctxt, cur);
while (cur != NULL) {
/* TODO: need to work on entities -> stack */
if ((cur->children != NULL) &&
- (cur->children->type != XML_ENTITY_DECL)) {
+ (cur->children->type != XML_ENTITY_DECL) &&
+ (cur->children->type != XML_XINCLUDE_START) &&
+ (cur->children->type != XML_XINCLUDE_END)) {
cur = cur->children;
if (xmlXIncludeTestNode(ctxt, cur))
xmlXIncludePreProcessNode(ctxt, cur);
int
xmlXIncludeProcess(xmlDocPtr doc) {
xmlXIncludeCtxtPtr ctxt;
+ xmlNodePtr tree;
int ret = 0;
if (doc == NULL)
return(-1);
+ tree = xmlDocGetRootElement(doc);
+ if (tree == NULL)
+ return(-1);
ctxt = xmlXIncludeNewContext(doc);
if (ctxt == NULL)
return(-1);
- ret = xmlXIncludeDoProcess(ctxt, doc);
+ ret = xmlXIncludeDoProcess(ctxt, doc, tree);
+ if ((ret >= 0) && (ctxt->nbErrors > 0))
+ ret = -1;
+
+ xmlXIncludeFreeContext(ctxt);
+ return(ret);
+}
+
+/**
+ * xmlXIncludeProcessTree:
+ * @tree: a node in an XML document
+ *
+ * Implement the XInclude substitution for the given subtree
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ * or the number of substitutions done.
+ */
+int
+xmlXIncludeProcessTree(xmlNodePtr tree) {
+ xmlXIncludeCtxtPtr ctxt;
+ int ret = 0;
+
+ if ((tree == NULL) || (tree->doc == NULL))
+ return(-1);
+ ctxt = xmlXIncludeNewContext(tree->doc);
+ if (ctxt == NULL)
+ return(-1);
+ ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
if ((ret >= 0) && (ctxt->nbErrors > 0))
ret = -1;