1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-27 16:21:14 +03:00

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.
This commit is contained in:
Kasimier T. Buchcik
2006-03-30 15:21:42 +00:00
parent bdd98c131b
commit ea9ed33cc8
7 changed files with 239 additions and 113 deletions

View File

@@ -1,3 +1,21 @@
Thu Mar 30 17:11:53 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
* 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 <daniel@veillard.com> Wed Mar 29 12:16:41 CEST 2006 Daniel Veillard <daniel@veillard.com>
* libxslt/transform.c: Charles Hardin pointed an OOM condition where * libxslt/transform.c: Charles Hardin pointed an OOM condition where

View File

@@ -282,7 +282,7 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return; return;
prop = xsltGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"name", NULL);
if (prop == NULL) { if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsl:attribute-set : name is missing\n"); "xsl:attribute-set : name is missing\n");
@@ -333,8 +333,8 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
*/ */
/* TODO check recursion */ /* TODO check recursion */
attributes = xsltGetNsProp(cur, (const xmlChar *)"use-attribute-sets", attributes = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets",
XSLT_NAMESPACE); NULL);
if (attributes == NULL) { if (attributes == NULL) {
goto done; goto done;
} }

View File

@@ -95,7 +95,7 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return (ret); return (ret);
uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
if (uriRef == NULL) { if (uriRef == NULL) {
xsltTransformError(NULL, style, cur, xsltTransformError(NULL, style, cur,
"xsl:import : missing href attribute\n"); "xsl:import : missing href attribute\n");
@@ -194,7 +194,7 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return (ret); return (ret);
uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
if (uriRef == NULL) { if (uriRef == NULL) {
xsltTransformError(NULL, style, cur, xsltTransformError(NULL, style, cur,
"xsl:include : missing href attribute\n"); "xsl:include : missing href attribute\n");

View File

@@ -69,15 +69,13 @@ xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) {
xmlNsPtr rNs; xmlNsPtr rNs;
const xmlChar *rhref; const xmlChar *rhref;
sprefix = xsltGetNsProp(node, (const xmlChar *)"stylesheet-prefix", sprefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
XSLT_NAMESPACE);
if (sprefix == NULL) { if (sprefix == NULL) {
xsltTransformError(NULL, style, node, xsltTransformError(NULL, style, node,
"namespace-alias: stylesheet-prefix attribute missing\n"); "namespace-alias: stylesheet-prefix attribute missing\n");
return; return;
} }
rprefix = xsltGetNsProp(node, (const xmlChar *)"result-prefix", rprefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
XSLT_NAMESPACE);
if (rprefix == NULL) { if (rprefix == NULL) {
xsltTransformError(NULL, style, node, xsltTransformError(NULL, style, node,
"namespace-alias: result-prefix attribute missing\n"); "namespace-alias: result-prefix attribute missing\n");

View File

@@ -329,6 +329,17 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
xsltStylePreCompPtr comp; xsltStylePreCompPtr comp;
const xmlChar *filename = NULL; 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); comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
if (comp == NULL) if (comp == NULL)
return (NULL); return (NULL);
@@ -340,36 +351,68 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"Found saxon:output extension\n"); "Found saxon:output extension\n");
#endif #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, filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"file", (const xmlChar *)"file",
XSLT_SAXON_NAMESPACE, &comp->has_filename); NULL, &comp->has_filename);
} else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) { } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
#ifdef WITH_XSLT_DEBUG_EXTRA #ifdef WITH_XSLT_DEBUG_EXTRA
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"Found xalan:write extension\n"); "Found xalan:write extension\n");
#endif #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")) { } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
filename = xsltEvalStaticAttrValueTemplate(style, inst, if (inst->ns != NULL) {
(const xmlChar *)"href", if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) {
XSLT_XT_NAMESPACE, &comp->has_filename); /* Mark the instruction as being of XSLT version 1.1. */
if (comp->has_filename == 0) { comp->ver11 = 1;
#ifdef WITH_XSLT_DEBUG_EXTRA #ifdef WITH_XSLT_DEBUG_EXTRA
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"Found xslt11:document construct\n"); "Found xslt11:document construct\n");
#endif #endif
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href",
XSLT_NAMESPACE, &comp->has_filename);
comp->ver11 = 1;
} else { } else {
if (xmlStrEqual(inst->ns->href,
(const xmlChar *)"http://exslt.org/common")) {
/* EXSLT. */
#ifdef WITH_XSLT_DEBUG_EXTRA
xsltGenericDebug(xsltGenericDebugContext,
"Found exslt:document extension\n");
#endif
} else if (xmlStrEqual(inst->ns->href, XSLT_XT_NAMESPACE)) {
/* James Clark's XT. */
#ifdef WITH_XSLT_DEBUG_EXTRA #ifdef WITH_XSLT_DEBUG_EXTRA
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"Found xt:document extension\n"); "Found xt:document extension\n");
#endif #endif
comp->ver11 = 0;
} }
} }
}
/*
* The element "document" is used in conjunction with the
* following namespaces:
* 1) XSLT_NAMESPACE (http://www.w3.org/1999/XSL/Transform version 1.1)
* <!ELEMENT xsl:document %template;>
* <!ATTLIST xsl:document
* href %avt; #REQUIRED
* 2) EXSLT_COMMON_NAMESPACE (http://exslt.org/common)
* <exsl:document
* href = { uri-reference }
* 3) XSLT_XT_NAMESPACE (http://www.jclark.com/xt)
* Example: <xt:document method="xml" href="myFile.xml">
*
* In all cases @href is in no namespace.
*/
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href", NULL, &comp->has_filename);
}
if (!comp->has_filename) { if (!comp->has_filename) {
goto error; goto error;
} }
@@ -398,6 +441,14 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
if ((style == NULL) || (inst == NULL)) if ((style == NULL) || (inst == NULL))
return; return;
/*
* <xsl:sort
* select = string-expression
* lang = { nmtoken }
* data-type = { "text" | "number" | qname-but-not-ncname }
* order = { "ascending" | "descending" }
* case-order = { "upper-first" | "lower-first" } />
*/
comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT); comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
if (comp == NULL) if (comp == NULL)
return; return;
@@ -406,7 +457,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->stype = xsltEvalStaticAttrValueTemplate(style, inst, comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"data-type", (const xmlChar *)"data-type",
XSLT_NAMESPACE, &comp->has_stype); NULL, &comp->has_stype);
if (comp->stype != NULL) { if (comp->stype != NULL) {
if (xmlStrEqual(comp->stype, (const xmlChar *) "text")) if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
comp->number = 0; comp->number = 0;
@@ -421,7 +472,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
} }
comp->order = xsltEvalStaticAttrValueTemplate(style, inst, comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"order", (const xmlChar *)"order",
XSLT_NAMESPACE, &comp->has_order); NULL, &comp->has_order);
if (comp->order != NULL) { if (comp->order != NULL) {
if (xmlStrEqual(comp->order, (const xmlChar *) "ascending")) if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
comp->descending = 0; comp->descending = 0;
@@ -436,7 +487,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
} }
comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst, comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"case-order", (const xmlChar *)"case-order",
XSLT_NAMESPACE, &comp->has_use); NULL, &comp->has_use);
if (comp->case_order != NULL) { if (comp->case_order != NULL) {
if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first")) if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first"))
comp->lower_first = 0; comp->lower_first = 0;
@@ -452,7 +503,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"lang", (const xmlChar *)"lang",
XSLT_NAMESPACE, &comp->has_lang); NULL, &comp->has_lang);
comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
if (comp->select == NULL) { if (comp->select == NULL) {
@@ -553,6 +604,14 @@ static void
xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp; xsltStylePreCompPtr comp;
/*
* <xsl:element
* name = { qname }
* namespace = { uri-reference }
* use-attribute-sets = qnames>
* <!-- Content: template -->
* </xsl:element>
*/
if ((style == NULL) || (inst == NULL)) if ((style == NULL) || (inst == NULL))
return; return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT); comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
@@ -563,7 +622,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->name = xsltEvalStaticAttrValueTemplate(style, inst, comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name", (const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name); NULL, &comp->has_name);
if (comp->name != NULL) { if (comp->name != NULL) {
if (xmlValidateQName(comp->name, 0)) { if (xmlValidateQName(comp->name, 0)) {
xsltTransformError(NULL, style, inst, xsltTransformError(NULL, style, inst,
@@ -573,7 +632,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
} }
comp->ns = xsltEvalStaticAttrValueTemplate(style, inst, comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace", (const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns); NULL, &comp->has_ns);
if (comp->has_ns == 0) { if (comp->has_ns == 0) {
xmlNsPtr defaultNs; xmlNsPtr defaultNs;
@@ -585,7 +644,7 @@ xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
} }
comp->use = xsltEvalStaticAttrValueTemplate(style, inst, comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"use-attribute-sets", (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) { xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp; xsltStylePreCompPtr comp;
/*
* <xsl:attribute
* name = { qname }
* namespace = { uri-reference }>
* <!-- Content: template -->
* </xsl:attribute>
*/
if ((style == NULL) || (inst == NULL)) if ((style == NULL) || (inst == NULL))
return; return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE); comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
@@ -612,7 +678,7 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
*/ */
comp->name = xsltEvalStaticAttrValueTemplate(style, inst, comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name", (const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name); NULL, &comp->has_name);
if (comp->name != NULL) { if (comp->name != NULL) {
if (xmlValidateQName(comp->name, 0)) { if (xmlValidateQName(comp->name, 0)) {
xsltTransformError(NULL, style, inst, xsltTransformError(NULL, style, inst,
@@ -622,7 +688,7 @@ xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
} }
comp->ns = xsltEvalStaticAttrValueTemplate(style, inst, comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace", (const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns); NULL, &comp->has_ns);
} }

View File

@@ -581,6 +581,16 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
int maxns = 10; int maxns = 10;
int i; int i;
/*
* TODO: This will gather the ns-decls of elements even if
* outside xsl:stylesheet. Example:
* <doc xmlns:foo="urn:test:foo">
* <xsl:stylesheet ...
* </doc>
* Will have foo="urn:test:foo" in the list.
* Is this a bug?
*/
if ((style == NULL) || (template == NULL) || (node == NULL) || if ((style == NULL) || (template == NULL) || (node == NULL) ||
(template->inheritedNsNr != 0) || (template->inheritedNs != NULL)) (template->inheritedNsNr != 0) || (template->inheritedNs != NULL))
return(0); return(0);
@@ -593,6 +603,11 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
if ((cur->prefix != NULL) && if ((cur->prefix != NULL) &&
(xsltCheckExtPrefix(style, cur->prefix))) (xsltCheckExtPrefix(style, cur->prefix)))
goto skip_ns; 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++) { for (i = 0;i < style->exclPrefixNr;i++) {
if (xmlStrEqual(cur->href, style->exclPrefixTab[i])) if (xmlStrEqual(cur->href, style->exclPrefixTab[i]))
goto skip_ns; goto skip_ns;
@@ -608,6 +623,9 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
} }
ret[nbns] = NULL; ret[nbns] = NULL;
} }
/*
* Skip shadowed namespace bindings.
*/
for (i = 0; i < nbns; i++) { for (i = 0; i < nbns; i++) {
if ((cur->prefix == ret[i]->prefix) || if ((cur->prefix == ret[i]->prefix) ||
(xmlStrEqual(cur->prefix, ret[i]->prefix))) (xmlStrEqual(cur->prefix, ret[i]->prefix)))
@@ -666,23 +684,24 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return; return;
prop = xsltGetNsProp(cur, (const xmlChar *) "version", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *) "version", NULL);
if (prop != NULL) { if (prop != NULL) {
if (style->version != NULL) if (style->version != NULL)
xmlFree(style->version); xmlFree(style->version);
style->version = prop; style->version = prop;
} }
prop = prop = xmlGetNsProp(cur, (const xmlChar *) "encoding", NULL);
xsltGetNsProp(cur, (const xmlChar *) "encoding", XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (style->encoding != NULL) if (style->encoding != NULL)
xmlFree(style->encoding); xmlFree(style->encoding);
style->encoding = prop; style->encoding = prop;
} }
/* relaxed to support xt:document */ /* relaxed to support xt:document
prop = xmlGetProp(cur, (const xmlChar *) "method"); * TODO KB: What does "relaxed to support xt:document" mean?
*/
prop = xmlGetNsProp(cur, (const xmlChar *) "method", NULL);
if (prop != NULL) { if (prop != NULL) {
const xmlChar *URI; const xmlChar *URI;
@@ -712,26 +731,21 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
} }
} }
prop = prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-system", NULL);
xsltGetNsProp(cur, (const xmlChar *) "doctype-system",
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (style->doctypeSystem != NULL) if (style->doctypeSystem != NULL)
xmlFree(style->doctypeSystem); xmlFree(style->doctypeSystem);
style->doctypeSystem = prop; style->doctypeSystem = prop;
} }
prop = prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-public", NULL);
xsltGetNsProp(cur, (const xmlChar *) "doctype-public",
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (style->doctypePublic != NULL) if (style->doctypePublic != NULL)
xmlFree(style->doctypePublic); xmlFree(style->doctypePublic);
style->doctypePublic = prop; style->doctypePublic = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *) "standalone", prop = xmlGetNsProp(cur, (const xmlChar *) "standalone", NULL);
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (xmlStrEqual(prop, (const xmlChar *) "yes")) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
style->standalone = 1; style->standalone = 1;
@@ -745,7 +759,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
xmlFree(prop); xmlFree(prop);
} }
prop = xsltGetNsProp(cur, (const xmlChar *) "indent", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *) "indent", NULL);
if (prop != NULL) { if (prop != NULL) {
if (xmlStrEqual(prop, (const xmlChar *) "yes")) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
style->indent = 1; style->indent = 1;
@@ -759,8 +773,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
xmlFree(prop); xmlFree(prop);
} }
prop = xsltGetNsProp(cur, (const xmlChar *) "omit-xml-declaration", prop = xmlGetNsProp(cur, (const xmlChar *) "omit-xml-declaration", NULL);
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (xmlStrEqual(prop, (const xmlChar *) "yes")) { if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
style->omitXmlDeclaration = 1; style->omitXmlDeclaration = 1;
@@ -775,9 +788,8 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
xmlFree(prop); xmlFree(prop);
} }
elements = elements = xmlGetNsProp(cur, (const xmlChar *) "cdata-section-elements",
xsltGetNsProp(cur, (const xmlChar *) "cdata-section-elements", NULL);
XSLT_NAMESPACE);
if (elements != NULL) { if (elements != NULL) {
if (style->cdataSection == NULL) if (style->cdataSection == NULL)
style->cdataSection = xmlHashCreate(10); style->cdataSection = xmlHashCreate(10);
@@ -829,7 +841,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
xmlFree(elements); xmlFree(elements);
} }
prop = xsltGetNsProp(cur, (const xmlChar *) "media-type", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *) "media-type", NULL);
if (prop != NULL) { if (prop != NULL) {
if (style->mediaType) if (style->mediaType)
xmlFree(style->mediaType); xmlFree(style->mediaType);
@@ -857,7 +869,7 @@ xsltParseStylesheetDecimalFormat(xsltStylesheetPtr style, xmlNodePtr cur)
format = style->decimalFormat; format = style->decimalFormat;
prop = xsltGetNsProp(cur, BAD_CAST("name"), XSLT_NAMESPACE); prop = xmlGetNsProp(cur, BAD_CAST("name"), NULL);
if (prop != NULL) { if (prop != NULL) {
format = xsltDecimalFormatGetByName(style, prop); format = xsltDecimalFormatGetByName(style, prop);
if (format != NULL) { if (format != NULL) {
@@ -880,64 +892,61 @@ xsltParseStylesheetDecimalFormat(xsltStylesheetPtr style, xmlNodePtr cur)
iter->next = format; iter->next = format;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"decimal-separator", prop = xmlGetNsProp(cur, (const xmlChar *)"decimal-separator", NULL);
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (format->decimalPoint != NULL) xmlFree(format->decimalPoint); if (format->decimalPoint != NULL) xmlFree(format->decimalPoint);
format->decimalPoint = prop; format->decimalPoint = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"grouping-separator", prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-separator", NULL);
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (format->grouping != NULL) xmlFree(format->grouping); if (format->grouping != NULL) xmlFree(format->grouping);
format->grouping = prop; format->grouping = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"infinity", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"infinity", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->infinity != NULL) xmlFree(format->infinity); if (format->infinity != NULL) xmlFree(format->infinity);
format->infinity = prop; format->infinity = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"minus-sign", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"minus-sign", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->minusSign != NULL) xmlFree(format->minusSign); if (format->minusSign != NULL) xmlFree(format->minusSign);
format->minusSign = prop; format->minusSign = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"NaN", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"NaN", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->noNumber != NULL) xmlFree(format->noNumber); if (format->noNumber != NULL) xmlFree(format->noNumber);
format->noNumber = prop; format->noNumber = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"percent", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"percent", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->percent != NULL) xmlFree(format->percent); if (format->percent != NULL) xmlFree(format->percent);
format->percent = prop; format->percent = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"per-mille", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"per-mille", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->permille != NULL) xmlFree(format->permille); if (format->permille != NULL) xmlFree(format->permille);
format->permille = prop; format->permille = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"zero-digit", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"zero-digit", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->zeroDigit != NULL) xmlFree(format->zeroDigit); if (format->zeroDigit != NULL) xmlFree(format->zeroDigit);
format->zeroDigit = prop; format->zeroDigit = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"digit", XSLT_NAMESPACE); prop = xmlGetNsProp(cur, (const xmlChar *)"digit", NULL);
if (prop != NULL) { if (prop != NULL) {
if (format->digit != NULL) xmlFree(format->digit); if (format->digit != NULL) xmlFree(format->digit);
format->digit = prop; format->digit = prop;
} }
prop = xsltGetNsProp(cur, (const xmlChar *)"pattern-separator", prop = xmlGetNsProp(cur, (const xmlChar *)"pattern-separator", NULL);
XSLT_NAMESPACE);
if (prop != NULL) { if (prop != NULL) {
if (format->patternSeparator != NULL) xmlFree(format->patternSeparator); if (format->patternSeparator != NULL) xmlFree(format->patternSeparator);
format->patternSeparator = prop; format->patternSeparator = prop;
@@ -961,7 +970,7 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return; return;
elements = xsltGetNsProp(cur, (const xmlChar *)"elements", XSLT_NAMESPACE); elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL);
if (elements == NULL) { if (elements == NULL) {
xsltTransformError(NULL, style, cur, xsltTransformError(NULL, style, cur,
"xsltParseStylesheetPreserveSpace: missing elements attribute\n"); "xsltParseStylesheetPreserveSpace: missing elements attribute\n");
@@ -1009,20 +1018,34 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
* @style: the XSLT stylesheet * @style: the XSLT stylesheet
* @template: the "extension-element-prefixes" prefix * @template: the "extension-element-prefixes" prefix
* *
* parse an XSLT stylesheet extension prefix and record * parse an XSLT stylesheet's "extension-element-prefix" attribute value
* prefixes needing stripping * 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 static void
xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur) { xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur,
int isXsltElem) {
xmlChar *prefixes; xmlChar *prefixes;
xmlChar *prefix, *end; xmlChar *prefix, *end;
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return; return;
prefixes = xsltGetNsProp(cur, (const xmlChar *)"extension-element-prefixes", if (isXsltElem) {
XSLT_NAMESPACE); /* 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) { if (prefixes == NULL) {
return; return;
} }
@@ -1066,8 +1089,8 @@ xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur) {
* @style: the XSLT stylesheet * @style: the XSLT stylesheet
* @cur: the "strip-space" element * @cur: the "strip-space" element
* *
* parse an XSLT stylesheet strip-space element and record * parse an XSLT stylesheet's strip-space element and record
* elements needing stripping * the elements needing stripping
*/ */
static void static void
@@ -1078,7 +1101,7 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return; return;
elements = xsltGetNsProp(cur, (const xmlChar *)"elements", XSLT_NAMESPACE); elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL);
if (elements == NULL) { if (elements == NULL) {
xsltTransformError(NULL, style, cur, xsltTransformError(NULL, style, cur,
"xsltParseStylesheetStripSpace: missing elements attribute\n"); "xsltParseStylesheetStripSpace: missing elements attribute\n");
@@ -1133,7 +1156,9 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
*/ */
static int static int
xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur) { xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur,
int isXsltElem)
{
int nb = 0; int nb = 0;
xmlChar *prefixes; xmlChar *prefixes;
xmlChar *prefix, *end; xmlChar *prefix, *end;
@@ -1141,8 +1166,13 @@ xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
return(0); return(0);
prefixes = xsltGetNsProp(cur, (const xmlChar *)"exclude-result-prefixes", if (isXsltElem)
XSLT_NAMESPACE); prefixes = xmlGetNsProp(cur,
(const xmlChar *)"exclude-result-prefixes", NULL);
else
prefixes = xmlGetNsProp(cur,
(const xmlChar *)"exclude-result-prefixes", XSLT_NAMESPACE);
if (prefixes == NULL) { if (prefixes == NULL) {
return(0); 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)) { if (IS_XSLT_ELEM(cur)) {
exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur, 1);
xsltStylePreCompute(style, cur); xsltStylePreCompute(style, cur);
if (IS_XSLT_NAME(cur, "text")) { if (IS_XSLT_NAME(cur, "text")) {
for (;exclPrefixes > 0;exclPrefixes--) for (;exclPrefixes > 0;exclPrefixes--)
exclPrefixPop(style); exclPrefixPop(style);
goto skip_children; goto skip_children;
} }
} } else
exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur, 0);
/* /*
* Remove excluded prefixes * Remove excluded prefixes
@@ -1504,9 +1545,9 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
xmlNodePtr text = cur->children, next; xmlNodePtr text = cur->children, next;
int noesc = 0; int noesc = 0;
prop = xsltGetNsProp(cur, prop = xmlGetNsProp(cur,
(const xmlChar *)"disable-output-escaping", (const xmlChar *)"disable-output-escaping",
XSLT_NAMESPACE); NULL);
if (prop != NULL) { if (prop != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING #ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
@@ -1690,7 +1731,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) {
/* /*
* Get arguments * Get arguments
*/ */
prop = xsltGetNsProp(key, (const xmlChar *)"name", XSLT_NAMESPACE); prop = xmlGetNsProp(key, (const xmlChar *)"name", NULL);
if (prop != NULL) { if (prop != NULL) {
const xmlChar *URI; const xmlChar *URI;
@@ -1714,7 +1755,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) {
goto error; goto error;
} }
match = xsltGetNsProp(key, (const xmlChar *)"match", XSLT_NAMESPACE); match = xmlGetNsProp(key, (const xmlChar *)"match", NULL);
if (match == NULL) { if (match == NULL) {
xsltTransformError(NULL, style, key, xsltTransformError(NULL, style, key,
"xsl:key : error missing match\n"); "xsl:key : error missing match\n");
@@ -1722,7 +1763,7 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) {
goto error; goto error;
} }
use = xsltGetNsProp(key, (const xmlChar *)"use", XSLT_NAMESPACE); use = xmlGetNsProp(key, (const xmlChar *)"use", NULL);
if (use == NULL) { if (use == NULL) {
xsltTransformError(NULL, style, key, xsltTransformError(NULL, style, key,
"xsl:key : error missing use\n"); "xsl:key : error missing use\n");
@@ -1762,7 +1803,6 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
xmlChar *mode = NULL; xmlChar *mode = NULL;
xmlChar *modeURI = NULL; xmlChar *modeURI = NULL;
double priority; double priority;
int exclPrefixes;
if (template == NULL) if (template == NULL)
return; return;
@@ -1777,11 +1817,6 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
style->templates = ret; style->templates = ret;
ret->style = style; ret->style = style;
/*
* Check excluded prefixes
*/
exclPrefixes = xsltParseStylesheetExcludePrefix(style, template);
/* /*
* Get inherited namespaces * Get inherited namespaces
*/ */
@@ -1790,7 +1825,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
/* /*
* Get arguments * Get arguments
*/ */
prop = xsltGetNsProp(template, (const xmlChar *)"mode", XSLT_NAMESPACE); prop = xmlGetNsProp(template, (const xmlChar *)"mode", NULL);
if (prop != NULL) { if (prop != NULL) {
const xmlChar *URI; const xmlChar *URI;
@@ -1812,20 +1847,20 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
if (mode != NULL) xmlFree(mode); if (mode != NULL) xmlFree(mode);
if (modeURI != NULL) xmlFree(modeURI); if (modeURI != NULL) xmlFree(modeURI);
} }
prop = xsltGetNsProp(template, (const xmlChar *)"match", XSLT_NAMESPACE); prop = xmlGetNsProp(template, (const xmlChar *)"match", NULL);
if (prop != NULL) { if (prop != NULL) {
if (ret->match != NULL) xmlFree(ret->match); if (ret->match != NULL) xmlFree(ret->match);
ret->match = prop; ret->match = prop;
} }
prop = xsltGetNsProp(template, (const xmlChar *)"priority", XSLT_NAMESPACE); prop = xmlGetNsProp(template, (const xmlChar *)"priority", NULL);
if (prop != NULL) { if (prop != NULL) {
priority = xmlXPathStringEvalNumber(prop); priority = xmlXPathStringEvalNumber(prop);
ret->priority = (float) priority; ret->priority = (float) priority;
xmlFree(prop); xmlFree(prop);
} }
prop = xsltGetNsProp(template, (const xmlChar *)"name", XSLT_NAMESPACE); prop = xmlGetNsProp(template, (const xmlChar *)"name", NULL);
if (prop != NULL) { if (prop != NULL) {
const xmlChar *URI; const xmlChar *URI;
xsltTemplatePtr cur; xsltTemplatePtr cur;
@@ -1880,14 +1915,13 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
xsltAddTemplate(style, ret, ret->mode, ret->modeURI); xsltAddTemplate(style, ret, ret->mode, ret->modeURI);
error: error:
for (;exclPrefixes > 0;exclPrefixes--) return;
exclPrefixPop(style);
} }
/** /**
* xsltParseStylesheetTop: * xsltParseStylesheetTop:
* @style: the XSLT stylesheet * @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 * scan the top level elements of an XSL stylesheet
*/ */
@@ -1903,7 +1937,7 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
if (top == NULL) if (top == NULL)
return; return;
prop = xsltGetNsProp(top, (const xmlChar *)"version", XSLT_NAMESPACE); prop = xmlGetNsProp(top, (const xmlChar *)"version", NULL);
if (prop == NULL) { if (prop == NULL) {
xsltTransformError(NULL, style, top, xsltTransformError(NULL, style, top,
"xsl:version is missing: document may not be a stylesheet\n"); "xsl:version is missing: document may not be a stylesheet\n");
@@ -2063,7 +2097,6 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
"xsltParseStylesheetProcess : empty stylesheet\n"); "xsltParseStylesheetProcess : empty stylesheet\n");
return(NULL); return(NULL);
} }
xsltParseStylesheetExcludePrefix(ret, cur);
if ((IS_XSLT_ELEM(cur)) && if ((IS_XSLT_ELEM(cur)) &&
((IS_XSLT_NAME(cur, "stylesheet")) || ((IS_XSLT_NAME(cur, "stylesheet")) ||
(IS_XSLT_NAME(cur, "transform")))) { (IS_XSLT_NAME(cur, "transform")))) {
@@ -2072,9 +2105,11 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
"xsltParseStylesheetProcess : found stylesheet\n"); "xsltParseStylesheetProcess : found stylesheet\n");
#endif #endif
ret->literal_result = 0; ret->literal_result = 0;
xsltParseStylesheetExcludePrefix(ret, cur, 1);
xsltParseStylesheetExtPrefix(ret, cur); xsltParseStylesheetExtPrefix(ret, cur, 1);
} else { } else {
xsltParseStylesheetExcludePrefix(ret, cur, 0);
xsltParseStylesheetExtPrefix(ret, cur, 0);
ret->literal_result = 1; ret->literal_result = 1;
} }
if (!ret->nopreproc) if (!ret->nopreproc)
@@ -2090,7 +2125,7 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
/* /*
* the document itself might be the template, check xsl:version * 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) { if (prop == NULL) {
xsltTransformError(NULL, ret, cur, xsltTransformError(NULL, ret, cur,
"xsltParseStylesheetProcess : document is not a stylesheet\n"); "xsltParseStylesheetProcess : document is not a stylesheet\n");

View File

@@ -173,6 +173,15 @@ xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
return(NULL); return(NULL);
prop = node->properties; 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:
* <xsl:element foo:name="myName"/>
* So this would return "myName" even if an attribute @name
* in the XSLT was requested.
*/
if (nameSpace == NULL) if (nameSpace == NULL)
return(xmlGetProp(node, name)); return(xmlGetProp(node, name));
while (prop != NULL) { while (prop != NULL) {
@@ -314,7 +323,7 @@ xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) {
if ((ctxt == NULL) || (inst == NULL)) if ((ctxt == NULL) || (inst == NULL))
return; return;
prop = xsltGetNsProp(inst, (const xmlChar *)"terminate", XSLT_NAMESPACE); prop = xmlGetNsProp(inst, (const xmlChar *)"terminate", NULL);
if (prop != NULL) { if (prop != NULL) {
if (xmlStrEqual(prop, (const xmlChar *)"yes")) { if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
terminate = 1; terminate = 1;