123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379 |
- /*
- * preproc.c: Preprocessing of style operations
- *
- * References:
- * http://www.w3.org/TR/1999/REC-xslt-19991116
- *
- * Michael Kay "XSLT Programmer's Reference" pp 637-643
- * Writing Multiple Output Files
- *
- * XSLT-1.1 Working Draft
- * http://www.w3.org/TR/xslt11#multiple-output
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
- #define IN_LIBXSLT
- #include "libxslt.h"
- #include <string.h>
- #include <libxml/xmlmemory.h>
- #include <libxml/parser.h>
- #include <libxml/tree.h>
- #include <libxml/valid.h>
- #include <libxml/hash.h>
- #include <libxml/uri.h>
- #include <libxml/encoding.h>
- #include <libxml/xmlerror.h>
- #include "xslt.h"
- #include "xsltutils.h"
- #include "xsltInternals.h"
- #include "transform.h"
- #include "templates.h"
- #include "variables.h"
- #include "numbersInternals.h"
- #include "preproc.h"
- #include "extra.h"
- #include "imports.h"
- #include "extensions.h"
- #include "pattern.h"
- #ifdef WITH_XSLT_DEBUG
- #define WITH_XSLT_DEBUG_PREPROC
- #endif
- const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
- /************************************************************************
- * *
- * Grammar checks *
- * *
- ************************************************************************/
- #ifdef XSLT_REFACTORED
- /*
- * Grammar checks are now performed in xslt.c.
- */
- #else
- /**
- * xsltCheckTopLevelElement:
- * @style: the XSLT stylesheet
- * @inst: the XSLT instruction
- * @err: raise an error or not
- *
- * Check that the instruction is instanciated as a top level element.
- *
- * Returns -1 in case of error, 0 if failed and 1 in case of success
- */
- static int
- xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {
- xmlNodePtr parent;
- if ((style == NULL) || (inst == NULL) || (inst->ns == NULL))
- return(-1);
- parent = inst->parent;
- if (parent == NULL) {
- if (err) {
- xsltTransformError(NULL, style, inst,
- "internal problem: element has no parent\n");
- style->errors++;
- }
- return(0);
- }
- if ((parent->ns == NULL) || (parent->type != XML_ELEMENT_NODE) ||
- ((parent->ns != inst->ns) &&
- (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
- ((!xmlStrEqual(parent->name, BAD_CAST "stylesheet")) &&
- (!xmlStrEqual(parent->name, BAD_CAST "transform")))) {
- if (err) {
- xsltTransformError(NULL, style, inst,
- "element %s only allowed as child of stylesheet\n",
- inst->name);
- style->errors++;
- }
- return(0);
- }
- return(1);
- }
- /**
- * xsltCheckInstructionElement:
- * @style: the XSLT stylesheet
- * @inst: the XSLT instruction
- *
- * Check that the instruction is instanciated as an instruction element.
- */
- static void
- xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {
- xmlNodePtr parent;
- int has_ext;
- if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
- (style->literal_result))
- return;
- has_ext = (style->extInfos != NULL);
- parent = inst->parent;
- if (parent == NULL) {
- xsltTransformError(NULL, style, inst,
- "internal problem: element has no parent\n");
- style->errors++;
- return;
- }
- while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
- if (((parent->ns == inst->ns) ||
- ((parent->ns != NULL) &&
- (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
- ((xmlStrEqual(parent->name, BAD_CAST "template")) ||
- (xmlStrEqual(parent->name, BAD_CAST "param")) ||
- (xmlStrEqual(parent->name, BAD_CAST "attribute")) ||
- (xmlStrEqual(parent->name, BAD_CAST "variable")))) {
- return;
- }
- /*
- * if we are within an extension element all bets are off
- * about the semantic there e.g. xsl:param within func:function
- */
- if ((has_ext) && (parent->ns != NULL) &&
- (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
- return;
- parent = parent->parent;
- }
- xsltTransformError(NULL, style, inst,
- "element %s only allowed within a template, variable or param\n",
- inst->name);
- style->errors++;
- }
- /**
- * xsltCheckParentElement:
- * @style: the XSLT stylesheet
- * @inst: the XSLT instruction
- * @allow1: allowed parent1
- * @allow2: allowed parent2
- *
- * Check that the instruction is instanciated as the childre of one of the
- * possible parents.
- */
- static void
- xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
- const xmlChar *allow1, const xmlChar *allow2) {
- xmlNodePtr parent;
- if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
- (style->literal_result))
- return;
- parent = inst->parent;
- if (parent == NULL) {
- xsltTransformError(NULL, style, inst,
- "internal problem: element has no parent\n");
- style->errors++;
- return;
- }
- if (((parent->ns == inst->ns) ||
- ((parent->ns != NULL) &&
- (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
- ((xmlStrEqual(parent->name, allow1)) ||
- (xmlStrEqual(parent->name, allow2)))) {
- return;
- }
- if (style->extInfos != NULL) {
- while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
- /*
- * if we are within an extension element all bets are off
- * about the semantic there e.g. xsl:param within func:function
- */
- if ((parent->ns != NULL) &&
- (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
- return;
- parent = parent->parent;
- }
- }
- xsltTransformError(NULL, style, inst,
- "element %s is not allowed within that context\n",
- inst->name);
- style->errors++;
- }
- #endif
- /************************************************************************
- * *
- * handling of precomputed data *
- * *
- ************************************************************************/
- /**
- * xsltNewStylePreComp:
- * @style: the XSLT stylesheet
- * @type: the construct type
- *
- * Create a new XSLT Style precomputed block
- *
- * Returns the newly allocated specialized structure
- * or NULL in case of error
- */
- static xsltStylePreCompPtr
- xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
- xsltStylePreCompPtr cur;
- #ifdef XSLT_REFACTORED
- size_t size;
- #endif
- if (style == NULL)
- return(NULL);
- #ifdef XSLT_REFACTORED
- /*
- * URGENT TODO: Use specialized factory functions in order
- * to avoid this ugliness.
- */
- switch (type) {
- case XSLT_FUNC_COPY:
- size = sizeof(xsltStyleItemCopy); break;
- case XSLT_FUNC_SORT:
- size = sizeof(xsltStyleItemSort); break;
- case XSLT_FUNC_TEXT:
- size = sizeof(xsltStyleItemText); break;
- case XSLT_FUNC_ELEMENT:
- size = sizeof(xsltStyleItemElement); break;
- case XSLT_FUNC_ATTRIBUTE:
- size = sizeof(xsltStyleItemAttribute); break;
- case XSLT_FUNC_COMMENT:
- size = sizeof(xsltStyleItemComment); break;
- case XSLT_FUNC_PI:
- size = sizeof(xsltStyleItemPI); break;
- case XSLT_FUNC_COPYOF:
- size = sizeof(xsltStyleItemCopyOf); break;
- case XSLT_FUNC_VALUEOF:
- size = sizeof(xsltStyleItemValueOf); break;;
- case XSLT_FUNC_NUMBER:
- size = sizeof(xsltStyleItemNumber); break;
- case XSLT_FUNC_APPLYIMPORTS:
- size = sizeof(xsltStyleItemApplyImports); break;
- case XSLT_FUNC_CALLTEMPLATE:
- size = sizeof(xsltStyleItemCallTemplate); break;
- case XSLT_FUNC_APPLYTEMPLATES:
- size = sizeof(xsltStyleItemApplyTemplates); break;
- case XSLT_FUNC_CHOOSE:
- size = sizeof(xsltStyleItemChoose); break;
- case XSLT_FUNC_IF:
- size = sizeof(xsltStyleItemIf); break;
- case XSLT_FUNC_FOREACH:
- size = sizeof(xsltStyleItemForEach); break;
- case XSLT_FUNC_DOCUMENT:
- size = sizeof(xsltStyleItemDocument); break;
- case XSLT_FUNC_WITHPARAM:
- size = sizeof(xsltStyleItemWithParam); break;
- case XSLT_FUNC_PARAM:
- size = sizeof(xsltStyleItemParam); break;
- case XSLT_FUNC_VARIABLE:
- size = sizeof(xsltStyleItemVariable); break;
- case XSLT_FUNC_WHEN:
- size = sizeof(xsltStyleItemWhen); break;
- case XSLT_FUNC_OTHERWISE:
- size = sizeof(xsltStyleItemOtherwise); break;
- default:
- xsltTransformError(NULL, style, NULL,
- "xsltNewStylePreComp : invalid type %d\n", type);
- style->errors++;
- return(NULL);
- }
- /*
- * Create the structure.
- */
- cur = (xsltStylePreCompPtr) xmlMalloc(size);
- if (cur == NULL) {
- xsltTransformError(NULL, style, NULL,
- "xsltNewStylePreComp : malloc failed\n");
- style->errors++;
- return(NULL);
- }
- memset(cur, 0, size);
- #else /* XSLT_REFACTORED */
- /*
- * Old behaviour.
- */
- cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
- if (cur == NULL) {
- xsltTransformError(NULL, style, NULL,
- "xsltNewStylePreComp : malloc failed\n");
- style->errors++;
- return(NULL);
- }
- memset(cur, 0, sizeof(xsltStylePreComp));
- #endif /* XSLT_REFACTORED */
- /*
- * URGENT TODO: Better to move this to spezialized factory functions.
- */
- cur->type = type;
- switch (cur->type) {
- case XSLT_FUNC_COPY:
- cur->func = xsltCopy;break;
- case XSLT_FUNC_SORT:
- cur->func = xsltSort;break;
- case XSLT_FUNC_TEXT:
- cur->func = xsltText;break;
- case XSLT_FUNC_ELEMENT:
- cur->func = xsltElement;break;
- case XSLT_FUNC_ATTRIBUTE:
- cur->func = xsltAttribute;break;
- case XSLT_FUNC_COMMENT:
- cur->func = xsltComment;break;
- case XSLT_FUNC_PI:
- cur->func = xsltProcessingInstruction;
- break;
- case XSLT_FUNC_COPYOF:
- cur->func = xsltCopyOf;break;
- case XSLT_FUNC_VALUEOF:
- cur->func = xsltValueOf;break;
- case XSLT_FUNC_NUMBER:
- cur->func = xsltNumber;break;
- case XSLT_FUNC_APPLYIMPORTS:
- cur->func = xsltApplyImports;break;
- case XSLT_FUNC_CALLTEMPLATE:
- cur->func = xsltCallTemplate;break;
- case XSLT_FUNC_APPLYTEMPLATES:
- cur->func = xsltApplyTemplates;break;
- case XSLT_FUNC_CHOOSE:
- cur->func = xsltChoose;break;
- case XSLT_FUNC_IF:
- cur->func = xsltIf;break;
- case XSLT_FUNC_FOREACH:
- cur->func = xsltForEach;break;
- case XSLT_FUNC_DOCUMENT:
- cur->func = xsltDocumentElem;break;
- case XSLT_FUNC_WITHPARAM:
- case XSLT_FUNC_PARAM:
- case XSLT_FUNC_VARIABLE:
- case XSLT_FUNC_WHEN:
- break;
- default:
- if (cur->func == NULL) {
- xsltTransformError(NULL, style, NULL,
- "xsltNewStylePreComp : no function for type %d\n", type);
- style->errors++;
- }
- }
- cur->next = style->preComps;
- style->preComps = (xsltElemPreCompPtr) cur;
- return(cur);
- }
- /**
- * xsltFreeStylePreComp:
- * @comp: an XSLT Style precomputed block
- *
- * Free up the memory allocated by @comp
- */
- static void
- xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
- if (comp == NULL)
- return;
- #ifdef XSLT_REFACTORED
- /*
- * URGENT TODO: Implement destructors.
- */
- switch (comp->type) {
- case XSLT_FUNC_LITERAL_RESULT_ELEMENT:
- break;
- case XSLT_FUNC_COPY:
- break;
- case XSLT_FUNC_SORT: {
- xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
- if (item->locale != (xsltLocale)0)
- xsltFreeLocale(item->locale);
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_TEXT:
- break;
- case XSLT_FUNC_ELEMENT:
- break;
- case XSLT_FUNC_ATTRIBUTE:
- break;
- case XSLT_FUNC_COMMENT:
- break;
- case XSLT_FUNC_PI:
- break;
- case XSLT_FUNC_COPYOF: {
- xsltStyleItemCopyOfPtr item = (xsltStyleItemCopyOfPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_VALUEOF: {
- xsltStyleItemValueOfPtr item = (xsltStyleItemValueOfPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_NUMBER: {
- xsltStyleItemNumberPtr item = (xsltStyleItemNumberPtr) comp;
- if (item->numdata.countPat != NULL)
- xsltFreeCompMatchList(item->numdata.countPat);
- if (item->numdata.fromPat != NULL)
- xsltFreeCompMatchList(item->numdata.fromPat);
- }
- break;
- case XSLT_FUNC_APPLYIMPORTS:
- break;
- case XSLT_FUNC_CALLTEMPLATE:
- break;
- case XSLT_FUNC_APPLYTEMPLATES: {
- xsltStyleItemApplyTemplatesPtr item =
- (xsltStyleItemApplyTemplatesPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_CHOOSE:
- break;
- case XSLT_FUNC_IF: {
- xsltStyleItemIfPtr item = (xsltStyleItemIfPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_FOREACH: {
- xsltStyleItemForEachPtr item =
- (xsltStyleItemForEachPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_DOCUMENT:
- break;
- case XSLT_FUNC_WITHPARAM: {
- xsltStyleItemWithParamPtr item =
- (xsltStyleItemWithParamPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_PARAM: {
- xsltStyleItemParamPtr item =
- (xsltStyleItemParamPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_VARIABLE: {
- xsltStyleItemVariablePtr item =
- (xsltStyleItemVariablePtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_WHEN: {
- xsltStyleItemWhenPtr item =
- (xsltStyleItemWhenPtr) comp;
- if (item->comp != NULL)
- xmlXPathFreeCompExpr(item->comp);
- }
- break;
- case XSLT_FUNC_OTHERWISE:
- case XSLT_FUNC_FALLBACK:
- case XSLT_FUNC_MESSAGE:
- case XSLT_FUNC_INCLUDE:
- case XSLT_FUNC_ATTRSET:
- break;
- default:
- /* TODO: Raise error. */
- break;
- }
- #else
- if (comp->locale != (xsltLocale)0)
- xsltFreeLocale(comp->locale);
- if (comp->comp != NULL)
- xmlXPathFreeCompExpr(comp->comp);
- if (comp->numdata.countPat != NULL)
- xsltFreeCompMatchList(comp->numdata.countPat);
- if (comp->numdata.fromPat != NULL)
- xsltFreeCompMatchList(comp->numdata.fromPat);
- if (comp->nsList != NULL)
- xmlFree(comp->nsList);
- #endif
- xmlFree(comp);
- }
- /************************************************************************
- * *
- * XSLT-1.1 extensions *
- * *
- ************************************************************************/
- /**
- * xsltDocumentComp:
- * @style: the XSLT stylesheet
- * @inst: the instruction in the stylesheet
- * @function: unused
- *
- * Pre process an XSLT-1.1 document element
- *
- * Returns a precompiled data structure for the element
- */
- xsltElemPreCompPtr
- xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
- xsltTransformFunction function ATTRIBUTE_UNUSED) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemDocumentPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- 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 (from the abandoned old working
- * draft of XSLT 1.1)
- * (in libexslt/common.c)
- * "document" in EXSLT_COMMON_NAMESPACE
- */
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemDocumentPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
- #endif
- if (comp == NULL)
- return (NULL);
- comp->inst = inst;
- comp->ver11 = 0;
- if (xmlStrEqual(inst->name, (const xmlChar *) "output")) {
- #ifdef WITH_XSLT_DEBUG_EXTRA
- 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; it is an AVT.
- * (http://www.computerwizards.com/saxon/doc/extensions.html#saxon:output)
- *
- * TODO: Do we need not to check the namespace here?
- */
- filename = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"file",
- 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
- /* 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?
- *
- * TODO: Do we need not to check the namespace here?
- * The extension ns is "http://xml.apache.org/xalan/redirect".
- * See http://xml.apache.org/xalan-j/extensionslib.html.
- */
- } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
- if (inst->ns != NULL) {
- if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) {
- /*
- * Mark the instruction as being of
- * XSLT version 1.1 (abandoned).
- */
- comp->ver11 = 1;
- #ifdef WITH_XSLT_DEBUG_EXTRA
- 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 exslt:document extension\n");
- #endif
- } 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)
- * <!ELEMENT xsl:document %template;>
- * <!ATTLIST xsl:document
- * href %avt; #REQUIRED
- * @href is an AVT
- * IMPORTANT: xsl:document was in the abandoned XSLT 1.1 draft,
- * it was removed and isn't available in XSLT 1.1 anymore.
- * In XSLT 2.0 it was renamed to xsl:result-document.
- *
- * All other attributes are identical to the attributes
- * on xsl:output
- *
- * 2) EXSLT_COMMON_NAMESPACE (http://exslt.org/common)
- * <exsl:document
- * href = { uri-reference }
- * TODO: is @href is an AVT?
- *
- * 3) XSLT_XT_NAMESPACE (http://www.jclark.com/xt)
- * Example: <xt:document method="xml" href="myFile.xml">
- * TODO: is @href is an AVT?
- *
- * 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;
- }
- comp->filename = filename;
- error:
- return ((xsltElemPreCompPtr) comp);
- }
- /************************************************************************
- * *
- * Most of the XSLT-1.0 transformations *
- * *
- ************************************************************************/
- /**
- * xsltSortComp:
- * @style: the XSLT stylesheet
- * @inst: the xslt sort node
- *
- * Process the xslt sort node on the source node
- */
- static void
- xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemSortPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemSortPtr) xsltNewStylePreComp(style, XSLT_FUNC_SORT);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"data-type",
- NULL, &comp->has_stype);
- if (comp->stype != NULL) {
- if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
- comp->number = 0;
- else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
- comp->number = 1;
- else {
- xsltTransformError(NULL, style, inst,
- "xsltSortComp: no support for data-type = %s\n", comp->stype);
- comp->number = 0; /* use default */
- if (style != NULL) style->warnings++;
- }
- }
- comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"order",
- NULL, &comp->has_order);
- if (comp->order != NULL) {
- if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
- comp->descending = 0;
- else if (xmlStrEqual(comp->order, (const xmlChar *) "descending"))
- comp->descending = 1;
- else {
- xsltTransformError(NULL, style, inst,
- "xsltSortComp: invalid value %s for order\n", comp->order);
- comp->descending = 0; /* use default */
- if (style != NULL) style->warnings++;
- }
- }
- comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"case-order",
- NULL, &comp->has_use);
- if (comp->case_order != NULL) {
- if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first"))
- comp->lower_first = 0;
- else if (xmlStrEqual(comp->case_order, (const xmlChar *) "lower-first"))
- comp->lower_first = 1;
- else {
- xsltTransformError(NULL, style, inst,
- "xsltSortComp: invalid value %s for order\n", comp->order);
- comp->lower_first = 0; /* use default */
- if (style != NULL) style->warnings++;
- }
- }
- comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"lang",
- NULL, &comp->has_lang);
- if (comp->lang != NULL) {
- comp->locale = xsltNewLocale(comp->lang);
- }
- else {
- comp->locale = (xsltLocale)0;
- }
- comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
- if (comp->select == NULL) {
- /*
- * The default value of the select attribute is ., which will
- * cause the string-value of the current node to be used as
- * the sort key.
- */
- comp->select = xmlDictLookup(style->dict, BAD_CAST ".", 1);
- }
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsltSortComp: could not compile select expression '%s'\n",
- comp->select);
- if (style != NULL) style->errors++;
- }
- if (inst->children != NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:sort : is not empty\n");
- if (style != NULL) style->errors++;
- }
- }
- /**
- * xsltCopyComp:
- * @style: the XSLT stylesheet
- * @inst: the xslt copy node
- *
- * Process the xslt copy node on the source node
- */
- static void
- xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemCopyPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemCopyPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPY);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->use = xsltGetCNsProp(style, inst, (const xmlChar *)"use-attribute-sets",
- XSLT_NAMESPACE);
- if (comp->use == NULL)
- comp->has_use = 0;
- else
- comp->has_use = 1;
- }
- #ifdef XSLT_REFACTORED
- /* Enable if ever needed for xsl:text. */
- #else
- /**
- * xsltTextComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt text node
- *
- * TODO: This function is obsolete, since xsl:text won't
- * be compiled, but removed from the tree.
- *
- * Process the xslt text node on the source node
- */
- static void
- xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemTextPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- const xmlChar *prop;
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemTextPtr) xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->noescape = 0;
- prop = xsltGetCNsProp(style, inst,
- (const xmlChar *)"disable-output-escaping",
- XSLT_NAMESPACE);
- if (prop != NULL) {
- if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
- comp->noescape = 1;
- } else if (!xmlStrEqual(prop,
- (const xmlChar *)"no")){
- xsltTransformError(NULL, style, inst,
- "xsl:text: disable-output-escaping allows only yes or no\n");
- if (style != NULL) style->warnings++;
- }
- }
- }
- #endif /* else of XSLT_REFACTORED */
- /**
- * xsltElementComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt element node
- *
- * Process the xslt element node on the source node
- */
- static void
- xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemElementPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- /*
- * <xsl:element
- * name = { qname }
- * namespace = { uri-reference }
- * use-attribute-sets = qnames>
- * <!-- Content: template -->
- * </xsl:element>
- */
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemElementPtr) xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "name".
- */
- /*
- * TODO: Precompile the AVT. See bug #344894.
- */
- comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"name", NULL, &comp->has_name);
- if (! comp->has_name) {
- xsltTransformError(NULL, style, inst,
- "xsl:element: The attribute 'name' is missing.\n");
- style->errors++;
- goto error;
- }
- /*
- * Attribute "namespace".
- */
- /*
- * TODO: Precompile the AVT. See bug #344894.
- */
- comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"namespace", NULL, &comp->has_ns);
- if (comp->name != NULL) {
- if (xmlValidateQName(comp->name, 0)) {
- xsltTransformError(NULL, style, inst,
- "xsl:element: The value '%s' of the attribute 'name' is "
- "not a valid QName.\n", comp->name);
- style->errors++;
- } else {
- const xmlChar *prefix = NULL, *name;
- name = xsltSplitQName(style->dict, comp->name, &prefix);
- if (comp->has_ns == 0) {
- xmlNsPtr ns;
- /*
- * SPEC XSLT 1.0:
- * "If the namespace attribute is not present, then the QName is
- * expanded into an expanded-name using the namespace declarations
- * in effect for the xsl:element element, including any default
- * namespace declaration.
- */
- ns = xmlSearchNs(inst->doc, inst, prefix);
- if (ns != NULL) {
- comp->ns = xmlDictLookup(style->dict, ns->href, -1);
- comp->has_ns = 1;
- #ifdef XSLT_REFACTORED
- comp->nsPrefix = prefix;
- comp->name = name;
- #else
- (void)name; /* Suppress unused variable warning. */
- #endif
- } else if (prefix != NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:element: The prefixed QName '%s' "
- "has no namespace binding in scope in the "
- "stylesheet; this is an error, since the namespace was "
- "not specified by the instruction itself.\n", comp->name);
- style->errors++;
- }
- }
- if ((prefix != NULL) &&
- (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
- {
- /*
- * Mark is to be skipped.
- */
- comp->has_name = 0;
- }
- }
- }
- /*
- * Attribute "use-attribute-sets",
- */
- comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"use-attribute-sets",
- NULL, &comp->has_use);
- error:
- return;
- }
- /**
- * xsltAttributeComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt attribute node
- *
- * Process the xslt attribute node on the source node
- */
- static void
- xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemAttributePtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- /*
- * <xsl:attribute
- * name = { qname }
- * namespace = { uri-reference }>
- * <!-- Content: template -->
- * </xsl:attribute>
- */
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemAttributePtr) xsltNewStylePreComp(style,
- XSLT_FUNC_ATTRIBUTE);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "name".
- */
- /*
- * TODO: Precompile the AVT. See bug #344894.
- */
- comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"name",
- NULL, &comp->has_name);
- if (! comp->has_name) {
- xsltTransformError(NULL, style, inst,
- "XSLT-attribute: The attribute 'name' is missing.\n");
- style->errors++;
- return;
- }
- /*
- * Attribute "namespace".
- */
- /*
- * TODO: Precompile the AVT. See bug #344894.
- */
- comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"namespace",
- NULL, &comp->has_ns);
- if (comp->name != NULL) {
- if (xmlValidateQName(comp->name, 0)) {
- xsltTransformError(NULL, style, inst,
- "xsl:attribute: The value '%s' of the attribute 'name' is "
- "not a valid QName.\n", comp->name);
- style->errors++;
- } else if (xmlStrEqual(comp->name, BAD_CAST "xmlns")) {
- xsltTransformError(NULL, style, inst,
- "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
- style->errors++;
- } else {
- const xmlChar *prefix = NULL, *name;
- name = xsltSplitQName(style->dict, comp->name, &prefix);
- if (prefix != NULL) {
- if (comp->has_ns == 0) {
- xmlNsPtr ns;
- /*
- * SPEC XSLT 1.0:
- * "If the namespace attribute is not present, then the
- * QName is expanded into an expanded-name using the
- * namespace declarations in effect for the xsl:element
- * element, including any default namespace declaration.
- */
- ns = xmlSearchNs(inst->doc, inst, prefix);
- if (ns != NULL) {
- comp->ns = xmlDictLookup(style->dict, ns->href, -1);
- comp->has_ns = 1;
- #ifdef XSLT_REFACTORED
- comp->nsPrefix = prefix;
- comp->name = name;
- #else
- (void)name; /* Suppress unused variable warning. */
- #endif
- } else {
- xsltTransformError(NULL, style, inst,
- "xsl:attribute: The prefixed QName '%s' "
- "has no namespace binding in scope in the "
- "stylesheet; this is an error, since the "
- "namespace was not specified by the instruction "
- "itself.\n", comp->name);
- style->errors++;
- }
- }
- }
- }
- }
- }
- /**
- * xsltCommentComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt comment node
- *
- * Process the xslt comment node on the source node
- */
- static void
- xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemCommentPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemCommentPtr) xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- }
- /**
- * xsltProcessingInstructionComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt processing-instruction node
- *
- * Process the xslt processing-instruction node on the source node
- */
- static void
- xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemPIPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemPIPtr) xsltNewStylePreComp(style, XSLT_FUNC_PI);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
- (const xmlChar *)"name",
- XSLT_NAMESPACE, &comp->has_name);
- }
- /**
- * xsltCopyOfComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt copy-of node
- *
- * Process the xslt copy-of node on the source node
- */
- static void
- xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemCopyOfPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemCopyOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:copy-of : select is missing\n");
- if (style != NULL) style->errors++;
- return;
- }
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:copy-of : could not compile select expression '%s'\n",
- comp->select);
- if (style != NULL) style->errors++;
- }
- }
- /**
- * xsltValueOfComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt value-of node
- *
- * Process the xslt value-of node on the source node
- */
- static void
- xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemValueOfPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- const xmlChar *prop;
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemValueOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- prop = xsltGetCNsProp(style, inst,
- (const xmlChar *)"disable-output-escaping",
- XSLT_NAMESPACE);
- if (prop != NULL) {
- if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
- comp->noescape = 1;
- } else if (!xmlStrEqual(prop,
- (const xmlChar *)"no")){
- xsltTransformError(NULL, style, inst,
- "xsl:value-of : disable-output-escaping allows only yes or no\n");
- if (style != NULL) style->warnings++;
- }
- }
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:value-of : select is missing\n");
- if (style != NULL) style->errors++;
- return;
- }
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:value-of : could not compile select expression '%s'\n",
- comp->select);
- if (style != NULL) style->errors++;
- }
- }
- static void
- xsltGetQNameProperty(xsltStylesheetPtr style, xmlNodePtr inst,
- const xmlChar *propName,
- int mandatory,
- int *hasProp, const xmlChar **nsName,
- const xmlChar** localName)
- {
- const xmlChar *prop;
- if (nsName)
- *nsName = NULL;
- if (localName)
- *localName = NULL;
- if (hasProp)
- *hasProp = 0;
- prop = xsltGetCNsProp(style, inst, propName, XSLT_NAMESPACE);
- if (prop == NULL) {
- if (mandatory) {
- xsltTransformError(NULL, style, inst,
- "The attribute '%s' is missing.\n", propName);
- style->errors++;
- return;
- }
- } else {
- const xmlChar *URI;
- if (xmlValidateQName(prop, 0)) {
- xsltTransformError(NULL, style, inst,
- "The value '%s' of the attribute "
- "'%s' is not a valid QName.\n", prop, propName);
- style->errors++;
- return;
- } else {
- /*
- * @prop will be in the string dict afterwards, @URI not.
- */
- URI = xsltGetQNameURI2(style, inst, &prop);
- if (prop == NULL) {
- style->errors++;
- } else {
- if (localName)
- *localName = prop;
- if (hasProp)
- *hasProp = 1;
- if (URI != NULL) {
- /*
- * Fixes bug #308441: Put the ns-name in the dict
- * in order to pointer compare names during XPath's
- * variable lookup.
- */
- if (nsName)
- *nsName = xmlDictLookup(style->dict, URI, -1);
- /* comp->has_ns = 1; */
- }
- }
- }
- }
- return;
- }
- /**
- * xsltWithParamComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt with-param node
- *
- * Process the xslt with-param node on the source node
- * Allowed parents: xsl:call-template, xsl:apply-templates.
- * <xsl:with-param
- * name = qname
- * select = expression>
- * <!-- Content: template -->
- * </xsl:with-param>
- */
- static void
- xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemWithParamPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemWithParamPtr) xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "name".
- */
- xsltGetQNameProperty(style, inst, BAD_CAST "name",
- 1, &(comp->has_name), &(comp->ns), &(comp->name));
- if (comp->ns)
- comp->has_ns = 1;
- /*
- * Attribute "select".
- */
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select != NULL) {
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-with-param: Failed to compile select "
- "expression '%s'\n", comp->select);
- style->errors++;
- }
- if (inst->children != NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-with-param: The content should be empty since "
- "the attribute select is present.\n");
- style->warnings++;
- }
- }
- }
- /**
- * xsltNumberComp:
- * @style: an XSLT compiled stylesheet
- * @cur: the xslt number node
- *
- * Process the xslt number node on the source node
- */
- static void
- xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemNumberPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- const xmlChar *prop;
- if ((style == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemNumberPtr) xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
- #endif
- if (comp == NULL)
- return;
- cur->psvi = comp;
- comp->numdata.doc = cur->doc;
- comp->numdata.node = cur;
- comp->numdata.value = xsltGetCNsProp(style, cur, (const xmlChar *)"value",
- XSLT_NAMESPACE);
- prop = xsltEvalStaticAttrValueTemplate(style, cur,
- (const xmlChar *)"format",
- XSLT_NAMESPACE, &comp->numdata.has_format);
- if (comp->numdata.has_format == 0) {
- comp->numdata.format = xmlDictLookup(style->dict, BAD_CAST "" , 0);
- } else {
- comp->numdata.format = prop;
- }
- comp->numdata.count = xsltGetCNsProp(style, cur, (const xmlChar *)"count",
- XSLT_NAMESPACE);
- comp->numdata.from = xsltGetCNsProp(style, cur, (const xmlChar *)"from",
- XSLT_NAMESPACE);
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"count", XSLT_NAMESPACE);
- if (prop != NULL) {
- comp->numdata.countPat = xsltCompilePattern(prop, cur->doc, cur, style,
- NULL);
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"from", XSLT_NAMESPACE);
- if (prop != NULL) {
- comp->numdata.fromPat = xsltCompilePattern(prop, cur->doc, cur, style,
- NULL);
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"level", XSLT_NAMESPACE);
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST("single")) ||
- xmlStrEqual(prop, BAD_CAST("multiple")) ||
- xmlStrEqual(prop, BAD_CAST("any"))) {
- comp->numdata.level = prop;
- } else {
- xsltTransformError(NULL, style, cur,
- "xsl:number : invalid value %s for level\n", prop);
- if (style != NULL) style->warnings++;
- }
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
- if (prop != NULL) {
- xsltTransformError(NULL, style, cur,
- "xsl:number : lang attribute not implemented\n");
- XSLT_TODO; /* xsl:number lang attribute */
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) {
- xsltTransformError(NULL, style, cur,
- "xsl:number : letter-value 'alphabetic' not implemented\n");
- if (style != NULL) style->warnings++;
- XSLT_TODO; /* xsl:number letter-value attribute alphabetic */
- } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) {
- xsltTransformError(NULL, style, cur,
- "xsl:number : letter-value 'traditional' not implemented\n");
- if (style != NULL) style->warnings++;
- XSLT_TODO; /* xsl:number letter-value attribute traditional */
- } else {
- xsltTransformError(NULL, style, cur,
- "xsl:number : invalid value %s for letter-value\n", prop);
- if (style != NULL) style->warnings++;
- }
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-separator",
- XSLT_NAMESPACE);
- if (prop != NULL) {
- comp->numdata.groupingCharacterLen = xmlStrlen(prop);
- comp->numdata.groupingCharacter =
- xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
- if (comp->numdata.groupingCharacter < 0)
- comp->numdata.groupingCharacter = 0;
- }
- prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
- if (prop != NULL) {
- sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup);
- } else {
- comp->numdata.groupingCharacter = 0;
- }
- /* Set default values */
- if (comp->numdata.value == NULL) {
- if (comp->numdata.level == NULL) {
- comp->numdata.level = xmlDictLookup(style->dict,
- BAD_CAST"single", 6);
- }
- }
- }
- /**
- * xsltApplyImportsComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt apply-imports node
- *
- * Process the xslt apply-imports node on the source node
- */
- static void
- xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemApplyImportsPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemApplyImportsPtr) xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- }
- /**
- * xsltCallTemplateComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt call-template node
- *
- * Process the xslt call-template node on the source node
- */
- static void
- xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemCallTemplatePtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemCallTemplatePtr)
- xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "name".
- */
- xsltGetQNameProperty(style, inst, BAD_CAST "name",
- 1, &(comp->has_name), &(comp->ns), &(comp->name));
- if (comp->ns)
- comp->has_ns = 1;
- }
- /**
- * xsltApplyTemplatesComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the apply-templates node
- *
- * Process the apply-templates node on the source node
- */
- static void
- xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemApplyTemplatesPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemApplyTemplatesPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "mode".
- */
- xsltGetQNameProperty(style, inst, BAD_CAST "mode",
- 0, NULL, &(comp->modeURI), &(comp->mode));
- /*
- * Attribute "select".
- */
- comp->select = xsltGetCNsProp(style, inst, BAD_CAST "select",
- XSLT_NAMESPACE);
- if (comp->select != NULL) {
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-apply-templates: could not compile select "
- "expression '%s'\n", comp->select);
- style->errors++;
- }
- }
- /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
- }
- /**
- * xsltChooseComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt choose node
- *
- * Process the xslt choose node on the source node
- */
- static void
- xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemChoosePtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemChoosePtr)
- xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- }
- /**
- * xsltIfComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt if node
- *
- * Process the xslt if node on the source node
- */
- static void
- xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemIfPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemIfPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_IF);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
- if (comp->test == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:if : test is not defined\n");
- if (style != NULL) style->errors++;
- return;
- }
- comp->comp = xsltXPathCompile(style, comp->test);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:if : could not compile test expression '%s'\n",
- comp->test);
- if (style != NULL) style->errors++;
- }
- }
- /**
- * xsltWhenComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt if node
- *
- * Process the xslt if node on the source node
- */
- static void
- xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemWhenPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemWhenPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
- if (comp->test == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:when : test is not defined\n");
- if (style != NULL) style->errors++;
- return;
- }
- comp->comp = xsltXPathCompile(style, comp->test);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:when : could not compile test expression '%s'\n",
- comp->test);
- if (style != NULL) style->errors++;
- }
- }
- /**
- * xsltForEachComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt for-each node
- *
- * Process the xslt for-each node on the source node
- */
- static void
- xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemForEachPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemForEachPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:for-each : select is missing\n");
- if (style != NULL) style->errors++;
- } else {
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "xsl:for-each : could not compile select expression '%s'\n",
- comp->select);
- if (style != NULL) style->errors++;
- }
- }
- /* TODO: handle and skip the xsl:sort */
- }
- /**
- * xsltVariableComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt variable node
- *
- * Process the xslt variable node on the source node
- */
- static void
- xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemVariablePtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemVariablePtr)
- xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * The full template resolution can be done statically
- */
- /*
- * Attribute "name".
- */
- xsltGetQNameProperty(style, inst, BAD_CAST "name",
- 1, &(comp->has_name), &(comp->ns), &(comp->name));
- if (comp->ns)
- comp->has_ns = 1;
- /*
- * Attribute "select".
- */
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select != NULL) {
- #ifndef XSLT_REFACTORED
- xmlNodePtr cur;
- #endif
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
- comp->select);
- style->errors++;
- }
- #ifdef XSLT_REFACTORED
- if (inst->children != NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-variable: There must be no child nodes, since the "
- "attribute 'select' was specified.\n");
- style->errors++;
- }
- #else
- for (cur = inst->children; cur != NULL; cur = cur->next) {
- if (cur->type != XML_COMMENT_NODE &&
- (cur->type != XML_TEXT_NODE || !xsltIsBlank(cur->content)))
- {
- xsltTransformError(NULL, style, inst,
- "XSLT-variable: There must be no child nodes, since the "
- "attribute 'select' was specified.\n");
- style->errors++;
- }
- }
- #endif
- }
- }
- /**
- * xsltParamComp:
- * @style: an XSLT compiled stylesheet
- * @inst: the xslt param node
- *
- * Process the xslt param node on the source node
- */
- static void
- xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
- #ifdef XSLT_REFACTORED
- xsltStyleItemParamPtr comp;
- #else
- xsltStylePreCompPtr comp;
- #endif
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
- return;
- #ifdef XSLT_REFACTORED
- comp = (xsltStyleItemParamPtr)
- xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
- #else
- comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
- #endif
- if (comp == NULL)
- return;
- inst->psvi = comp;
- comp->inst = inst;
- /*
- * Attribute "name".
- */
- xsltGetQNameProperty(style, inst, BAD_CAST "name",
- 1, &(comp->has_name), &(comp->ns), &(comp->name));
- if (comp->ns)
- comp->has_ns = 1;
- /*
- * Attribute "select".
- */
- comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
- XSLT_NAMESPACE);
- if (comp->select != NULL) {
- comp->comp = xsltXPathCompile(style, comp->select);
- if (comp->comp == NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-param: could not compile select expression '%s'.\n",
- comp->select);
- style->errors++;
- }
- if (inst->children != NULL) {
- xsltTransformError(NULL, style, inst,
- "XSLT-param: The content should be empty since the "
- "attribute 'select' is present.\n");
- style->warnings++;
- }
- }
- }
- /************************************************************************
- * *
- * Generic interface *
- * *
- ************************************************************************/
- /**
- * xsltFreeStylePreComps:
- * @style: an XSLT transformation context
- *
- * Free up the memory allocated by all precomputed blocks
- */
- void
- xsltFreeStylePreComps(xsltStylesheetPtr style) {
- xsltElemPreCompPtr cur, next;
- if (style == NULL)
- return;
- cur = style->preComps;
- while (cur != NULL) {
- next = cur->next;
- if (cur->type == XSLT_FUNC_EXTENSION)
- cur->free(cur);
- else
- xsltFreeStylePreComp((xsltStylePreCompPtr) cur);
- cur = next;
- }
- }
- #ifdef XSLT_REFACTORED
- /**
- * xsltStylePreCompute:
- * @style: the XSLT stylesheet
- * @node: the element in the XSLT namespace
- *
- * Precompute an XSLT element.
- * This expects the type of the element to be already
- * set in style->compCtxt->inode->type;
- */
- void
- xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr node) {
- /*
- * The xsltXSLTElemMarker marker was set beforehand by
- * the parsing mechanism for all elements in the XSLT namespace.
- */
- if (style == NULL) {
- if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
- node->psvi = NULL;
- return;
- }
- if (node == NULL)
- return;
- if (! IS_XSLT_ELEM_FAST(node))
- return;
- node->psvi = NULL;
- if (XSLT_CCTXT(style)->inode->type != 0) {
- switch (XSLT_CCTXT(style)->inode->type) {
- case XSLT_FUNC_APPLYTEMPLATES:
- xsltApplyTemplatesComp(style, node);
- break;
- case XSLT_FUNC_WITHPARAM:
- xsltWithParamComp(style, node);
- break;
- case XSLT_FUNC_VALUEOF:
- xsltValueOfComp(style, node);
- break;
- case XSLT_FUNC_COPY:
- xsltCopyComp(style, node);
- break;
- case XSLT_FUNC_COPYOF:
- xsltCopyOfComp(style, node);
- break;
- case XSLT_FUNC_IF:
- xsltIfComp(style, node);
- break;
- case XSLT_FUNC_CHOOSE:
- xsltChooseComp(style, node);
- break;
- case XSLT_FUNC_WHEN:
- xsltWhenComp(style, node);
- break;
- case XSLT_FUNC_OTHERWISE:
- /* NOP yet */
- return;
- case XSLT_FUNC_FOREACH:
- xsltForEachComp(style, node);
- break;
- case XSLT_FUNC_APPLYIMPORTS:
- xsltApplyImportsComp(style, node);
- break;
- case XSLT_FUNC_ATTRIBUTE:
- xsltAttributeComp(style, node);
- break;
- case XSLT_FUNC_ELEMENT:
- xsltElementComp(style, node);
- break;
- case XSLT_FUNC_SORT:
- xsltSortComp(style, node);
- break;
- case XSLT_FUNC_COMMENT:
- xsltCommentComp(style, node);
- break;
- case XSLT_FUNC_NUMBER:
- xsltNumberComp(style, node);
- break;
- case XSLT_FUNC_PI:
- xsltProcessingInstructionComp(style, node);
- break;
- case XSLT_FUNC_CALLTEMPLATE:
- xsltCallTemplateComp(style, node);
- break;
- case XSLT_FUNC_PARAM:
- xsltParamComp(style, node);
- break;
- case XSLT_FUNC_VARIABLE:
- xsltVariableComp(style, node);
- break;
- case XSLT_FUNC_FALLBACK:
- /* NOP yet */
- return;
- case XSLT_FUNC_DOCUMENT:
- /* The extra one */
- node->psvi = (void *) xsltDocumentComp(style, node,
- xsltDocumentElem);
- break;
- case XSLT_FUNC_MESSAGE:
- /* NOP yet */
- return;
- default:
- /*
- * NOTE that xsl:text, xsl:template, xsl:stylesheet,
- * xsl:transform, xsl:import, xsl:include are not expected
- * to be handed over to this function.
- */
- xsltTransformError(NULL, style, node,
- "Internal error: (xsltStylePreCompute) cannot handle "
- "the XSLT element '%s'.\n", node->name);
- style->errors++;
- return;
- }
- } else {
- /*
- * Fallback to string comparison.
- */
- if (IS_XSLT_NAME(node, "apply-templates")) {
- xsltApplyTemplatesComp(style, node);
- } else if (IS_XSLT_NAME(node, "with-param")) {
- xsltWithParamComp(style, node);
- } else if (IS_XSLT_NAME(node, "value-of")) {
- xsltValueOfComp(style, node);
- } else if (IS_XSLT_NAME(node, "copy")) {
- xsltCopyComp(style, node);
- } else if (IS_XSLT_NAME(node, "copy-of")) {
- xsltCopyOfComp(style, node);
- } else if (IS_XSLT_NAME(node, "if")) {
- xsltIfComp(style, node);
- } else if (IS_XSLT_NAME(node, "choose")) {
- xsltChooseComp(style, node);
- } else if (IS_XSLT_NAME(node, "when")) {
- xsltWhenComp(style, node);
- } else if (IS_XSLT_NAME(node, "otherwise")) {
- /* NOP yet */
- return;
- } else if (IS_XSLT_NAME(node, "for-each")) {
- xsltForEachComp(style, node);
- } else if (IS_XSLT_NAME(node, "apply-imports")) {
- xsltApplyImportsComp(style, node);
- } else if (IS_XSLT_NAME(node, "attribute")) {
- xsltAttributeComp(style, node);
- } else if (IS_XSLT_NAME(node, "element")) {
- xsltElementComp(style, node);
- } else if (IS_XSLT_NAME(node, "sort")) {
- xsltSortComp(style, node);
- } else if (IS_XSLT_NAME(node, "comment")) {
- xsltCommentComp(style, node);
- } else if (IS_XSLT_NAME(node, "number")) {
- xsltNumberComp(style, node);
- } else if (IS_XSLT_NAME(node, "processing-instruction")) {
- xsltProcessingInstructionComp(style, node);
- } else if (IS_XSLT_NAME(node, "call-template")) {
- xsltCallTemplateComp(style, node);
- } else if (IS_XSLT_NAME(node, "param")) {
- xsltParamComp(style, node);
- } else if (IS_XSLT_NAME(node, "variable")) {
- xsltVariableComp(style, node);
- } else if (IS_XSLT_NAME(node, "fallback")) {
- /* NOP yet */
- return;
- } else if (IS_XSLT_NAME(node, "document")) {
- /* The extra one */
- node->psvi = (void *) xsltDocumentComp(style, node,
- xsltDocumentElem);
- } else if (IS_XSLT_NAME(node, "output")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "preserve-space")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "strip-space")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "key")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "message")) {
- return;
- } else if (IS_XSLT_NAME(node, "attribute-set")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "namespace-alias")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "decimal-format")) {
- /* Top-level */
- return;
- } else if (IS_XSLT_NAME(node, "include")) {
- /* Top-level */
- } else {
- /*
- * NOTE that xsl:text, xsl:template, xsl:stylesheet,
- * xsl:transform, xsl:import, xsl:include are not expected
- * to be handed over to this function.
- */
- xsltTransformError(NULL, style, node,
- "Internal error: (xsltStylePreCompute) cannot handle "
- "the XSLT element '%s'.\n", node->name);
- style->errors++;
- return;
- }
- }
- /*
- * Assign the current list of in-scope namespaces to the
- * item. This is needed for XPath expressions.
- */
- if (node->psvi != NULL) {
- ((xsltStylePreCompPtr) node->psvi)->inScopeNs =
- XSLT_CCTXT(style)->inode->inScopeNs;
- }
- }
- #else
- /**
- * xsltStylePreCompute:
- * @style: the XSLT stylesheet
- * @inst: the instruction in the stylesheet
- *
- * Precompute an XSLT stylesheet element
- */
- void
- xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
- /*
- * URGENT TODO: Normally inst->psvi Should never be reserved here,
- * BUT: since if we include the same stylesheet from
- * multiple imports, then the stylesheet will be parsed
- * again. We simply must not try to compute the stylesheet again.
- * TODO: Get to the point where we don't need to query the
- * namespace- and local-name of the node, but can evaluate this
- * using cctxt->style->inode->category;
- */
- if ((inst == NULL) || (inst->type != XML_ELEMENT_NODE) ||
- (inst->psvi != NULL))
- return;
- if (IS_XSLT_ELEM(inst)) {
- xsltStylePreCompPtr cur;
- if (IS_XSLT_NAME(inst, "apply-templates")) {
- xsltCheckInstructionElement(style, inst);
- xsltApplyTemplatesComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "with-param")) {
- xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
- BAD_CAST "call-template");
- xsltWithParamComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "value-of")) {
- xsltCheckInstructionElement(style, inst);
- xsltValueOfComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "copy")) {
- xsltCheckInstructionElement(style, inst);
- xsltCopyComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "copy-of")) {
- xsltCheckInstructionElement(style, inst);
- xsltCopyOfComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "if")) {
- xsltCheckInstructionElement(style, inst);
- xsltIfComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "when")) {
- xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
- xsltWhenComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "choose")) {
- xsltCheckInstructionElement(style, inst);
- xsltChooseComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "for-each")) {
- xsltCheckInstructionElement(style, inst);
- xsltForEachComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "apply-imports")) {
- xsltCheckInstructionElement(style, inst);
- xsltApplyImportsComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "attribute")) {
- xmlNodePtr parent = inst->parent;
- if ((parent == NULL) ||
- (parent->type != XML_ELEMENT_NODE) || (parent->ns == NULL) ||
- ((parent->ns != inst->ns) &&
- (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
- (!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) {
- xsltCheckInstructionElement(style, inst);
- }
- xsltAttributeComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "element")) {
- xsltCheckInstructionElement(style, inst);
- xsltElementComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "text")) {
- xsltCheckInstructionElement(style, inst);
- xsltTextComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "sort")) {
- xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
- BAD_CAST "for-each");
- xsltSortComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "comment")) {
- xsltCheckInstructionElement(style, inst);
- xsltCommentComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "number")) {
- xsltCheckInstructionElement(style, inst);
- xsltNumberComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "processing-instruction")) {
- xsltCheckInstructionElement(style, inst);
- xsltProcessingInstructionComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "call-template")) {
- xsltCheckInstructionElement(style, inst);
- xsltCallTemplateComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "param")) {
- if (xsltCheckTopLevelElement(style, inst, 0) == 0)
- xsltCheckInstructionElement(style, inst);
- xsltParamComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "variable")) {
- if (xsltCheckTopLevelElement(style, inst, 0) == 0)
- xsltCheckInstructionElement(style, inst);
- xsltVariableComp(style, inst);
- } else if (IS_XSLT_NAME(inst, "otherwise")) {
- xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
- xsltCheckInstructionElement(style, inst);
- return;
- } else if (IS_XSLT_NAME(inst, "template")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "output")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "preserve-space")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "strip-space")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if ((IS_XSLT_NAME(inst, "stylesheet")) ||
- (IS_XSLT_NAME(inst, "transform"))) {
- xmlNodePtr parent = inst->parent;
- if ((parent == NULL) || (parent->type != XML_DOCUMENT_NODE)) {
- xsltTransformError(NULL, style, inst,
- "element %s only allowed only as root element\n",
- inst->name);
- style->errors++;
- }
- return;
- } else if (IS_XSLT_NAME(inst, "key")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "message")) {
- xsltCheckInstructionElement(style, inst);
- return;
- } else if (IS_XSLT_NAME(inst, "attribute-set")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "namespace-alias")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "include")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "import")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "decimal-format")) {
- xsltCheckTopLevelElement(style, inst, 1);
- return;
- } else if (IS_XSLT_NAME(inst, "fallback")) {
- xsltCheckInstructionElement(style, inst);
- return;
- } else if (IS_XSLT_NAME(inst, "document")) {
- xsltCheckInstructionElement(style, inst);
- inst->psvi = (void *) xsltDocumentComp(style, inst,
- xsltDocumentElem);
- } else if ((style == NULL) || (style->forwards_compatible == 0)) {
- xsltTransformError(NULL, style, inst,
- "xsltStylePreCompute: unknown xsl:%s\n", inst->name);
- if (style != NULL) style->warnings++;
- }
- cur = (xsltStylePreCompPtr) inst->psvi;
- /*
- * A ns-list is build for every XSLT item in the
- * node-tree. This is needed for XPath expressions.
- */
- if (cur != NULL) {
- int i = 0;
- cur->nsList = xmlGetNsList(inst->doc, inst);
- if (cur->nsList != NULL) {
- while (cur->nsList[i] != NULL)
- i++;
- }
- cur->nsNr = i;
- }
- } else {
- inst->psvi =
- (void *) xsltPreComputeExtModuleElement(style, inst);
- /*
- * Unknown element, maybe registered at the context
- * level. Mark it for later recognition.
- */
- if (inst->psvi == NULL)
- inst->psvi = (void *) xsltExtMarker;
- }
- }
- #endif /* XSLT_REFACTORED */
|