1 /* 2 * extra.c: Implementation of non-standard features 3 * 4 * Reference: 5 * Michael Kay "XSLT Programmer's Reference" pp 637-643 6 * The node-set() extension function 7 * 8 * See Copyright for the status of this software. 9 * 10 * daniel@veillard.com 11 */ 12 13 #include "precomp.h" 14 15 #ifdef WITH_XSLT_DEBUG 16 #define WITH_XSLT_DEBUG_EXTRA 17 #endif 18 19 /************************************************************************ 20 * * 21 * Handling of XSLT debugging * 22 * * 23 ************************************************************************/ 24 25 /** 26 * xsltDebug: 27 * @ctxt: an XSLT processing context 28 * @node: The current node 29 * @inst: the instruction in the stylesheet 30 * @comp: precomputed information 31 * 32 * Process an debug node 33 */ 34 void 35 xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, 36 xmlNodePtr inst ATTRIBUTE_UNUSED, 37 xsltElemPreCompPtr comp ATTRIBUTE_UNUSED) 38 { 39 int i, j; 40 41 xsltGenericError(xsltGenericErrorContext, "Templates:\n"); 42 for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) { 43 xsltGenericError(xsltGenericErrorContext, "#%d ", i); 44 if (ctxt->templTab[j]->name != NULL) 45 xsltGenericError(xsltGenericErrorContext, "name %s ", 46 ctxt->templTab[j]->name); 47 if (ctxt->templTab[j]->match != NULL) 48 xsltGenericError(xsltGenericErrorContext, "name %s ", 49 ctxt->templTab[j]->match); 50 if (ctxt->templTab[j]->mode != NULL) 51 xsltGenericError(xsltGenericErrorContext, "name %s ", 52 ctxt->templTab[j]->mode); 53 xsltGenericError(xsltGenericErrorContext, "\n"); 54 } 55 xsltGenericError(xsltGenericErrorContext, "Variables:\n"); 56 for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) { 57 xsltStackElemPtr cur; 58 59 if (ctxt->varsTab[j] == NULL) 60 continue; 61 xsltGenericError(xsltGenericErrorContext, "#%d\n", i); 62 cur = ctxt->varsTab[j]; 63 while (cur != NULL) { 64 if (cur->comp == NULL) { 65 xsltGenericError(xsltGenericErrorContext, 66 "corrupted !!!\n"); 67 } else if (cur->comp->type == XSLT_FUNC_PARAM) { 68 xsltGenericError(xsltGenericErrorContext, "param "); 69 } else if (cur->comp->type == XSLT_FUNC_VARIABLE) { 70 xsltGenericError(xsltGenericErrorContext, "var "); 71 } 72 if (cur->name != NULL) 73 xsltGenericError(xsltGenericErrorContext, "%s ", 74 cur->name); 75 else 76 xsltGenericError(xsltGenericErrorContext, "noname !!!!"); 77 #ifdef LIBXML_DEBUG_ENABLED 78 if (cur->value != NULL) { 79 if ((xsltGenericDebugContext == stdout) || 80 (xsltGenericDebugContext == stderr)) 81 xmlXPathDebugDumpObject((FILE*)xsltGenericDebugContext, 82 cur->value, 1); 83 } else { 84 xsltGenericError(xsltGenericErrorContext, "NULL !!!!"); 85 } 86 #endif 87 xsltGenericError(xsltGenericErrorContext, "\n"); 88 cur = cur->next; 89 } 90 91 } 92 } 93 94 /************************************************************************ 95 * * 96 * Classic extensions as described by M. Kay * 97 * * 98 ************************************************************************/ 99 100 /** 101 * xsltFunctionNodeSet: 102 * @ctxt: the XPath Parser context 103 * @nargs: the number of arguments 104 * 105 * Implement the node-set() XSLT function 106 * node-set node-set(result-tree) 107 * 108 * This function is available in libxslt, saxon or xt namespace. 109 */ 110 void 111 xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){ 112 if (nargs != 1) { 113 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 114 "node-set() : expects one result-tree arg\n"); 115 ctxt->error = XPATH_INVALID_ARITY; 116 return; 117 } 118 if ((ctxt->value == NULL) || 119 ((ctxt->value->type != XPATH_XSLT_TREE) && 120 (ctxt->value->type != XPATH_NODESET))) { 121 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 122 "node-set() invalid arg expecting a result tree\n"); 123 ctxt->error = XPATH_INVALID_TYPE; 124 return; 125 } 126 if (ctxt->value->type == XPATH_XSLT_TREE) { 127 ctxt->value->type = XPATH_NODESET; 128 } 129 } 130 131 /** 132 * xsltRegisterExtras: 133 * @ctxt: a XSLT process context 134 * 135 * Registers the built-in extensions. This function is deprecated, use 136 * xsltRegisterAllExtras instead. 137 */ 138 void 139 xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) { 140 xsltRegisterAllExtras(); 141 } 142 143 /** 144 * xsltRegisterAllExtras: 145 * 146 * Registers the built-in extensions 147 */ 148 void 149 xsltRegisterAllExtras (void) { 150 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 151 XSLT_LIBXSLT_NAMESPACE, 152 xsltFunctionNodeSet); 153 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 154 XSLT_SAXON_NAMESPACE, 155 xsltFunctionNodeSet); 156 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 157 XSLT_XT_NAMESPACE, 158 xsltFunctionNodeSet); 159 xsltRegisterExtModuleElement((const xmlChar *) "debug", 160 XSLT_LIBXSLT_NAMESPACE, 161 NULL, 162 xsltDebug); 163 xsltRegisterExtModuleElement((const xmlChar *) "output", 164 XSLT_SAXON_NAMESPACE, 165 xsltDocumentComp, 166 xsltDocumentElem); 167 xsltRegisterExtModuleElement((const xmlChar *) "write", 168 XSLT_XALAN_NAMESPACE, 169 xsltDocumentComp, 170 xsltDocumentElem); 171 xsltRegisterExtModuleElement((const xmlChar *) "document", 172 XSLT_XT_NAMESPACE, 173 xsltDocumentComp, 174 xsltDocumentElem); 175 xsltRegisterExtModuleElement((const xmlChar *) "document", 176 XSLT_NAMESPACE, 177 xsltDocumentComp, 178 xsltDocumentElem); 179 } 180