#ifdef WITH_XSLT_DEBUG_PROCESS
if (cur->type == XML_PI_NODE)
xsltGenericDebug(xsltGenericDebugContext,
- "xsltProcessOneNode: template found for PI %s\n",
+ "xsltDefaultProcessOneNode: template found for PI %s\n",
cur->name);
else if (cur->type == XML_COMMENT_NODE)
xsltGenericDebug(xsltGenericDebugContext,
- "xsltProcessOneNode: template found for comment\n");
+ "xsltDefaultProcessOneNode: template found for comment\n");
#endif
oldNode = ctxt->node;
ctxt->node = cur;
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
- "xsltDefaultProcessOneNode: removing ignorable blank node\n");
+ "xsltProcessOneNode: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
URL = xmlBuildURI(filename, base);
if (URL == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xsltDocumentComp: URL computation failed %s\n", filename);
+ "xsltDocumentElem: URL computation failed %s\n", filename);
} else {
xmlFree(filename);
filename = URL;
* @inst: the xslt sort node
* @comp: precomputed informations
*
- * function attached to xslt:sort nodes, but this should not be
+ * function attached to xsl:sort nodes, but this should not be
* called directly
*/
void
xsltStylePreCompPtr comp) {
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:sort : compilation had failed\n");
+ "xsl:sort : compilation failed\n");
return;
}
xsltGenericError(xsltGenericErrorContext,
- "xslt:sort : improper use this should not be reached\n");
+ "xsl:sort : improper use this should not be reached\n");
}
/**
(text->type != XML_CDATA_SECTION_NODE)) ||
(text->next != NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:text content problem\n");
+ "xsl:text content problem\n");
break;
}
copy = xmlNewDocText(ctxt->output, text->content);
(const xmlChar *)"name", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:element : name is missing\n");
+ "xsl:element : name is missing\n");
goto error;
}
name = prop;
if (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)) {
#ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext,
- "xslt:element : xml prefix forbidden\n");
+ "xsl:element : xml prefix forbidden\n");
#endif
goto error;
}
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "no namespace bound to prefix %s\n", prefix);
+ "xsl:element : no namespace bound to prefix %s\n", prefix);
} else {
ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert);
}
return;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:attribute : compilation had failed\n");
+ "xsl:attribute : compilation failed\n");
return;
}
}
if (ctxt->insert->children != NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:attribute : node has already children\n");
+ "xsl:attribute : node has already children\n");
return;
}
if (comp->name == NULL) {
XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:element : name is missing\n");
+ "xsl:attribute : name is missing\n");
goto error;
}
name = prop;
if (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)) {
#ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext,
- "xslt:attribute : xml prefix forbidden\n");
+ "xsl:attribute : xml prefix forbidden\n");
#endif
goto error;
}
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "no namespace bound to prefix %s\n", prefix);
+ "xsl:attribute : no namespace bound to prefix %s\n", prefix);
} else {
ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert);
}
(const xmlChar *)"name", XSLT_NAMESPACE);
if (ncname == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:processing-instruction : name is missing\n");
+ "xsl:processing-instruction : name is missing\n");
goto error;
}
name = ncname;
return;
if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xsl:copy-of : compilation have failed\n");
+ "xsl:copy-of : compilation failed\n");
return;
}
if (res->type == XPATH_NODESET) {
#ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
- "xslcopyOf: result is a node set\n");
+ "xsltCopyOf: result is a node set\n");
#endif
list = res->nodesetval;
if (list != NULL) {
} else if (res->type == XPATH_XSLT_TREE) {
#ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
- "xslcopyOf: result is a result tree fragment\n");
+ "xsltCopyOf: result is a result tree fragment\n");
#endif
list = res->nodesetval;
if ((list != NULL) && (list->nodeTab != NULL) &&
#ifdef WITH_XSLT_DEBUG_PROCESS
else
xsltGenericDebug(xsltGenericDebugContext,
- "xslcopyOf: result %s\n", res->stringval);
+ "xsltCopyOf: result %s\n", res->stringval);
#endif
}
}
return;
if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xsl:value-of : compilation have failed\n");
+ "xsl:value-of : compilation failed\n");
return;
}
}
if (copy == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xsltDefaultProcessOneNode: text copy failed\n");
+ "xsltValueOf: text copy failed\n");
}
#ifdef WITH_XSLT_DEBUG_PROCESS
else
{
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:number : compilation had failed\n");
+ "xsl:number : compilation failed\n");
return;
}
if ((ctxt->templ == NULL) || (ctxt->templ->style == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:apply-imports : internal error no current template\n");
+ "xsl:apply-imports : internal error no current template\n");
return;
}
template = xsltGetTemplate(ctxt, node, ctxt->templ->style);
return;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:call-template : compilation had failed\n");
+ "xsl:call-template : compilation failed\n");
return;
}
comp->templ = xsltFindTemplate(ctxt, comp->name, comp->ns);
if (comp->templ == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:call-template : template %s not found\n", comp->name);
+ "xsl:call-template : template %s not found\n", comp->name);
return;
}
}
}
} else {
xsltGenericError(xsltGenericDebugContext,
- "xslt:call-template: misplaced xslt:%s\n", cur->name);
+ "xsl:call-template: misplaced xsl:%s\n", cur->name);
}
} else {
xsltGenericError(xsltGenericDebugContext,
- "xslt:call-template: misplaced %s element\n", cur->name);
+ "xsl:call-template: misplaced %s element\n", cur->name);
}
cur = cur->next;
}
void
xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
- xmlNodePtr cur, delete = NULL, oldnode;
+ xmlNodePtr cur, delete = NULL, oldNode;
xmlXPathObjectPtr res = NULL;
- xmlNodeSetPtr list = NULL, oldlist;
+ xmlNodeSetPtr list = NULL, oldList;
int i, oldProximityPosition, oldContextSize;
- const xmlChar *oldmode, *oldmodeURI;
+ const xmlChar *oldMode, *oldModeURI;
xsltStackElemPtr params = NULL, param, tmp, p;
int nbsorts = 0;
+ int newdoc = 0;
xmlNodePtr sorts[XSLT_MAX_SORT];
-
+ xmlDocPtr oldXDocPtr, newXDocPtr;
+ xsltDocumentPtr oldCDocPtr, newCDocPtr;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:apply-templates : compilation had failed\n");
+ "xsl:apply-templates : compilation failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
/*
* Get mode if any
*/
- oldnode = ctxt->node;
- oldmode = ctxt->mode;
- oldmodeURI = ctxt->modeURI;
+ oldNode = ctxt->node;
+ oldMode = ctxt->mode;
+ oldModeURI = ctxt->modeURI;
ctxt->mode = comp->mode;
ctxt->modeURI = comp->modeURI;
+ /*
+ * The xpath context size and proximity position, as
+ * well as the xpath and context documents, may be changed
+ * so we save their initial state and will restore on exit
+ */
+ newXDocPtr = oldXDocPtr = ctxt->xpathCtxt->doc;
+ newCDocPtr = oldCDocPtr = ctxt->document;
+ oldContextSize = ctxt->xpathCtxt->contextSize;
+ oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
+
if (comp->select != NULL) {
if (comp->comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:apply-templates : compilation had failed\n");
+ "xsl:apply-templates : compilation failed\n");
goto error;
}
#ifdef WITH_XSLT_DEBUG_PROCESS
"xsltApplyTemplates: select %s\n", comp->select);
#endif
- oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
- oldContextSize = ctxt->xpathCtxt->contextSize;
ctxt->xpathCtxt->node = node;
ctxt->xpathCtxt->namespaces = comp->nsList;
ctxt->xpathCtxt->nsNr = comp->nsNr;
if (res != NULL) {
if (res->type == XPATH_NODESET) {
list = res->nodesetval;
+ /* For a 'select' nodeset, need to check if document has changed */
+ if ( (res->nodesetval!=NULL) &&
+ (res->nodesetval->nodeTab!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc->doc!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc->doc)!=ctxt->xpathCtxt->doc) {
+ newXDocPtr=res->nodesetval->nodeTab[0]->doc->doc;
+ /* The nodeset is from another document, so must change */
+ if ((newCDocPtr = xsltFindDocument(ctxt,newXDocPtr))==NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:apply-templates : can't find doc\n");
+ goto error;
+ }
+ /* Can't actually do the change yet, so set flag for later */
+ newdoc = 1;
+ }
res->nodesetval = NULL;
} else {
list = NULL;
"xsltApplyTemplates: list of %d nodes\n", list->nodeNr);
#endif
- oldlist = ctxt->nodeList;
+ oldList = ctxt->nodeList;
ctxt->nodeList = list;
- oldContextSize = ctxt->xpathCtxt->contextSize;
- oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
ctxt->xpathCtxt->contextSize = list->nodeNr;
/*
} else if (IS_XSLT_NAME(cur, "sort")) {
if (nbsorts >= XSLT_MAX_SORT) {
xsltGenericError(xsltGenericDebugContext,
- "xslt:call-template: %s too many sort\n", node->name);
+ "xsl:call-template: %s too many sort\n", node->name);
} else {
sorts[nbsorts++] = cur;
}
} else {
xsltGenericError(xsltGenericDebugContext,
- "xslt:call-template: misplaced xslt:%s\n", cur->name);
+ "xsl:call-template: misplaced xsl:%s\n", cur->name);
}
} else {
xsltGenericError(xsltGenericDebugContext,
- "xslt:call-template: misplaced %s element\n", cur->name);
+ "xsl:call-template: misplaced %s element\n", cur->name);
}
cur = cur->next;
}
xsltDoSortFunction(ctxt, sorts, nbsorts);
}
+
+ /* The original 'select' may have required a change of document*/
+ if (newdoc) {
+#ifdef WITH_XSLT_DEBUG_PROCESS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltApplyTemplates: Changing document - context doc %s, xpathdoc %s\n",
+ newCDocPtr->doc->URL, newXDocPtr->URL);
+#endif
+
+ ctxt->document = newCDocPtr;
+ ctxt->xpathCtxt->doc = newXDocPtr;
+ ctxt->xpathCtxt->node = list->nodeTab[0];
+ }
+
for (i = 0;i < list->nodeNr;i++) {
ctxt->node = list->nodeTab[i];
ctxt->xpathCtxt->proximityPosition = i + 1;
}
}
xsltFreeStackElemList(params); /* free the parameter list */
- ctxt->nodeList = oldlist;
+ ctxt->nodeList = oldList;
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
+ ctxt->xpathCtxt->doc = oldXDocPtr;
+ ctxt->document = oldCDocPtr;
error:
- ctxt->node = oldnode;
- ctxt->mode = oldmode;
- ctxt->modeURI = oldmodeURI;
+ ctxt->node = oldNode;
+ ctxt->mode = oldMode;
+ ctxt->modeURI = oldModeURI;
if (res != NULL)
xmlXPathFreeObject(res);
if (list != NULL)
replacement = inst->children;
if (replacement == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:choose: empty content not allowed\n");
+ "xsl:choose: empty content not allowed\n");
goto error;
}
if ((!IS_XSLT_ELEM(replacement)) ||
(!IS_XSLT_NAME(replacement, "when"))) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:choose: xsl:when expected first\n");
+ "xsl:choose: xsl:when expected first\n");
goto error;
}
while (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "when"))) {
replacement = replacement->next;
}
if (replacement != NULL) {
-#ifdef WITH_XSLT_DEBUG_PROCESS
- xsltGenericDebug(xsltGenericDebugContext,
- "xsl:otherwise: applying default fallback\n");
-#endif
xsltGenericError(xsltGenericErrorContext,
- "xslt:choose: unexpected content %s\n", replacement->name);
+ "xsl:choose: unexpected content %s\n", replacement->name);
goto error;
}
return;
if ((comp == NULL) || (comp->test == NULL) || (comp->comp == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xsl:if : compilation have failed\n");
+ "xsl:if : compilation failed\n");
return;
}
xmlNodePtr inst, xsltStylePreCompPtr comp) {
xmlXPathObjectPtr res = NULL;
xmlNodePtr replacement;
- xmlNodeSetPtr list = NULL, oldlist;
+ xmlNodeSetPtr list = NULL, oldList;
int i, oldProximityPosition, oldContextSize;
xmlNodePtr oldNode = ctxt->node;
int nbsorts = 0;
xmlNodePtr sorts[XSLT_MAX_SORT];
+ xmlDocPtr oldXDocPtr, newXDocPtr;
+ xsltDocumentPtr oldCDocPtr, newCDocPtr;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
return;
if ((comp == NULL) || (comp->select == NULL) || (comp->comp == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "xslt:for-each : compilation had failed\n");
+ "xsl:for-each : compilation failed\n");
return;
}
ctxt->xpathCtxt->node = node;
ctxt->xpathCtxt->namespaces = comp->nsList;
ctxt->xpathCtxt->nsNr = comp->nsNr;
+ oldCDocPtr = ctxt->document;
+ oldXDocPtr = ctxt->xpathCtxt->doc;
res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
#ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
- "xsltForEach: select evaluate to %d nodes\n", list->nodeNr);
+ "xsltForEach: select evaluates to %d nodes\n", list->nodeNr);
#endif
- oldlist = ctxt->nodeList;
+ oldList = ctxt->nodeList;
ctxt->nodeList = list;
oldContextSize = ctxt->xpathCtxt->contextSize;
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
ctxt->xpathCtxt->contextSize = list->nodeNr;
+ /* For a 'select' nodeset, need to check if document has changed */
+ if (list->nodeTab!=NULL) {
+ if ( (res->nodesetval!=NULL) &&
+ (res->nodesetval->nodeTab!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc->doc!=NULL) &&
+ (res->nodesetval->nodeTab[0]->doc->doc)!=ctxt->xpathCtxt->doc) {
+ newXDocPtr=res->nodesetval->nodeTab[0]->doc->doc;
+ /* The nodeset is from another document, so must change */
+ if ((newCDocPtr = xsltFindDocument(ctxt,newXDocPtr))==NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:for-each : can't find document\n");
+ goto error;
+ }
+ ctxt->document = newCDocPtr;
+ ctxt->xpathCtxt->doc = newXDocPtr;
+ ctxt->xpathCtxt->node = list->nodeTab[0];
+ ctxt->xpathCtxt->contextSize = list->nodeNr;
+ ctxt->xpathCtxt->proximityPosition = 0;
+ }
+ }
+
/*
* handle and skip the xsl:sort
*/
while (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "sort"))) {
if (nbsorts >= XSLT_MAX_SORT) {
xsltGenericError(xsltGenericDebugContext,
- "xslt:for-each: too many sort\n");
+ "xsl:for-each: too many sort\n");
} else {
sorts[nbsorts++] = replacement;
}
xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement, 0);
xsltFreeStackElemList(varsPop(ctxt));
}
- ctxt->nodeList = oldlist;
+ ctxt->document = oldCDocPtr;
+ ctxt->nodeList = oldList;
ctxt->node = oldNode;
+ ctxt->xpathCtxt->doc = oldXDocPtr;
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
goto error;
} else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
xsltGenericError(xsltGenericErrorContext,
- "xsltApplyStylesheet: insupported method xhtml, using html\n",
+ "xsltApplyStylesheet: unsupported method xhtml, using html\n",
style->method);
ctxt->type = XSLT_OUTPUT_HTML;
res = htmlNewDoc(doctypeSystem, doctypePublic);
goto error;
} else {
xsltGenericError(xsltGenericErrorContext,
- "xsltApplyStylesheet: insupported method %s\n",
+ "xsltApplyStylesheet: unsupported method %s\n",
style->method);
goto error;
}