OLD | NEW |
1 /* | 1 /* |
2 * namespaces.c: Implementation of the XSLT namespaces handling | 2 * namespaces.c: Implementation of the XSLT namespaces handling |
3 * | 3 * |
4 * Reference: | 4 * Reference: |
5 * http://www.w3.org/TR/1999/REC-xslt-19991116 | 5 * http://www.w3.org/TR/1999/REC-xslt-19991116 |
6 * | 6 * |
7 * See Copyright for the status of this software. | 7 * See Copyright for the status of this software. |
8 * | 8 * |
9 * daniel@veillard.com | 9 * daniel@veillard.com |
10 */ | 10 */ |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "xsltutils.h" | 48 #include "xsltutils.h" |
49 #include "namespaces.h" | 49 #include "namespaces.h" |
50 #include "imports.h" | 50 #include "imports.h" |
51 | 51 |
52 /************************************************************************ | 52 /************************************************************************ |
53 * * | 53 * * |
54 * Module interfaces * | 54 * Module interfaces * |
55 * * | 55 * * |
56 ************************************************************************/ | 56 ************************************************************************/ |
57 | 57 |
58 #ifdef XSLT_REFACTORED | 58 #ifdef XSLT_REFACTORED |
59 static xsltNsAliasPtr | 59 static xsltNsAliasPtr |
60 xsltNewNsAlias(xsltCompilerCtxtPtr cctxt) | 60 xsltNewNsAlias(xsltCompilerCtxtPtr cctxt) |
61 { | 61 { |
62 xsltNsAliasPtr ret; | 62 xsltNsAliasPtr ret; |
63 | 63 |
64 if (cctxt == NULL) | 64 if (cctxt == NULL) |
65 return(NULL); | 65 return(NULL); |
66 | 66 |
67 ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias)); | 67 ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias)); |
68 if (ret == NULL) { | 68 if (ret == NULL) { |
69 xsltTransformError(NULL, cctxt->style, NULL, | 69 xsltTransformError(NULL, cctxt->style, NULL, |
70 "Internal error in xsltNewNsAlias(): Memory allocation failed.\n"); | 70 "Internal error in xsltNewNsAlias(): Memory allocation failed.\n"); |
71 cctxt->style->errors++; | 71 cctxt->style->errors++; |
72 return(NULL); | 72 return(NULL); |
73 } | 73 } |
74 memset(ret, 0, sizeof(xsltNsAlias)); | 74 memset(ret, 0, sizeof(xsltNsAlias)); |
75 /* | 75 /* |
76 * TODO: Store the item at current stylesheet-level. | 76 * TODO: Store the item at current stylesheet-level. |
77 */ | 77 */ |
78 ret->next = cctxt->nsAliases; | 78 ret->next = cctxt->nsAliases; |
79 cctxt->nsAliases = ret; | 79 cctxt->nsAliases = ret; |
80 | 80 |
81 return(ret); | 81 return(ret); |
82 } | 82 } |
83 #endif /* XSLT_REFACTORED */ | 83 #endif /* XSLT_REFACTORED */ |
84 /** | 84 /** |
85 * xsltNamespaceAlias: | 85 * xsltNamespaceAlias: |
86 * @style: the XSLT stylesheet | 86 * @style: the XSLT stylesheet |
87 * @node: the xsl:namespace-alias node | 87 * @node: the xsl:namespace-alias node |
88 * | 88 * |
89 * Read the stylesheet-prefix and result-prefix attributes, register | 89 * Read the stylesheet-prefix and result-prefix attributes, register |
90 * them as well as the corresponding namespace. | 90 * them as well as the corresponding namespace. |
91 */ | 91 */ |
92 void | 92 void |
93 xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) | 93 xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) |
94 { | 94 { |
95 xmlChar *resultPrefix = NULL; | 95 xmlChar *resultPrefix = NULL; |
96 xmlChar *stylePrefix = NULL; | 96 xmlChar *stylePrefix = NULL; |
97 xmlNsPtr literalNs = NULL; | 97 xmlNsPtr literalNs = NULL; |
98 xmlNsPtr targetNs = NULL; | 98 xmlNsPtr targetNs = NULL; |
99 | 99 |
100 #ifdef XSLT_REFACTORED | 100 #ifdef XSLT_REFACTORED |
101 xsltNsAliasPtr alias; | 101 xsltNsAliasPtr alias; |
102 | 102 |
103 if ((style == NULL) || (node == NULL)) | 103 if ((style == NULL) || (node == NULL)) |
104 return; | 104 return; |
105 | 105 |
106 /* | 106 /* |
107 * SPEC XSLT 1.0: | 107 * SPEC XSLT 1.0: |
108 * "If a namespace URI is declared to be an alias for multiple | 108 * "If a namespace URI is declared to be an alias for multiple |
109 * different namespace URIs, then the declaration with the highest | 109 * different namespace URIs, then the declaration with the highest |
110 * import precedence is used. It is an error if there is more than | 110 * import precedence is used. It is an error if there is more than |
111 * one such declaration. An XSLT processor may signal the error; | 111 * one such declaration. An XSLT processor may signal the error; |
112 * if it does not signal the error, it must recover by choosing, | 112 * if it does not signal the error, it must recover by choosing, |
113 * from amongst the declarations with the highest import precedence, | 113 * from amongst the declarations with the highest import precedence, |
114 * the one that occurs last in the stylesheet." | 114 * the one that occurs last in the stylesheet." |
115 * | 115 * |
116 * SPEC TODO: Check for the errors mentioned above. | 116 * SPEC TODO: Check for the errors mentioned above. |
117 */ | 117 */ |
118 /* | 118 /* |
119 * NOTE that the XSLT 2.0 also *does* use the NULL namespace if | 119 * NOTE that the XSLT 2.0 also *does* use the NULL namespace if |
120 * "#default" is used and there's no default namespace is scope. | 120 * "#default" is used and there's no default namespace is scope. |
121 * I.e., this is *not* an error. | 121 * I.e., this is *not* an error. |
122 * Most XSLT 1.0 implementations work this way. | 122 * Most XSLT 1.0 implementations work this way. |
123 * The XSLT 1.0 spec has nothing to say on the subject. | 123 * The XSLT 1.0 spec has nothing to say on the subject. |
124 */ | 124 */ |
125 /* | 125 /* |
126 * Attribute "stylesheet-prefix". | 126 * Attribute "stylesheet-prefix". |
127 */ | 127 */ |
128 stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL)
; | 128 stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL)
; |
129 if (stylePrefix == NULL) { | 129 if (stylePrefix == NULL) { |
130 xsltTransformError(NULL, style, node, | 130 xsltTransformError(NULL, style, node, |
131 "The attribute 'stylesheet-prefix' is missing.\n"); | 131 "The attribute 'stylesheet-prefix' is missing.\n"); |
132 return; | 132 return; |
133 } | 133 } |
134 if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) | 134 if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) |
135 » literalNs = xmlSearchNs(node->doc, node, NULL);» | 135 » literalNs = xmlSearchNs(node->doc, node, NULL); |
136 else { | 136 else { |
137 literalNs = xmlSearchNs(node->doc, node, stylePrefix); | 137 literalNs = xmlSearchNs(node->doc, node, stylePrefix); |
138 if (literalNs == NULL) { | 138 if (literalNs == NULL) { |
139 xsltTransformError(NULL, style, node, | 139 xsltTransformError(NULL, style, node, |
140 "Attribute 'stylesheet-prefix': There's no namespace " | 140 "Attribute 'stylesheet-prefix': There's no namespace " |
141 "declaration in scope for the prefix '%s'.\n", | 141 "declaration in scope for the prefix '%s'.\n", |
142 stylePrefix); | 142 stylePrefix); |
143 goto error; | 143 goto error; |
144 } | 144 } |
145 } | 145 } |
146 /* | 146 /* |
147 * Attribute "result-prefix". | 147 * Attribute "result-prefix". |
148 */ | 148 */ |
149 resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); | 149 resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); |
150 if (resultPrefix == NULL) { | 150 if (resultPrefix == NULL) { |
151 xsltTransformError(NULL, style, node, | 151 xsltTransformError(NULL, style, node, |
152 "The attribute 'result-prefix' is missing.\n"); | 152 "The attribute 'result-prefix' is missing.\n"); |
153 goto error; | 153 goto error; |
154 } | 154 } |
155 if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) | 155 if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) |
156 targetNs = xmlSearchNs(node->doc, node, NULL); | 156 targetNs = xmlSearchNs(node->doc, node, NULL); |
157 else { | 157 else { |
158 targetNs = xmlSearchNs(node->doc, node, resultPrefix); | 158 targetNs = xmlSearchNs(node->doc, node, resultPrefix); |
159 | 159 |
160 if (targetNs == NULL) { | 160 if (targetNs == NULL) { |
161 xsltTransformError(NULL, style, node, | 161 xsltTransformError(NULL, style, node, |
162 "Attribute 'result-prefix': There's no namespace " | 162 "Attribute 'result-prefix': There's no namespace " |
163 "declaration in scope for the prefix '%s'.\n", | 163 "declaration in scope for the prefix '%s'.\n", |
164 stylePrefix); | 164 stylePrefix); |
(...skipping 25 matching lines...) Expand all Loading... |
190 * TODO: Has this an effect at all? | 190 * TODO: Has this an effect at all? |
191 * | 191 * |
192 * <xsl:namespace-alias stylesheet-prefix="foo" | 192 * <xsl:namespace-alias stylesheet-prefix="foo" |
193 * result-prefix="#default"/> | 193 * result-prefix="#default"/> |
194 * From namespace to no namespace. | 194 * From namespace to no namespace. |
195 * | 195 * |
196 * <xsl:namespace-alias stylesheet-prefix="#default" | 196 * <xsl:namespace-alias stylesheet-prefix="#default" |
197 * result-prefix="foo"/> | 197 * result-prefix="foo"/> |
198 * From no namespace to namespace. | 198 * From no namespace to namespace. |
199 */ | 199 */ |
200 | 200 |
201 » | 201 |
202 /* | 202 /* |
203 * Store the ns-node in the alias-object. | 203 * Store the ns-node in the alias-object. |
204 */ | 204 */ |
205 alias = xsltNewNsAlias(XSLT_CCTXT(style)); | 205 alias = xsltNewNsAlias(XSLT_CCTXT(style)); |
206 if (alias == NULL) | 206 if (alias == NULL) |
207 return; | 207 return; |
208 alias->literalNs = literalNs; | 208 alias->literalNs = literalNs; |
209 alias->targetNs = targetNs; | 209 alias->targetNs = targetNs; |
210 XSLT_CCTXT(style)->hasNsAliases = 1; | 210 XSLT_CCTXT(style)->hasNsAliases = 1; |
211 | 211 |
212 | 212 |
213 #else /* XSLT_REFACTORED */ | 213 #else /* XSLT_REFACTORED */ |
214 const xmlChar *literalNsName; | 214 const xmlChar *literalNsName; |
215 const xmlChar *targetNsName; | 215 const xmlChar *targetNsName; |
216 | 216 |
217 | 217 |
218 if ((style == NULL) || (node == NULL)) | 218 if ((style == NULL) || (node == NULL)) |
219 return; | 219 return; |
220 | 220 |
221 stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL)
; | 221 stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL)
; |
222 if (stylePrefix == NULL) { | 222 if (stylePrefix == NULL) { |
223 xsltTransformError(NULL, style, node, | 223 xsltTransformError(NULL, style, node, |
224 "namespace-alias: stylesheet-prefix attribute missing\n"); | 224 "namespace-alias: stylesheet-prefix attribute missing\n"); |
225 return; | 225 return; |
226 } | 226 } |
227 resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); | 227 resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); |
228 if (resultPrefix == NULL) { | 228 if (resultPrefix == NULL) { |
229 xsltTransformError(NULL, style, node, | 229 xsltTransformError(NULL, style, node, |
230 "namespace-alias: result-prefix attribute missing\n"); | 230 "namespace-alias: result-prefix attribute missing\n"); |
231 goto error; | 231 goto error; |
232 } | 232 } |
233 | 233 |
234 if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) { | 234 if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) { |
235 literalNs = xmlSearchNs(node->doc, node, NULL); | 235 literalNs = xmlSearchNs(node->doc, node, NULL); |
236 if (literalNs == NULL) { | 236 if (literalNs == NULL) { |
237 literalNsName = NULL; | 237 literalNsName = NULL; |
238 } else | 238 } else |
239 literalNsName = literalNs->href; /* Yes - set for nsAlias table */ | 239 literalNsName = literalNs->href; /* Yes - set for nsAlias table */ |
240 } else { | 240 } else { |
241 literalNs = xmlSearchNs(node->doc, node, stylePrefix); | 241 literalNs = xmlSearchNs(node->doc, node, stylePrefix); |
242 | 242 |
243 if ((literalNs == NULL) || (literalNs->href == NULL)) { | 243 if ((literalNs == NULL) || (literalNs->href == NULL)) { |
244 xsltTransformError(NULL, style, node, | 244 xsltTransformError(NULL, style, node, |
245 "namespace-alias: prefix %s not bound to any namespace\n", | 245 "namespace-alias: prefix %s not bound to any namespace\n", |
246 stylePrefix); | 246 stylePrefix); |
247 goto error; | 247 goto error; |
248 } else | 248 } else |
249 literalNsName = literalNs->href; | 249 literalNsName = literalNs->href; |
250 } | 250 } |
251 | 251 |
252 /* | 252 /* |
(...skipping 15 matching lines...) Expand all Loading... |
268 "namespace-alias: prefix %s not bound to any namespace\n", | 268 "namespace-alias: prefix %s not bound to any namespace\n", |
269 resultPrefix); | 269 resultPrefix); |
270 goto error; | 270 goto error; |
271 } else | 271 } else |
272 targetNsName = targetNs->href; | 272 targetNsName = targetNs->href; |
273 } | 273 } |
274 /* | 274 /* |
275 * Special case: if #default is used for | 275 * Special case: if #default is used for |
276 * the stylesheet-prefix (literal namespace) and there's no default | 276 * the stylesheet-prefix (literal namespace) and there's no default |
277 * namespace in scope, we'll use style->defaultAlias for this. | 277 * namespace in scope, we'll use style->defaultAlias for this. |
278 */ | 278 */ |
279 if (literalNsName == NULL) { | 279 if (literalNsName == NULL) { |
280 if (targetNs != NULL) { | 280 if (targetNs != NULL) { |
281 /* | 281 /* |
282 * BUG TODO: Is it not sufficient to have only 1 field for | 282 * BUG TODO: Is it not sufficient to have only 1 field for |
283 * this, since subsequently alias declarations will | 283 * this, since subsequently alias declarations will |
284 » * overwrite this.» | 284 » * overwrite this. |
285 * Example: | 285 * Example: |
286 * <xsl:namespace-alias result-prefix="foo" | 286 * <xsl:namespace-alias result-prefix="foo" |
287 * stylesheet-prefix="#default"/> | 287 * stylesheet-prefix="#default"/> |
288 * <xsl:namespace-alias result-prefix="bar" | 288 * <xsl:namespace-alias result-prefix="bar" |
289 * stylesheet-prefix="#default"/> | 289 * stylesheet-prefix="#default"/> |
290 * The mapping for "foo" won't be visible anymore. | 290 * The mapping for "foo" won't be visible anymore. |
291 */ | 291 */ |
292 style->defaultAlias = targetNs->href; | 292 style->defaultAlias = targetNs->href; |
293 } | 293 } |
294 } else { | 294 } else { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 * here (it was in the old code). | 351 * here (it was in the old code). |
352 * NOTE: @invocNode was named @cur in the old code and was documented to | 352 * NOTE: @invocNode was named @cur in the old code and was documented to |
353 * be an input node; since it was only used to anchor an error report | 353 * be an input node; since it was only used to anchor an error report |
354 * somewhere, we can safely change this to @invocNode, which now | 354 * somewhere, we can safely change this to @invocNode, which now |
355 * will be the XSLT instruction (also a literal result element/attribute), | 355 * will be the XSLT instruction (also a literal result element/attribute), |
356 * which was responsible for this call. | 356 * which was responsible for this call. |
357 */ | 357 */ |
358 /* | 358 /* |
359 * OPTIMIZE TODO: This all could be optimized by keeping track of | 359 * OPTIMIZE TODO: This all could be optimized by keeping track of |
360 * the ns-decls currently in-scope via a specialized context. | 360 * the ns-decls currently in-scope via a specialized context. |
361 */ | 361 */ |
362 if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) { | 362 if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) { |
363 /* | 363 /* |
364 * NOTE: the "undeclaration" of the default namespace was | 364 * NOTE: the "undeclaration" of the default namespace was |
365 * part of the logic of the old xsltGetSpecialNamespace() code, | 365 * part of the logic of the old xsltGetSpecialNamespace() code, |
366 * so we'll keep that mechanism. | 366 * so we'll keep that mechanism. |
367 * Related to the old code: bug #302020: | 367 * Related to the old code: bug #302020: |
368 */ | 368 */ |
369 /* | 369 /* |
370 * OPTIMIZE TODO: This all could be optimized by keeping track of | 370 * OPTIMIZE TODO: This all could be optimized by keeping track of |
371 * the ns-decls currently in-scope via a specialized context. | 371 * the ns-decls currently in-scope via a specialized context. |
(...skipping 19 matching lines...) Expand all Loading... |
391 /* | 391 /* |
392 * The default namespace was undeclared on the | 392 * The default namespace was undeclared on the |
393 * result element. | 393 * result element. |
394 */ | 394 */ |
395 return(NULL); | 395 return(NULL); |
396 } | 396 } |
397 break; | 397 break; |
398 } | 398 } |
399 ns = ns->next; | 399 ns = ns->next; |
400 } while (ns != NULL); | 400 } while (ns != NULL); |
401 » }» | 401 » } |
402 if ((target->parent != NULL) && | 402 if ((target->parent != NULL) && |
403 (target->parent->type == XML_ELEMENT_NODE)) | 403 (target->parent->type == XML_ELEMENT_NODE)) |
404 { | 404 { |
405 /* | 405 /* |
406 * The parent element is in no namespace, so assume | 406 * The parent element is in no namespace, so assume |
407 * that there is no default namespace in scope. | 407 * that there is no default namespace in scope. |
408 */ | 408 */ |
409 if (target->parent->ns == NULL) | 409 if (target->parent->ns == NULL) |
410 return(NULL); | 410 return(NULL); |
411 » | 411 |
412 ns = xmlSearchNs(target->doc, target->parent, | 412 ns = xmlSearchNs(target->doc, target->parent, |
413 NULL); | 413 NULL); |
414 /* | 414 /* |
415 * Fine if there's no default ns is scope, or if the | 415 * Fine if there's no default ns is scope, or if the |
416 * default ns was undeclared. | 416 * default ns was undeclared. |
417 */ | 417 */ |
418 if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0)) | 418 if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0)) |
419 return(NULL); | 419 return(NULL); |
420 » | 420 |
421 /* | 421 /* |
422 * Undeclare the default namespace. | 422 * Undeclare the default namespace. |
423 */ | 423 */ |
424 xmlNewNs(target, BAD_CAST "", NULL); | 424 xmlNewNs(target, BAD_CAST "", NULL); |
425 » /* TODO: Check result */» | 425 » /* TODO: Check result */ |
426 return(NULL); | 426 return(NULL); |
427 } | 427 } |
428 return(NULL); | 428 return(NULL); |
429 } | 429 } |
430 /* | 430 /* |
431 * Handle the XML namespace. | 431 * Handle the XML namespace. |
432 * QUESTION: Is this faster than using xmlStrEqual() anyway? | 432 * QUESTION: Is this faster than using xmlStrEqual() anyway? |
433 */ | 433 */ |
434 if ((nsPrefix != NULL) && | 434 if ((nsPrefix != NULL) && |
435 (nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') && | 435 (nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') && |
(...skipping 21 matching lines...) Expand all Loading... |
457 } | 457 } |
458 } | 458 } |
459 ns = ns->next; | 459 ns = ns->next; |
460 } while (ns != NULL); | 460 } while (ns != NULL); |
461 } | 461 } |
462 if (prefixOccupied) { | 462 if (prefixOccupied) { |
463 /* | 463 /* |
464 * If the ns-prefix is occupied by an other ns-decl on the | 464 * If the ns-prefix is occupied by an other ns-decl on the |
465 * result element, then this means: | 465 * result element, then this means: |
466 * 1) The desired prefix is shadowed | 466 * 1) The desired prefix is shadowed |
467 » * 2) There's no way around changing the prefix» | 467 » * 2) There's no way around changing the prefix |
468 * | 468 * |
469 * Try a desperate search for an in-scope ns-decl | 469 * Try a desperate search for an in-scope ns-decl |
470 * with a matching ns-name before we use the last option, | 470 * with a matching ns-name before we use the last option, |
471 * which is to recreate the ns-decl with a modified prefix. | 471 * which is to recreate the ns-decl with a modified prefix. |
472 */ | 472 */ |
473 ns = xmlSearchNsByHref(target->doc, target, nsName); | 473 ns = xmlSearchNsByHref(target->doc, target, nsName); |
474 if (ns != NULL) | 474 if (ns != NULL) |
475 return(ns); | 475 return(ns); |
476 | 476 |
477 /* | 477 /* |
478 * Fallback to changing the prefix. | 478 * Fallback to changing the prefix. |
479 » */ | 479 » */ |
480 } else if ((target->parent != NULL) && | 480 } else if ((target->parent != NULL) && |
481 (target->parent->type == XML_ELEMENT_NODE)) | 481 (target->parent->type == XML_ELEMENT_NODE)) |
482 { | 482 { |
483 /* | 483 /* |
484 * Try to find a matching ns-decl in the ancestor-axis. | 484 * Try to find a matching ns-decl in the ancestor-axis. |
485 * | 485 * |
486 * Check the common case: The parent element of the current | 486 * Check the common case: The parent element of the current |
487 * result element is in the same namespace (with an equal ns-prefix). | 487 * result element is in the same namespace (with an equal ns-prefix). |
488 » */ | 488 » */ |
489 if ((target->parent->ns != NULL) && | 489 if ((target->parent->ns != NULL) && |
490 ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL))) | 490 ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL))) |
491 { | 491 { |
492 ns = target->parent->ns; | 492 ns = target->parent->ns; |
493 » | 493 |
494 if (nsPrefix == NULL) { | 494 if (nsPrefix == NULL) { |
495 if (xmlStrEqual(ns->href, nsName)) | 495 if (xmlStrEqual(ns->href, nsName)) |
496 return(ns); | 496 return(ns); |
497 } else if (xmlStrEqual(ns->prefix, nsPrefix) && | 497 } else if (xmlStrEqual(ns->prefix, nsPrefix) && |
498 xmlStrEqual(ns->href, nsName)) | 498 xmlStrEqual(ns->href, nsName)) |
499 { | 499 { |
500 return(ns); | 500 return(ns); |
501 } | 501 } |
502 } | 502 } |
503 /* | 503 /* |
504 * Lookup the remaining in-scope namespaces. | 504 * Lookup the remaining in-scope namespaces. |
505 » */ | 505 » */ |
506 ns = xmlSearchNs(target->doc, target->parent, nsPrefix); | 506 ns = xmlSearchNs(target->doc, target->parent, nsPrefix); |
507 if (ns != NULL) { | 507 if (ns != NULL) { |
508 if (xmlStrEqual(ns->href, nsName)) | 508 if (xmlStrEqual(ns->href, nsName)) |
509 » » return(ns);» | 509 » » return(ns); |
510 /* | 510 /* |
511 * Now check for a nasty case: We need to ensure that the new | 511 * Now check for a nasty case: We need to ensure that the new |
512 * ns-decl won't shadow a prefix in-use by an existing attribute. | 512 * ns-decl won't shadow a prefix in-use by an existing attribute. |
513 * <foo xmlns:a="urn:test:a"> | 513 * <foo xmlns:a="urn:test:a"> |
514 * <bar a:a="val-a"> | 514 * <bar a:a="val-a"> |
515 * <xsl:attribute xmlns:a="urn:test:b" name="a:b"> | 515 * <xsl:attribute xmlns:a="urn:test:b" name="a:b"> |
516 * val-b</xsl:attribute> | 516 * val-b</xsl:attribute> |
517 * </bar> | 517 * </bar> |
518 * </foo> | 518 * </foo> |
519 */ | 519 */ |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 declare_new_prefix: | 578 declare_new_prefix: |
579 /* | 579 /* |
580 * Fallback: we need to generate a new prefix and declare the namespace | 580 * Fallback: we need to generate a new prefix and declare the namespace |
581 * on the result element. | 581 * on the result element. |
582 */ | 582 */ |
583 { | 583 { |
584 xmlChar pref[30]; | 584 xmlChar pref[30]; |
585 int counter = 1; | 585 int counter = 1; |
586 | 586 |
587 if (nsPrefix == NULL) { | 587 if (nsPrefix == NULL) { |
588 » nsPrefix = "ns"; | 588 » nsPrefix = BAD_CAST "ns"; |
589 } | 589 } |
590 | 590 |
591 do { | 591 do { |
592 snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++); | 592 snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++); |
593 ns = xmlSearchNs(target->doc, target, BAD_CAST pref); | 593 ns = xmlSearchNs(target->doc, target, BAD_CAST pref); |
594 if (counter > 1000) { | 594 if (counter > 1000) { |
595 xsltTransformError(ctxt, NULL, invocNode, | 595 xsltTransformError(ctxt, NULL, invocNode, |
596 "Internal error in xsltAcquireResultInScopeNs(): " | 596 "Internal error in xsltAcquireResultInScopeNs(): " |
597 "Failed to compute a unique ns-prefix for the " | 597 "Failed to compute a unique ns-prefix for the " |
598 "generated element"); | 598 "generated element"); |
(...skipping 27 matching lines...) Expand all Loading... |
626 * - xsltCopyTreeInternal() (*not* anymore) | 626 * - xsltCopyTreeInternal() (*not* anymore) |
627 * - xsltApplySequenceConstructor() (*not* in the refactored code), | 627 * - xsltApplySequenceConstructor() (*not* in the refactored code), |
628 * - xsltElement() (*not* anymore) | 628 * - xsltElement() (*not* anymore) |
629 * | 629 * |
630 * Returns a namespace declaration or NULL in case of | 630 * Returns a namespace declaration or NULL in case of |
631 * namespace fixup failures or API or internal errors. | 631 * namespace fixup failures or API or internal errors. |
632 */ | 632 */ |
633 xmlNsPtr | 633 xmlNsPtr |
634 xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, | 634 xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, |
635 xmlNodePtr out) | 635 xmlNodePtr out) |
636 { | 636 { |
637 | 637 |
638 if (ns == NULL) | 638 if (ns == NULL) |
639 return(NULL); | 639 return(NULL); |
640 | 640 |
641 #ifdef XSLT_REFACTORED | 641 #ifdef XSLT_REFACTORED |
642 /* | 642 /* |
643 * Namespace exclusion and ns-aliasing is performed at | 643 * Namespace exclusion and ns-aliasing is performed at |
644 * compilation-time in the refactored code. | 644 * compilation-time in the refactored code. |
645 * Additionally, aliasing is not intended for non Literal | 645 * Additionally, aliasing is not intended for non Literal |
646 * Result Elements. | 646 * Result Elements. |
647 */ | 647 */ |
648 return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out)); | 648 return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out)); |
649 #else | 649 #else |
650 { | 650 { |
651 xsltStylesheetPtr style; | 651 xsltStylesheetPtr style; |
652 const xmlChar *URI = NULL; /* the replacement URI */ | 652 const xmlChar *URI = NULL; /* the replacement URI */ |
653 | 653 |
654 if ((ctxt == NULL) || (cur == NULL) || (out == NULL)) | 654 if ((ctxt == NULL) || (cur == NULL) || (out == NULL)) |
655 return(NULL); | 655 return(NULL); |
656 | 656 |
657 style = ctxt->style; | 657 style = ctxt->style; |
658 while (style != NULL) { | 658 while (style != NULL) { |
659 if (style->nsAliases != NULL) | 659 if (style->nsAliases != NULL) |
660 » » URI = (const xmlChar *) | 660 » » URI = (const xmlChar *) |
661 xmlHashLookup(style->nsAliases, ns->href); | 661 xmlHashLookup(style->nsAliases, ns->href); |
662 if (URI != NULL) | 662 if (URI != NULL) |
663 break; | 663 break; |
664 » | 664 |
665 style = xsltNextImport(style); | 665 style = xsltNextImport(style); |
666 } | 666 } |
667 » | 667 |
668 » | 668 |
669 if (URI == UNDEFINED_DEFAULT_NS) { | 669 if (URI == UNDEFINED_DEFAULT_NS) { |
670 return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out)); | 670 return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out)); |
671 #if 0 | 671 #if 0 |
672 /* | 672 /* |
673 * TODO: Removed, since wrong. If there was no default | 673 * TODO: Removed, since wrong. If there was no default |
674 * namespace in the stylesheet then this must resolve to | 674 * namespace in the stylesheet then this must resolve to |
675 * the NULL namespace. | 675 * the NULL namespace. |
676 */ | 676 */ |
677 » xmlNsPtr dflt;» | 677 » xmlNsPtr dflt; |
678 dflt = xmlSearchNs(cur->doc, cur, NULL); | 678 dflt = xmlSearchNs(cur->doc, cur, NULL); |
679 if (dflt != NULL) | 679 if (dflt != NULL) |
680 URI = dflt->href; | 680 URI = dflt->href; |
681 else | 681 else |
682 return NULL; | 682 return NULL; |
683 #endif | 683 #endif |
684 } else if (URI == NULL) | 684 } else if (URI == NULL) |
685 URI = ns->href; | 685 URI = ns->href; |
686 | 686 |
687 return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out)); | 687 return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out)); |
688 } | 688 } |
689 #endif | 689 #endif |
690 } | 690 } |
691 | 691 |
692 /** | 692 /** |
693 * xsltGetPlainNamespace: | 693 * xsltGetPlainNamespace: |
694 * @ctxt: a transformation context | 694 * @ctxt: a transformation context |
695 * @cur: the input node | 695 * @cur: the input node |
696 * @ns: the namespace | 696 * @ns: the namespace |
697 * @out: the result element | 697 * @out: the result element |
698 * | 698 * |
699 * Obsolete. | 699 * Obsolete. |
700 * *Not* called by any Libxslt/Libexslt function. | 700 * *Not* called by any Libxslt/Libexslt function. |
701 * Exaclty the same as xsltGetNamespace(). | 701 * Exaclty the same as xsltGetNamespace(). |
702 * | 702 * |
703 * Returns a namespace declaration or NULL in case of | 703 * Returns a namespace declaration or NULL in case of |
704 * namespace fixup failures or API or internal errors. | 704 * namespace fixup failures or API or internal errors. |
705 */ | 705 */ |
706 xmlNsPtr | 706 xmlNsPtr |
707 xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, | 707 xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, |
708 xmlNsPtr ns, xmlNodePtr out) | 708 xmlNsPtr ns, xmlNodePtr out) |
709 { | 709 { |
710 return(xsltGetNamespace(ctxt, cur, ns, out)); | 710 return(xsltGetNamespace(ctxt, cur, ns, out)); |
711 } | 711 } |
712 | 712 |
713 /** | 713 /** |
714 * xsltCopyNamespaceList: | 714 * xsltCopyNamespaceList: |
715 * @ctxt: a transformation context | 715 * @ctxt: a transformation context |
716 * @node: the target node | 716 * @node: the target node |
717 * @cur: the first namespace | 717 * @cur: the first namespace |
718 * | 718 * |
719 * Do a copy of an namespace list. If @node is non-NULL the | 719 * Do a copy of an namespace list. If @node is non-NULL the |
720 * new namespaces are added automatically. This handles namespaces | 720 * new namespaces are added automatically. This handles namespaces |
721 * aliases. | 721 * aliases. |
722 * This function is intended only for *internal* use at | 722 * This function is intended only for *internal* use at |
723 * transformation-time for copying ns-declarations of Literal | 723 * transformation-time for copying ns-declarations of Literal |
724 * Result Elements. | 724 * Result Elements. |
725 * | 725 * |
726 * Called by: | 726 * Called by: |
727 * xsltCopyTreeInternal() (transform.c) | 727 * xsltCopyTreeInternal() (transform.c) |
728 * xsltShallowCopyElem() (transform.c) | 728 * xsltShallowCopyElem() (transform.c) |
729 * | 729 * |
730 * REVISIT: This function won't be used in the refactored code. | 730 * REVISIT: This function won't be used in the refactored code. |
731 * | 731 * |
732 * Returns: a new xmlNsPtr, or NULL in case of error. | 732 * Returns: a new xmlNsPtr, or NULL in case of error. |
733 */ | 733 */ |
734 xmlNsPtr | 734 xmlNsPtr |
735 xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node, | 735 xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node, |
736 xmlNsPtr cur) { | 736 xmlNsPtr cur) { |
737 xmlNsPtr ret = NULL, tmp; | 737 xmlNsPtr ret = NULL, tmp; |
738 xmlNsPtr p = NULL,q; | 738 xmlNsPtr p = NULL,q; |
739 | 739 |
740 if (cur == NULL) | 740 if (cur == NULL) |
741 return(NULL); | 741 return(NULL); |
742 if (cur->type != XML_NAMESPACE_DECL) | 742 if (cur->type != XML_NAMESPACE_DECL) |
743 return(NULL); | 743 return(NULL); |
744 | 744 |
745 /* | 745 /* |
746 * One can add namespaces only on element nodes | 746 * One can add namespaces only on element nodes |
747 */ | 747 */ |
748 if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) | 748 if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) |
749 node = NULL; | 749 node = NULL; |
750 | 750 |
751 while (cur != NULL) { | 751 while (cur != NULL) { |
752 if (cur->type != XML_NAMESPACE_DECL) | 752 if (cur->type != XML_NAMESPACE_DECL) |
753 break; | 753 break; |
754 | 754 |
755 /* | 755 /* |
756 * Avoid duplicating namespace declarations in the tree if | 756 * Avoid duplicating namespace declarations in the tree if |
757 * a matching declaration is in scope. | 757 * a matching declaration is in scope. |
758 */ | 758 */ |
759 if (node != NULL) { | 759 if (node != NULL) { |
760 if ((node->ns != NULL) && | 760 if ((node->ns != NULL) && |
761 (xmlStrEqual(node->ns->prefix, cur->prefix)) && | 761 (xmlStrEqual(node->ns->prefix, cur->prefix)) && |
762 » (xmlStrEqual(node->ns->href, cur->href))) { | 762 » (xmlStrEqual(node->ns->href, cur->href))) { |
763 cur = cur->next; | 763 cur = cur->next; |
764 continue; | 764 continue; |
765 } | 765 } |
766 tmp = xmlSearchNs(node->doc, node, cur->prefix); | 766 tmp = xmlSearchNs(node->doc, node, cur->prefix); |
767 if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) { | 767 if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) { |
768 cur = cur->next; | 768 cur = cur->next; |
769 continue; | 769 continue; |
770 } | 770 } |
771 } | 771 } |
772 #ifdef XSLT_REFACTORED | 772 #ifdef XSLT_REFACTORED |
(...skipping 10 matching lines...) Expand all Loading... |
783 } | 783 } |
784 #else | 784 #else |
785 /* | 785 /* |
786 * TODO: Remove this if the refactored code gets enabled. | 786 * TODO: Remove this if the refactored code gets enabled. |
787 */ | 787 */ |
788 if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) { | 788 if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) { |
789 const xmlChar *URI; | 789 const xmlChar *URI; |
790 /* TODO apply cascading */ | 790 /* TODO apply cascading */ |
791 URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases, | 791 URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases, |
792 cur->href); | 792 cur->href); |
793 » if (URI == UNDEFINED_DEFAULT_NS) | 793 » if (URI == UNDEFINED_DEFAULT_NS) { |
| 794 » » cur = cur->next; |
794 continue; | 795 continue; |
| 796 } |
795 if (URI != NULL) { | 797 if (URI != NULL) { |
796 q = xmlNewNs(node, URI, cur->prefix); | 798 q = xmlNewNs(node, URI, cur->prefix); |
797 } else { | 799 } else { |
798 q = xmlNewNs(node, cur->href, cur->prefix); | 800 q = xmlNewNs(node, cur->href, cur->prefix); |
799 } | 801 } |
800 if (p == NULL) { | 802 if (p == NULL) { |
801 ret = p = q; | 803 ret = p = q; |
802 } else { | 804 } else { |
803 p->next = q; | 805 p->next = q; |
804 p = q; | 806 p = q; |
(...skipping 12 matching lines...) Expand all Loading... |
817 * @ns: the namespace node | 819 * @ns: the namespace node |
818 * | 820 * |
819 * Copies a namespace node (declaration). If @elem is not NULL, | 821 * Copies a namespace node (declaration). If @elem is not NULL, |
820 * then the new namespace will be declared on @elem. | 822 * then the new namespace will be declared on @elem. |
821 * | 823 * |
822 * Returns: a new xmlNsPtr, or NULL in case of an error. | 824 * Returns: a new xmlNsPtr, or NULL in case of an error. |
823 */ | 825 */ |
824 xmlNsPtr | 826 xmlNsPtr |
825 xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, | 827 xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, |
826 xmlNodePtr elem, xmlNsPtr ns) | 828 xmlNodePtr elem, xmlNsPtr ns) |
827 { | 829 { |
828 if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) | 830 if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) |
829 return(NULL); | 831 return(NULL); |
830 /* | 832 /* |
831 * One can add namespaces only on element nodes | 833 * One can add namespaces only on element nodes |
832 */ | 834 */ |
833 if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE)) | 835 if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE)) |
834 return(xmlNewNs(NULL, ns->href, ns->prefix)); | 836 return(xmlNewNs(NULL, ns->href, ns->prefix)); |
835 else | 837 else |
836 return(xmlNewNs(elem, ns->href, ns->prefix)); | 838 return(xmlNewNs(elem, ns->href, ns->prefix)); |
837 } | 839 } |
838 | 840 |
839 | 841 |
840 /** | 842 /** |
841 * xsltFreeNamespaceAliasHashes: | 843 * xsltFreeNamespaceAliasHashes: |
842 * @style: an XSLT stylesheet | 844 * @style: an XSLT stylesheet |
843 * | 845 * |
844 * Free up the memory used by namespaces aliases | 846 * Free up the memory used by namespaces aliases |
845 */ | 847 */ |
846 void | 848 void |
847 xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) { | 849 xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) { |
848 if (style->nsAliases != NULL) | 850 if (style->nsAliases != NULL) |
849 xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL); | 851 xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL); |
850 style->nsAliases = NULL; | 852 style->nsAliases = NULL; |
851 } | 853 } |
OLD | NEW |