From ea9ed33cc885dfde09b82e0cf1e80dba96ebf11b Mon Sep 17 00:00:00 2001 From: "Kasimier T. Buchcik" Date: Thu, 30 Mar 2006 15:21:42 +0000 Subject: [PATCH] Eliminated usage of xsltGetNsProp() in cases where an attribute with a * libxslt/xslt.c libxslt/xsltutils.c libxslt/preproc.c libxslt/namespaces.c libxslt/imports.c libxslt/attributes.c: Eliminated usage of xsltGetNsProp() in cases where an attribute with a specific namespace is requested. xsltGetNsProp() uses xmlGetProp() which is not namespace aware and thus will return the first attribute with the requested name but of arbitrary namespace. Changed retrieval of the attributes "exclude-result-prefixes" and "extension-element-prefixes", which are expected to be in no namespace on XSLT elements and in the XSLT namespace on literal result elements or extension elements. Additional change: for XSLT elements the attribute "exclude-result-prefixes" is only allowed on xsl:stylesheet and xsl:transform. This attribute was previously processed on all XSLT elements. --- ChangeLog | 18 +++++ libxslt/attributes.c | 6 +- libxslt/imports.c | 4 +- libxslt/namespaces.c | 6 +- libxslt/preproc.c | 120 ++++++++++++++++++++------- libxslt/xslt.c | 187 +++++++++++++++++++++++++------------------ libxslt/xsltutils.c | 11 ++- 7 files changed, 239 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37386e75..e0fcb7aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Thu Mar 30 17:11:53 CEST 2006 Kasimier Buchcik + + * libxslt/xslt.c libxslt/xsltutils.c libxslt/preproc.c + libxslt/namespaces.c libxslt/imports.c + libxslt/attributes.c: Eliminated usage of xsltGetNsProp() in cases + where an attribute with a specific namespace is requested. + xsltGetNsProp() uses xmlGetProp() which is not namespace aware + and thus will return the first attribute with the requested + name but of arbitrary namespace. + Changed retrieval of the attributes "exclude-result-prefixes" + and "extension-element-prefixes", which are expected to be in + no namespace on XSLT elements and in the XSLT namespace on + literal result elements or extension elements. + Additional change: for XSLT elements the attribute + "exclude-result-prefixes" is only allowed on xsl:stylesheet + and xsl:transform. This attribute was previously processed on + all XSLT elements. + Wed Mar 29 12:16:41 CEST 2006 Daniel Veillard * libxslt/transform.c: Charles Hardin pointed an OOM condition where diff --git a/libxslt/attributes.c b/libxslt/attributes.c index 1265831e..c6869eca 100644 --- a/libxslt/attributes.c +++ b/libxslt/attributes.c @@ -282,7 +282,7 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return; - prop = xsltGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"name", NULL); if (prop == NULL) { xsltGenericError(xsltGenericErrorContext, "xsl:attribute-set : name is missing\n"); @@ -333,8 +333,8 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { */ /* TODO check recursion */ - attributes = xsltGetNsProp(cur, (const xmlChar *)"use-attribute-sets", - XSLT_NAMESPACE); + attributes = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets", + NULL); if (attributes == NULL) { goto done; } diff --git a/libxslt/imports.c b/libxslt/imports.c index a2832f05..1a2b12d3 100644 --- a/libxslt/imports.c +++ b/libxslt/imports.c @@ -95,7 +95,7 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return (ret); - uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); + uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL); if (uriRef == NULL) { xsltTransformError(NULL, style, cur, "xsl:import : missing href attribute\n"); @@ -194,7 +194,7 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return (ret); - uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); + uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL); if (uriRef == NULL) { xsltTransformError(NULL, style, cur, "xsl:include : missing href attribute\n"); diff --git a/libxslt/namespaces.c b/libxslt/namespaces.c index 0589d045..063741b1 100644 --- a/libxslt/namespaces.c +++ b/libxslt/namespaces.c @@ -69,15 +69,13 @@ xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) { xmlNsPtr rNs; const xmlChar *rhref; - sprefix = xsltGetNsProp(node, (const xmlChar *)"stylesheet-prefix", - XSLT_NAMESPACE); + sprefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL); if (sprefix == NULL) { xsltTransformError(NULL, style, node, "namespace-alias: stylesheet-prefix attribute missing\n"); return; } - rprefix = xsltGetNsProp(node, (const xmlChar *)"result-prefix", - XSLT_NAMESPACE); + rprefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); if (rprefix == NULL) { xsltTransformError(NULL, style, node, "namespace-alias: result-prefix attribute missing\n"); diff --git a/libxslt/preproc.c b/libxslt/preproc.c index 7a5092b5..936146cb 100644 --- a/libxslt/preproc.c +++ b/libxslt/preproc.c @@ -329,6 +329,17 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst, xsltStylePreCompPtr comp; const xmlChar *filename = NULL; + /* + * As of 2006-03-30, this function is currently defined in Libxslt + * to be used for: + * (in libxslt/extra.c) + * "output" in XSLT_SAXON_NAMESPACE + * "write" XSLT_XALAN_NAMESPACE + * "document" XSLT_XT_NAMESPACE + * "document" XSLT_NAMESPACE + * (in libexslt/common.c) + * "document" in EXSLT_COMMON_NAMESPACE + */ comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT); if (comp == NULL) return (NULL); @@ -340,36 +351,68 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst, xsltGenericDebug(xsltGenericDebugContext, "Found saxon:output extension\n"); #endif + /* + * The element "output" is in the namespace XSLT_SAXON_NAMESPACE + * (http://icl.com/saxon) + * The @file is in no namespace. + */ filename = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"file", - XSLT_SAXON_NAMESPACE, &comp->has_filename); + NULL, &comp->has_filename); } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) { #ifdef WITH_XSLT_DEBUG_EXTRA xsltGenericDebug(xsltGenericDebugContext, "Found xalan:write extension\n"); #endif - comp->ver11 = 0; /* the filename need to be interpreted */ + /* the filename need to be interpreted */ + /* + * TODO: Is "filename need to be interpreted" meant to be a todo? + * Where will be the filename of xalan:write be processed? + */ } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) { - filename = xsltEvalStaticAttrValueTemplate(style, inst, - (const xmlChar *)"href", - XSLT_XT_NAMESPACE, &comp->has_filename); - if (comp->has_filename == 0) { + if (inst->ns != NULL) { + if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) { + /* Mark the instruction as being of XSLT version 1.1. */ + comp->ver11 = 1; #ifdef WITH_XSLT_DEBUG_EXTRA - xsltGenericDebug(xsltGenericDebugContext, - "Found xslt11:document construct\n"); -#endif - filename = xsltEvalStaticAttrValueTemplate(style, inst, - (const xmlChar *)"href", - XSLT_NAMESPACE, &comp->has_filename); - comp->ver11 = 1; - } else { + xsltGenericDebug(xsltGenericDebugContext, + "Found xslt11:document construct\n"); +#endif + } else { + if (xmlStrEqual(inst->ns->href, + (const xmlChar *)"http://exslt.org/common")) { + /* EXSLT. */ #ifdef WITH_XSLT_DEBUG_EXTRA - xsltGenericDebug(xsltGenericDebugContext, - "Found xt:document extension\n"); + xsltGenericDebug(xsltGenericDebugContext, + "Found exslt:document extension\n"); #endif - comp->ver11 = 0; + } else if (xmlStrEqual(inst->ns->href, XSLT_XT_NAMESPACE)) { + /* James Clark's XT. */ +#ifdef WITH_XSLT_DEBUG_EXTRA + xsltGenericDebug(xsltGenericDebugContext, + "Found xt:document extension\n"); +#endif + } + } } - } + /* + * The element "document" is used in conjunction with the + * following namespaces: + * 1) XSLT_NAMESPACE (http://www.w3.org/1999/XSL/Transform version 1.1) + * + * + * + * In all cases @href is in no namespace. + */ + filename = xsltEvalStaticAttrValueTemplate(style, inst, + (const xmlChar *)"href", NULL, &comp->has_filename); + } if (!comp->has_filename) { goto error; } @@ -398,6 +441,14 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { if ((style == NULL) || (inst == NULL)) return; + /* + * + */ comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT); if (comp == NULL) return; @@ -406,7 +457,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { comp->stype = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"data-type", - XSLT_NAMESPACE, &comp->has_stype); + NULL, &comp->has_stype); if (comp->stype != NULL) { if (xmlStrEqual(comp->stype, (const xmlChar *) "text")) comp->number = 0; @@ -421,7 +472,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { } comp->order = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"order", - XSLT_NAMESPACE, &comp->has_order); + NULL, &comp->has_order); if (comp->order != NULL) { if (xmlStrEqual(comp->order, (const xmlChar *) "ascending")) comp->descending = 0; @@ -436,7 +487,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { } comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"case-order", - XSLT_NAMESPACE, &comp->has_use); + NULL, &comp->has_use); if (comp->case_order != NULL) { if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first")) comp->lower_first = 0; @@ -452,7 +503,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"lang", - XSLT_NAMESPACE, &comp->has_lang); + NULL, &comp->has_lang); comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); if (comp->select == NULL) { @@ -553,6 +604,14 @@ static void xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; + /* + * + * + * + */ if ((style == NULL) || (inst == NULL)) return; comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT); @@ -563,7 +622,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) { comp->name = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"name", - XSLT_NAMESPACE, &comp->has_name); + NULL, &comp->has_name); if (comp->name != NULL) { if (xmlValidateQName(comp->name, 0)) { xsltTransformError(NULL, style, inst, @@ -573,7 +632,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) { } comp->ns = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"namespace", - XSLT_NAMESPACE, &comp->has_ns); + NULL, &comp->has_ns); if (comp->has_ns == 0) { xmlNsPtr defaultNs; @@ -585,7 +644,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) { } comp->use = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"use-attribute-sets", - XSLT_NAMESPACE, &comp->has_use); + NULL, &comp->has_use); } /** @@ -599,6 +658,13 @@ static void xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; + /* + * + * + * + */ if ((style == NULL) || (inst == NULL)) return; comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE); @@ -612,7 +678,7 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) { */ comp->name = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"name", - XSLT_NAMESPACE, &comp->has_name); + NULL, &comp->has_name); if (comp->name != NULL) { if (xmlValidateQName(comp->name, 0)) { xsltTransformError(NULL, style, inst, @@ -622,7 +688,7 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) { } comp->ns = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"namespace", - XSLT_NAMESPACE, &comp->has_ns); + NULL, &comp->has_ns); } diff --git a/libxslt/xslt.c b/libxslt/xslt.c index 6dada2e3..dab816b5 100644 --- a/libxslt/xslt.c +++ b/libxslt/xslt.c @@ -581,6 +581,16 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, int maxns = 10; int i; + /* + * TODO: This will gather the ns-decls of elements even if + * outside xsl:stylesheet. Example: + * + * + * Will have foo="urn:test:foo" in the list. + * Is this a bug? + */ + if ((style == NULL) || (template == NULL) || (node == NULL) || (template->inheritedNsNr != 0) || (template->inheritedNs != NULL)) return(0); @@ -593,6 +603,11 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, if ((cur->prefix != NULL) && (xsltCheckExtPrefix(style, cur->prefix))) goto skip_ns; + /* + * Check if this namespace was excluded. + * Note that at this point only the exclusions defined + * on the topmost stylesheet element are in the exclusion-list. + */ for (i = 0;i < style->exclPrefixNr;i++) { if (xmlStrEqual(cur->href, style->exclPrefixTab[i])) goto skip_ns; @@ -608,6 +623,9 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, } ret[nbns] = NULL; } + /* + * Skip shadowed namespace bindings. + */ for (i = 0; i < nbns; i++) { if ((cur->prefix == ret[i]->prefix) || (xmlStrEqual(cur->prefix, ret[i]->prefix))) @@ -665,24 +683,25 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) if ((cur == NULL) || (style == NULL)) return; - - prop = xsltGetNsProp(cur, (const xmlChar *) "version", XSLT_NAMESPACE); + + prop = xmlGetNsProp(cur, (const xmlChar *) "version", NULL); if (prop != NULL) { if (style->version != NULL) xmlFree(style->version); style->version = prop; } - prop = - xsltGetNsProp(cur, (const xmlChar *) "encoding", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "encoding", NULL); if (prop != NULL) { if (style->encoding != NULL) xmlFree(style->encoding); style->encoding = prop; } - /* relaxed to support xt:document */ - prop = xmlGetProp(cur, (const xmlChar *) "method"); + /* relaxed to support xt:document + * TODO KB: What does "relaxed to support xt:document" mean? + */ + prop = xmlGetNsProp(cur, (const xmlChar *) "method", NULL); if (prop != NULL) { const xmlChar *URI; @@ -712,26 +731,21 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) } } - prop = - xsltGetNsProp(cur, (const xmlChar *) "doctype-system", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-system", NULL); if (prop != NULL) { if (style->doctypeSystem != NULL) xmlFree(style->doctypeSystem); style->doctypeSystem = prop; } - prop = - xsltGetNsProp(cur, (const xmlChar *) "doctype-public", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-public", NULL); if (prop != NULL) { if (style->doctypePublic != NULL) xmlFree(style->doctypePublic); style->doctypePublic = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *) "standalone", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "standalone", NULL); if (prop != NULL) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) { style->standalone = 1; @@ -745,7 +759,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xmlFree(prop); } - prop = xsltGetNsProp(cur, (const xmlChar *) "indent", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "indent", NULL); if (prop != NULL) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) { style->indent = 1; @@ -759,8 +773,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xmlFree(prop); } - prop = xsltGetNsProp(cur, (const xmlChar *) "omit-xml-declaration", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "omit-xml-declaration", NULL); if (prop != NULL) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) { style->omitXmlDeclaration = 1; @@ -775,9 +788,8 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xmlFree(prop); } - elements = - xsltGetNsProp(cur, (const xmlChar *) "cdata-section-elements", - XSLT_NAMESPACE); + elements = xmlGetNsProp(cur, (const xmlChar *) "cdata-section-elements", + NULL); if (elements != NULL) { if (style->cdataSection == NULL) style->cdataSection = xmlHashCreate(10); @@ -829,7 +841,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xmlFree(elements); } - prop = xsltGetNsProp(cur, (const xmlChar *) "media-type", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *) "media-type", NULL); if (prop != NULL) { if (style->mediaType) xmlFree(style->mediaType); @@ -857,7 +869,7 @@ xsltParseStylesheetDecimalFormat(xsltStylesheetPtr style, xmlNodePtr cur) format = style->decimalFormat; - prop = xsltGetNsProp(cur, BAD_CAST("name"), XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, BAD_CAST("name"), NULL); if (prop != NULL) { format = xsltDecimalFormatGetByName(style, prop); if (format != NULL) { @@ -880,64 +892,61 @@ xsltParseStylesheetDecimalFormat(xsltStylesheetPtr style, xmlNodePtr cur) iter->next = format; } - prop = xsltGetNsProp(cur, (const xmlChar *)"decimal-separator", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"decimal-separator", NULL); if (prop != NULL) { if (format->decimalPoint != NULL) xmlFree(format->decimalPoint); format->decimalPoint = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"grouping-separator", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-separator", NULL); if (prop != NULL) { if (format->grouping != NULL) xmlFree(format->grouping); format->grouping = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"infinity", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"infinity", NULL); if (prop != NULL) { if (format->infinity != NULL) xmlFree(format->infinity); format->infinity = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"minus-sign", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"minus-sign", NULL); if (prop != NULL) { if (format->minusSign != NULL) xmlFree(format->minusSign); format->minusSign = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"NaN", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"NaN", NULL); if (prop != NULL) { if (format->noNumber != NULL) xmlFree(format->noNumber); format->noNumber = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"percent", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"percent", NULL); if (prop != NULL) { if (format->percent != NULL) xmlFree(format->percent); format->percent = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"per-mille", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"per-mille", NULL); if (prop != NULL) { if (format->permille != NULL) xmlFree(format->permille); format->permille = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"zero-digit", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"zero-digit", NULL); if (prop != NULL) { if (format->zeroDigit != NULL) xmlFree(format->zeroDigit); format->zeroDigit = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"digit", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"digit", NULL); if (prop != NULL) { if (format->digit != NULL) xmlFree(format->digit); format->digit = prop; } - prop = xsltGetNsProp(cur, (const xmlChar *)"pattern-separator", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"pattern-separator", NULL); if (prop != NULL) { if (format->patternSeparator != NULL) xmlFree(format->patternSeparator); format->patternSeparator = prop; @@ -961,7 +970,7 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return; - elements = xsltGetNsProp(cur, (const xmlChar *)"elements", XSLT_NAMESPACE); + elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL); if (elements == NULL) { xsltTransformError(NULL, style, cur, "xsltParseStylesheetPreserveSpace: missing elements attribute\n"); @@ -1009,20 +1018,34 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) { * @style: the XSLT stylesheet * @template: the "extension-element-prefixes" prefix * - * parse an XSLT stylesheet extension prefix and record - * prefixes needing stripping + * parse an XSLT stylesheet's "extension-element-prefix" attribute value + * and register the namespaces of extension elements. + * SPEC "A namespace is designated as an extension namespace by using + * an extension-element-prefixes attribute on: + * 1) an xsl:stylesheet element + * 2) TODO: an xsl:extension-element-prefixes attribute on a + * literal result element + * 3) TODO: an extension element." */ static void -xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur) { +xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur, + int isXsltElem) { xmlChar *prefixes; xmlChar *prefix, *end; if ((cur == NULL) || (style == NULL)) return; - prefixes = xsltGetNsProp(cur, (const xmlChar *)"extension-element-prefixes", - XSLT_NAMESPACE); + if (isXsltElem) { + /* For xsl:stylesheet/xsl:transform. */ + prefixes = xmlGetNsProp(cur, + (const xmlChar *)"extension-element-prefixes", NULL); + } else { + /* For literal result elements and extension elements. */ + prefixes = xmlGetNsProp(cur, + (const xmlChar *)"extension-element-prefixes", XSLT_NAMESPACE); + } if (prefixes == NULL) { return; } @@ -1066,8 +1089,8 @@ xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur) { * @style: the XSLT stylesheet * @cur: the "strip-space" element * - * parse an XSLT stylesheet strip-space element and record - * elements needing stripping + * parse an XSLT stylesheet's strip-space element and record + * the elements needing stripping */ static void @@ -1078,7 +1101,7 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return; - elements = xsltGetNsProp(cur, (const xmlChar *)"elements", XSLT_NAMESPACE); + elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL); if (elements == NULL) { xsltTransformError(NULL, style, cur, "xsltParseStylesheetStripSpace: missing elements attribute\n"); @@ -1133,7 +1156,9 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { */ static int -xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur) { +xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur, + int isXsltElem) +{ int nb = 0; xmlChar *prefixes; xmlChar *prefix, *end; @@ -1141,8 +1166,13 @@ xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL)) return(0); - prefixes = xsltGetNsProp(cur, (const xmlChar *)"exclude-result-prefixes", - XSLT_NAMESPACE); + if (isXsltElem) + prefixes = xmlGetNsProp(cur, + (const xmlChar *)"exclude-result-prefixes", NULL); + else + prefixes = xmlGetNsProp(cur, + (const xmlChar *)"exclude-result-prefixes", XSLT_NAMESPACE); + if (prefixes == NULL) { return(0); } @@ -1256,15 +1286,26 @@ xsltPrecomputeStylesheet(xsltStylesheetPtr style, xmlNodePtr cur) { } } - exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur); + /* + * SPEC "A namespace URI is designated as an excluded namespace + * by using an exclude-result-prefixes attribute on an + * xsl:stylesheet element or an xsl:exclude-result-prefixes + * attribute on a literal result element." + * TODO: The evaluation of "exclude-result-prefixes" is still not + * correrct here, since we apply this to extension elements as + * well. So either we need to be extension-element-aware here + * or move this to an other layer. + */ if (IS_XSLT_ELEM(cur)) { + exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur, 1); xsltStylePreCompute(style, cur); if (IS_XSLT_NAME(cur, "text")) { for (;exclPrefixes > 0;exclPrefixes--) exclPrefixPop(style); goto skip_children; } - } + } else + exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur, 0); /* * Remove excluded prefixes @@ -1504,9 +1545,9 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) { xmlNodePtr text = cur->children, next; int noesc = 0; - prop = xsltGetNsProp(cur, - (const xmlChar *)"disable-output-escaping", - XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, + (const xmlChar *)"disable-output-escaping", + NULL); if (prop != NULL) { #ifdef WITH_XSLT_DEBUG_PARSING xsltGenericDebug(xsltGenericDebugContext, @@ -1690,7 +1731,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) { /* * Get arguments */ - prop = xsltGetNsProp(key, (const xmlChar *)"name", XSLT_NAMESPACE); + prop = xmlGetNsProp(key, (const xmlChar *)"name", NULL); if (prop != NULL) { const xmlChar *URI; @@ -1714,7 +1755,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) { goto error; } - match = xsltGetNsProp(key, (const xmlChar *)"match", XSLT_NAMESPACE); + match = xmlGetNsProp(key, (const xmlChar *)"match", NULL); if (match == NULL) { xsltTransformError(NULL, style, key, "xsl:key : error missing match\n"); @@ -1722,7 +1763,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) { goto error; } - use = xsltGetNsProp(key, (const xmlChar *)"use", XSLT_NAMESPACE); + use = xmlGetNsProp(key, (const xmlChar *)"use", NULL); if (use == NULL) { xsltTransformError(NULL, style, key, "xsl:key : error missing use\n"); @@ -1762,7 +1803,6 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { xmlChar *mode = NULL; xmlChar *modeURI = NULL; double priority; - int exclPrefixes; if (template == NULL) return; @@ -1776,12 +1816,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { ret->next = style->templates; style->templates = ret; ret->style = style; - - /* - * Check excluded prefixes - */ - exclPrefixes = xsltParseStylesheetExcludePrefix(style, template); - + /* * Get inherited namespaces */ @@ -1790,7 +1825,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { /* * Get arguments */ - prop = xsltGetNsProp(template, (const xmlChar *)"mode", XSLT_NAMESPACE); + prop = xmlGetNsProp(template, (const xmlChar *)"mode", NULL); if (prop != NULL) { const xmlChar *URI; @@ -1812,20 +1847,20 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { if (mode != NULL) xmlFree(mode); if (modeURI != NULL) xmlFree(modeURI); } - prop = xsltGetNsProp(template, (const xmlChar *)"match", XSLT_NAMESPACE); + prop = xmlGetNsProp(template, (const xmlChar *)"match", NULL); if (prop != NULL) { if (ret->match != NULL) xmlFree(ret->match); ret->match = prop; } - prop = xsltGetNsProp(template, (const xmlChar *)"priority", XSLT_NAMESPACE); + prop = xmlGetNsProp(template, (const xmlChar *)"priority", NULL); if (prop != NULL) { priority = xmlXPathStringEvalNumber(prop); ret->priority = (float) priority; xmlFree(prop); } - prop = xsltGetNsProp(template, (const xmlChar *)"name", XSLT_NAMESPACE); + prop = xmlGetNsProp(template, (const xmlChar *)"name", NULL); if (prop != NULL) { const xmlChar *URI; xsltTemplatePtr cur; @@ -1880,14 +1915,13 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { xsltAddTemplate(style, ret, ret->mode, ret->modeURI); error: - for (;exclPrefixes > 0;exclPrefixes--) - exclPrefixPop(style); + return; } /** * xsltParseStylesheetTop: * @style: the XSLT stylesheet - * @top: the top level "stylesheet" element + * @top: the top level "stylesheet" or "transform" element * * scan the top level elements of an XSL stylesheet */ @@ -1903,7 +1937,7 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) { if (top == NULL) return; - prop = xsltGetNsProp(top, (const xmlChar *)"version", XSLT_NAMESPACE); + prop = xmlGetNsProp(top, (const xmlChar *)"version", NULL); if (prop == NULL) { xsltTransformError(NULL, style, top, "xsl:version is missing: document may not be a stylesheet\n"); @@ -2062,19 +2096,20 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) { xsltTransformError(NULL, ret, (xmlNodePtr) doc, "xsltParseStylesheetProcess : empty stylesheet\n"); return(NULL); - } - xsltParseStylesheetExcludePrefix(ret, cur); + } if ((IS_XSLT_ELEM(cur)) && ((IS_XSLT_NAME(cur, "stylesheet")) || - (IS_XSLT_NAME(cur, "transform")))) { + (IS_XSLT_NAME(cur, "transform")))) { #ifdef WITH_XSLT_DEBUG_PARSING xsltGenericDebug(xsltGenericDebugContext, "xsltParseStylesheetProcess : found stylesheet\n"); #endif ret->literal_result = 0; - - xsltParseStylesheetExtPrefix(ret, cur); + xsltParseStylesheetExcludePrefix(ret, cur, 1); + xsltParseStylesheetExtPrefix(ret, cur, 1); } else { + xsltParseStylesheetExcludePrefix(ret, cur, 0); + xsltParseStylesheetExtPrefix(ret, cur, 0); ret->literal_result = 1; } if (!ret->nopreproc) @@ -2090,7 +2125,7 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) { /* * the document itself might be the template, check xsl:version */ - prop = xsltGetNsProp(cur, (const xmlChar *)"version", XSLT_NAMESPACE); + prop = xmlGetNsProp(cur, (const xmlChar *)"version", XSLT_NAMESPACE); if (prop == NULL) { xsltTransformError(NULL, ret, cur, "xsltParseStylesheetProcess : document is not a stylesheet\n"); diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c index 66b5e1ac..0700bf5a 100644 --- a/libxslt/xsltutils.c +++ b/libxslt/xsltutils.c @@ -173,6 +173,15 @@ xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) { return(NULL); prop = node->properties; + /* + * TODO: Substitute xmlGetProp() for xmlGetNsProp(), since the former + * is not namespace-aware and will return an attribute with equal + * name regardless of its namespace. + * Example: + * + * So this would return "myName" even if an attribute @name + * in the XSLT was requested. + */ if (nameSpace == NULL) return(xmlGetProp(node, name)); while (prop != NULL) { @@ -314,7 +323,7 @@ xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) { if ((ctxt == NULL) || (inst == NULL)) return; - prop = xsltGetNsProp(inst, (const xmlChar *)"terminate", XSLT_NAMESPACE); + prop = xmlGetNsProp(inst, (const xmlChar *)"terminate", NULL); if (prop != NULL) { if (xmlStrEqual(prop, (const xmlChar *)"yes")) { terminate = 1;