From 1e4297d54db0491514cb35f71c4c87b6a25f7b33 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Fri, 29 Jun 2001 21:36:22 +0000 Subject: [PATCH] added xsltGetQNameURI() and cleaned up the way URI for QNames were * libxslt/pattern.c libxslt/preproc.c libxslt/transform.c libxslt/xslt.c libxslt/xsltutils.[ch]: added xsltGetQNameURI() and cleaned up the way URI for QNames were computed through the code, serious cleanup. * libxslt/xsltInternals.h libxslt/xslt.c: moved cdata-sections in their own hash table, implementation not yet finished. Daniel --- ChangeLog | 9 +++ libxslt/pattern.c | 80 +++++++------------ libxslt/preproc.c | 200 ++++++++++++++---------------------------------- libxslt/transform.c | 72 +++++++---------- libxslt/xslt.c | 167 +++++++++++++--------------------------- libxslt/xsltInternals.h | 7 +- libxslt/xsltutils.c | 85 ++++++++++++++++++++ libxslt/xsltutils.h | 10 ++- 8 files changed, 272 insertions(+), 358 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa1fded..7847d2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Fri Jun 29 23:32:37 CEST 2001 Daniel Veillard + + * libxslt/pattern.c libxslt/preproc.c libxslt/transform.c + libxslt/xslt.c libxslt/xsltutils.[ch]: added xsltGetQNameURI() + and cleaned up the way URI for QNames were computed through + the code, serious cleanup. + * libxslt/xsltInternals.h libxslt/xslt.c: moved cdata-sections + in their own hash table, implementation not yet finished. + Thu Jun 28 23:01:14 CEST 2001 Daniel Veillard * libxslt/keys.c libxslt/templates.c libxslt/transform.c diff --git a/libxslt/pattern.c b/libxslt/pattern.c index e61fe7e..489da70 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -234,7 +234,7 @@ xsltFreeParserContext(xsltParserContextPtr ctxt) { */ static int xsltCompMatchAdd(xsltCompMatchPtr comp, xsltOp op, xmlChar *value, - xmlChar *value2) { + xmlChar *value2) { if (comp->nbStep >= 20) { xsltGenericError(xsltGenericErrorContext, "xsltCompMatchAddOp: overflow\n"); @@ -1126,13 +1126,14 @@ error: static void xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) { xmlChar *name = NULL; - xmlChar *prefix = NULL; - xmlChar *ncname = NULL; + const xmlChar *URI = NULL; xmlChar *URL = NULL; int level; SKIP_BLANKS; if ((token == NULL) && (CUR == '@')) { + xmlChar *prefix = NULL; + NEXT; if (CUR == '*') { NEXT; @@ -1205,23 +1206,14 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) { ctxt->error = 1; goto error; } - ncname = xmlSplitQName2(name, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsl: pattern, no namespace bound to prefix %s\n", - prefix); - } else { - URL = xmlStrdup(ns->href); - } - xmlFree(prefix); - } - xmlFree(name); - name = ncname; + URI = xsltGetQNameURI(ctxt->elem, &token); + if (token == NULL) { + ctxt->error = 1; + goto error; + } else { + name = xmlStrdup(token); + if (URI != NULL) + URL = xmlStrdup(URI); } PUSH(XSLT_OP_CHILD, name, URL); } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) { @@ -1232,23 +1224,14 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) { ctxt->error = 1; goto error; } - ncname = xmlSplitQName2(name, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsl: pattern, no namespace bound to prefix %s\n", - prefix); - } else { - URL = xmlStrdup(ns->href); - } - xmlFree(prefix); - } - xmlFree(name); - name = ncname; + URI = xsltGetQNameURI(ctxt->elem, &token); + if (token == NULL) { + ctxt->error = 1; + goto error; + } else { + name = xmlStrdup(token); + if (URI != NULL) + URL = xmlStrdup(URI); } PUSH(XSLT_OP_ATTR, name, URL); } else { @@ -1262,24 +1245,13 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token) { NEXT; PUSH(XSLT_OP_ALL, token, NULL); } else { - ncname = xmlSplitQName2(token, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsl: pattern, no namespace bound to prefix %s\n", - prefix); - } else { - URL = xmlStrdup(ns->href); - } - xmlFree(prefix); - } - xmlFree(token); - token = ncname; + URI = xsltGetQNameURI(ctxt->elem, &token); + if (token == NULL) { + ctxt->error = 1; + goto error; } + if (URI != NULL) + URL = xmlStrdup(URI); PUSH(XSLT_OP_ELEM, token, URL); } parse_predicate: diff --git a/libxslt/preproc.c b/libxslt/preproc.c index 9168a41..9da6d95 100644 --- a/libxslt/preproc.c +++ b/libxslt/preproc.c @@ -625,9 +625,6 @@ static void xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; xmlChar *prop; - xmlChar *ncname = NULL; - xmlChar *prefix = NULL; - xmlNsPtr ns = NULL; if ((style == NULL) || (inst == NULL)) return; @@ -646,28 +643,21 @@ xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xslt:with-param : name is missing\n"); style->errors++; } else { + const xmlChar *URI; - ncname = xmlSplitQName2(prop, &prefix); - if (ncname == NULL) { - ncname = prop; - prop = NULL; - prefix = NULL; - } - if (prefix != NULL) { - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xslt:with-param : no namespace bound to prefix %s\n", prefix); - style->warnings++; + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else { + comp->name = prop; + comp->has_name = 1; + if (URI != NULL) { + comp->ns = xmlStrdup(URI); + comp->has_ns = 1; + } else { + comp->has_ns = 0; } } - comp->name = xmlStrdup(ncname); - comp->has_name = 1; - if (ns != NULL) { - comp->has_ns = 1; - comp->ns = xmlStrdup(ns->href); - } else - comp->has_ns = 0; } comp->select = xsltGetNsProp(inst, (const xmlChar *)"select", @@ -685,13 +675,6 @@ xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xsl:param : content should be empty since select is present \n"); style->warnings++; } - - if (prop != NULL) - xmlFree(prop); - if (ncname != NULL) - xmlFree(ncname); - if (prefix != NULL) - xmlFree(prefix); } /** @@ -828,9 +811,6 @@ static void xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; xmlChar *prop; - xmlChar *ncname = NULL; - xmlChar *prefix = NULL; - xmlNsPtr ns = NULL; if ((style == NULL) || (inst == NULL)) return; @@ -849,37 +829,23 @@ xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xslt:call-template : name is missing\n"); style->errors++; } else { + const xmlChar *URI; - ncname = xmlSplitQName2(prop, &prefix); - if (ncname == NULL) { - ncname = prop; - prop = NULL; - prefix = NULL; - } - if (prefix != NULL) { - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xslt:call-template : no namespace bound to prefix %s\n", prefix); - style->warnings++; + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else { + comp->name = prop; + comp->has_name = 1; + if (URI != NULL) { + comp->ns = xmlStrdup(URI); + comp->has_ns = 1; + } else { + comp->has_ns = 0; } } - comp->name = xmlStrdup(ncname); - comp->has_name = 1; - if (ns != NULL) { - comp->ns = xmlStrdup(ns->href); - comp->has_ns = 1; - } else - comp->has_ns = 0; comp->templ = NULL; } - - if (prop != NULL) - xmlFree(prop); - if (ncname != NULL) - xmlFree(ncname); - if (prefix != NULL) - xmlFree(prefix); } /** @@ -907,34 +873,18 @@ xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) { */ prop = xsltGetNsProp(inst, (const xmlChar *)"mode", XSLT_NAMESPACE); if (prop != NULL) { - xmlChar *prefix = NULL; - - comp->mode = xmlSplitQName2(prop, &prefix); - if (comp->mode != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(comp->mode); - comp->mode = prop; - comp->modeURI = NULL; - } else { - comp->modeURI = xmlStrdup(ns->href); - xmlFree(prefix); - xmlFree(prop); - } + const xmlChar *URI; + + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else { + comp->mode = prop; + if (URI != NULL) { + comp->modeURI = xmlStrdup(URI); } else { - xmlFree(prop); comp->modeURI = NULL; } - } else { - comp->mode = prop; - comp->modeURI = NULL; } } comp->select = xsltGetNsProp(inst, (const xmlChar *)"select", @@ -1090,9 +1040,6 @@ static void xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; xmlChar *prop; - xmlChar *ncname = NULL; - xmlChar *prefix = NULL; - xmlNsPtr ns = NULL; if ((style == NULL) || (inst == NULL)) return; @@ -1111,27 +1058,21 @@ xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xslt:variable : name is missing\n"); style->errors++; } else { - ncname = xmlSplitQName2(prop, &prefix); - if (ncname == NULL) { - ncname = prop; - prop = NULL; - prefix = NULL; - } - if (prefix != NULL) { - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsl:variable no namespace bound to prefix %s\n", prefix); - style->warnings++; + const xmlChar *URI; + + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else { + comp->name = prop; + comp->has_name = 1; + if (URI != NULL) { + comp->ns = xmlStrdup(URI); + comp->has_ns = 1; + } else { + comp->has_ns = 0; } } - comp->name = xmlStrdup(ncname); - comp->has_name = 1; - if (ns != NULL) { - comp->ns = xmlStrdup(ns->href); - comp->has_ns = 1; - } else - comp->has_ns = 0; } comp->select = xsltGetNsProp(inst, (const xmlChar *)"select", @@ -1149,13 +1090,6 @@ xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xsl:variable : content should be empty since select is present \n"); style->warnings++; } - - if (prop != NULL) - xmlFree(prop); - if (ncname != NULL) - xmlFree(ncname); - if (prefix != NULL) - xmlFree(prefix); } /** @@ -1169,9 +1103,6 @@ static void xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { xsltStylePreCompPtr comp; xmlChar *prop; - xmlChar *ncname = NULL; - xmlChar *prefix = NULL; - xmlNsPtr ns = NULL; if ((style == NULL) || (inst == NULL)) return; @@ -1190,27 +1121,21 @@ xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xslt:param : name is missing\n"); style->errors++; } else { - ncname = xmlSplitQName2(prop, &prefix); - if (ncname == NULL) { - ncname = prop; - prop = NULL; - prefix = NULL; - } - if (prefix != NULL) { - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsl:param no namespace bound to prefix %s\n", prefix); - style->warnings++; + const xmlChar *URI; + + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else { + comp->name = prop; + comp->has_name = 1; + if (URI != NULL) { + comp->ns = xmlStrdup(URI); + comp->has_ns = 1; + } else { + comp->has_ns = 0; } } - comp->name = xmlStrdup(ncname); - comp->has_name = 1; - if (ns != NULL) { - comp->ns = xmlStrdup(ns->href); - comp->has_ns = 1; - } else - comp->has_ns = 0; } comp->select = xsltGetNsProp(inst, (const xmlChar *)"select", @@ -1228,13 +1153,6 @@ xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) { "xsl:param : content should be empty since select is present \n"); style->warnings++; } - - if (prop != NULL) - xmlFree(prop); - if (ncname != NULL) - xmlFree(ncname); - if (prefix != NULL) - xmlFree(prefix); } diff --git a/libxslt/transform.c b/libxslt/transform.c index ddf4d93..81cc891 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -1193,52 +1193,32 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node, (const xmlChar *) "method", XSLT_NAMESPACE); if (prop != NULL) { - xmlChar *ncname; - xmlChar *prefix = NULL; - - if (style->method != NULL) - xmlFree(style->method); - style->method = NULL; - if (style->methodURI != NULL) - xmlFree(style->methodURI); - style->methodURI = NULL; - - ncname = xmlSplitQName2(prop, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", - prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(ncname); - style->method = prop; - } else { - style->methodURI = xmlStrdup(ns->href); - style->method = ncname; - xmlFree(prefix); - xmlFree(prop); - } - } else { - style->method = ncname; - xmlFree(prop); - } - } else { - if ((xmlStrEqual(prop, (const xmlChar *) "xml")) || - (xmlStrEqual(prop, (const xmlChar *) "html")) || - (xmlStrEqual(prop, (const xmlChar *) "text"))) { - style->method = prop; - } else { - xsltGenericError(xsltGenericErrorContext, - "invalid value for method: %s\n", - prop); - style->warnings++; - } - } + const xmlChar *URI; + + if (style->method != NULL) + xmlFree(style->method); + style->method = NULL; + if (style->methodURI != NULL) + xmlFree(style->methodURI); + style->methodURI = NULL; + + URI = xsltGetQNameURI(inst, &prop); + if (prop == NULL) { + style->errors++; + } else if (URI == NULL) { + if ((xmlStrEqual(prop, (const xmlChar *) "xml")) || + (xmlStrEqual(prop, (const xmlChar *) "html")) || + (xmlStrEqual(prop, (const xmlChar *) "text"))) { + style->method = prop; + } else { + xsltGenericError(xsltGenericErrorContext, + "invalid value for method: %s\n", prop); + style->warnings++; + } + } else { + style->method = prop; + style->methodURI = xmlStrdup(URI); + } } prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *) diff --git a/libxslt/xslt.c b/libxslt/xslt.c index 61bac09..35aa9d9 100644 --- a/libxslt/xslt.c +++ b/libxslt/xslt.c @@ -316,6 +316,8 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet) xmlFreeDoc(sheet->doc); if (sheet->variables != NULL) xsltFreeStackElemList(sheet->variables); + if (sheet->cdataSection != NULL) + xmlHashFree(sheet->cdataSection, NULL); if (sheet->stripSpaces != NULL) xmlHashFree(sheet->stripSpaces, NULL); if (sheet->nsHash != NULL) @@ -387,8 +389,7 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) /* relaxed to support xt:document */ prop = xmlGetProp(cur, (const xmlChar *) "method"); if (prop != NULL) { - xmlChar *ncname; - xmlChar *prefix = NULL; + const xmlChar *URI; if (style->method != NULL) xmlFree(style->method); @@ -397,31 +398,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xmlFree(style->methodURI); style->methodURI = NULL; - ncname = xmlSplitQName2(prop, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(cur->doc, cur, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", - prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(ncname); - style->method = prop; - } else { - style->methodURI = xmlStrdup(ns->href); - style->method = ncname; - xmlFree(prefix); - xmlFree(prop); - } - } else { - style->method = ncname; - xmlFree(prop); - } - } else { + URI = xsltGetQNameURI(cur, &prop); + if (prop == NULL) { + style->errors++; + } else if (URI == NULL) { if ((xmlStrEqual(prop, (const xmlChar *) "xml")) || (xmlStrEqual(prop, (const xmlChar *) "html")) || (xmlStrEqual(prop, (const xmlChar *) "text"))) { @@ -431,7 +411,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) "invalid value for method: %s\n", prop); style->warnings++; } - } + } else { + style->method = prop; + style->methodURI = xmlStrdup(URI); + } } prop = @@ -501,9 +484,9 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) xsltGetNsProp(cur, (const xmlChar *) "cdata-section-elements", XSLT_NAMESPACE); if (elements != NULL) { - if (style->stripSpaces == NULL) - style->stripSpaces = xmlHashCreate(10); - if (style->stripSpaces == NULL) + if (style->cdataSection == NULL) + style->cdataSection = xmlHashCreate(10); + if (style->cdataSection == NULL) return; element = elements; @@ -517,14 +500,21 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) end++; element = xmlStrndup(element, end - element); if (element) { + const xmlChar *URI; #ifdef WITH_XSLT_DEBUG_PARSING xsltGenericDebug(xsltGenericDebugContext, "add cdata section output element %s\n", element); #endif - xmlHashAddEntry(style->stripSpaces, element, - (xmlChar *) "cdata"); - xmlFree(element); + + URI = xsltGetQNameURI(cur, &element); + if (element == NULL) { + style->errors++; + } else { + xmlHashAddEntry2(style->cdataSection, element, URI, + (void *) "cdata"); + xmlFree(element); + } } element = end; } @@ -1176,34 +1166,16 @@ xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) { */ prop = xsltGetNsProp(key, (const xmlChar *)"name", XSLT_NAMESPACE); if (prop != NULL) { - xmlChar *prefix = NULL; - - name = xmlSplitQName2(prop, &prefix); - if (name != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(key->doc, key, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(name); - name = prop; - nameURI = NULL; - } else { - nameURI = xmlStrdup(ns->href); - xmlFree(prefix); - xmlFree(prop); - } - } else { - xmlFree(prop); - nameURI = NULL; - } + const xmlChar *URI; + + URI = xsltGetQNameURI(key, &prop); + if (prop == NULL) { + style->errors++; + goto error; } else { name = prop; - nameURI = NULL; + if (URI != NULL) + nameURI = xmlStrdup(URI); } #ifdef WITH_XSLT_DEBUG_PARSING xsltGenericDebug(xsltGenericDebugContext, @@ -1260,8 +1232,8 @@ static void xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { xsltTemplatePtr ret; xmlChar *prop; - xmlChar *mode; - xmlChar *modeURI; + xmlChar *mode = NULL; + xmlChar *modeURI = NULL; double priority; if (template == NULL) @@ -1282,34 +1254,16 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { */ prop = xsltGetNsProp(template, (const xmlChar *)"mode", XSLT_NAMESPACE); if (prop != NULL) { - xmlChar *prefix = NULL; - - mode = xmlSplitQName2(prop, &prefix); - if (mode != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(template->doc, template, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(mode); - mode = prop; - modeURI = NULL; - } else { - modeURI = xmlStrdup(ns->href); - xmlFree(prefix); - xmlFree(prop); - } - } else { - xmlFree(prop); - modeURI = NULL; - } + const xmlChar *URI; + + URI = xsltGetQNameURI(template, &prop); + if (prop == NULL) { + style->errors++; + goto error; } else { mode = prop; - modeURI = NULL; + if (URI != NULL) + modeURI = xmlStrdup(URI); } #ifdef WITH_XSLT_DEBUG_PARSING xsltGenericDebug(xsltGenericDebugContext, @@ -1334,39 +1288,23 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { prop = xsltGetNsProp(template, (const xmlChar *)"name", XSLT_NAMESPACE); if (prop != NULL) { - xmlChar *ncname; - xmlChar *prefix = NULL; + const xmlChar *URI; if (ret->name != NULL) xmlFree(ret->name); ret->name = NULL; if (ret->nameURI != NULL) xmlFree(ret->nameURI); ret->nameURI = NULL; - ncname = xmlSplitQName2(prop, &prefix); - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; - - ns = xmlSearchNs(template->doc, template, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", prefix); - style->warnings++; - xmlFree(prefix); - xmlFree(ncname); - ret->name = prop; - } else { - ret->nameURI = xmlStrdup(ns->href); - ret->name = ncname; - xmlFree(prefix); - xmlFree(prop); - } - } else { - ret->name = ncname; - xmlFree(prop); - } + URI = xsltGetQNameURI(template, &prop); + if (prop == NULL) { + style->errors++; + goto error; } else { - ret->name = prop; + ret->name = prop; + if (URI != NULL) + ret->nameURI = xmlStrdup(URI); + else + ret->nameURI = NULL; } } @@ -1376,6 +1314,7 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { xsltParseTemplateContent(style, ret, template); xsltAddTemplate(style, ret, mode, modeURI); +error: if (mode != NULL) xmlFree(mode); if (modeURI != NULL) diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index c8fa47f..5eddd7f 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -1,6 +1,8 @@ /* * xsltInternals.h: internal data structures, constants and functions used * by the XSLT engine + * They are not part of the API or ABI, i.e. they can change + * without prior notice, use carefully. * * See Copyright for the status of this software. * @@ -237,9 +239,10 @@ struct _xsltStylesheet { * General data on the style sheet document */ xmlDocPtr doc; /* the parsed XML stylesheet */ - xmlHashTablePtr stripSpaces;/* the hash table of the strip-space - preserve space and cdata-section elements */ + xmlHashTablePtr stripSpaces;/* the hash table of the strip-space and + preserve space elements */ int stripAll; /* strip-space * (1) preserve-space * (-1) */ + xmlHashTablePtr cdataSection;/* the hash table of the cdata-section */ /* * Global variable or parameters diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c index 8a44eda..df69fac 100644 --- a/libxslt/xsltutils.c +++ b/libxslt/xsltutils.c @@ -255,6 +255,91 @@ xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler) { /************************************************************************ * * + * QNames * + * * + ************************************************************************/ + +/** + * xsltGetQNameURI: + * @node: the node holding the QName + * @name: pointer to the initial QName value + * + * This function analyze @name, if the name contains a prefix, + * the function seaches the associated namespace in scope for it. + * It will also replace @name value with the NCName, the old value being + * freed. + * Errors in the prefix lookup are signalled by setting @name to NULL. + * + * NOTE: the namespace returned is a pointer to the place where it is + * defined and hence has the same lifespan as the document holding it. + * + * Returns the namespace URI if there is a prefix, or NULL if @name is + * not prefixed. + */ +const xmlChar * +xsltGetQNameURI(xmlNodePtr node, xmlChar ** name) +{ + int len = 0; + xmlChar *qname; + xmlNsPtr ns; + + if (name == NULL) + return(NULL); + qname = *name; + if ((qname == NULL) || (*qname == 0)) + return(NULL); + if (node == NULL) { + xsltGenericError(xsltGenericErrorContext, + "QName: no element for namespace lookup %s\n", + qname); + xmlFree(qname); + *name = NULL; + return(NULL); + } + + /* nasty but valid */ + if (qname[0] == ':') + return(NULL); + + /* + * we are not trying to validate but just to cut, and yes it will + * work even if this is as set of UTF-8 encoded chars + */ + while ((qname[len] != 0) && (qname[len] != ':')) + len++; + + if (qname[len] == 0) + return(NULL); + + /* + * handle xml: separately, this one is magical + */ + if ((qname[0] == 'x') && (qname[1] == 'm') && + (qname[2] == 'l') && (qname[3] == ':')) { + if (qname[4] == 0) + return(NULL); + *name = xmlStrdup(&qname[4]); + xmlFree(qname); + return(XML_XML_NAMESPACE); + } + + qname[len] = 0; + ns = xmlSearchNs(node->doc, node, qname); + if (ns == NULL) { + xsltGenericError(xsltGenericErrorContext, + "%s:%s : no namespace bound to prefix %s\n", + qname, &qname[len + 1]); + *name = NULL; + xmlFree(qname); + return(NULL); + } + *name = xmlStrdup(&qname[len + 1]); + xmlFree(qname); + return(ns->href); +} + +/************************************************************************ + * * * Sorting * * * ************************************************************************/ diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h index 8a54d9a..fce4c3c 100644 --- a/libxslt/xsltutils.h +++ b/libxslt/xsltutils.h @@ -78,13 +78,21 @@ void xsltSetGenericDebugFunc (void *ctx, xmlGenericErrorFunc handler); /* - * Sorting ... this is definitely a temporary interface ! + * Sorting */ void xsltDocumentSortFunction (xmlNodeSetPtr list); void xsltDoSortFunction (xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts); + +/* + * QNames handling + */ + +const xmlChar * xsltGetQNameURI (xmlNodePtr node, + xmlChar **name); + /* * Output, reuse libxml I/O buffers */ -- 2.7.4