OLD | NEW |
1 /* | 1 /* |
2 * xslt.c: Implemetation of an XSL Transformation 1.0 engine | 2 * xslt.c: Implemetation of an XSL Transformation 1.0 engine |
3 * | 3 * |
4 * Reference: | 4 * Reference: |
5 * XSLT specification | 5 * XSLT specification |
6 * http://www.w3.org/TR/1999/REC-xslt-19991116 | 6 * http://www.w3.org/TR/1999/REC-xslt-19991116 |
7 * | 7 * |
8 * Associating Style Sheets with XML documents | 8 * Associating Style Sheets with XML documents |
9 * http://www.w3.org/1999/06/REC-xml-stylesheet-19990629 | 9 * http://www.w3.org/1999/06/REC-xml-stylesheet-19990629 |
10 * | 10 * |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 } | 268 } |
269 return(1); | 269 return(1); |
270 } | 270 } |
271 | 271 |
272 /************************************************************************ | 272 /************************************************************************ |
273 * * | 273 * * |
274 * Routines to handle XSLT data structures * | 274 * Routines to handle XSLT data structures * |
275 * * | 275 * * |
276 ************************************************************************/ | 276 ************************************************************************/ |
277 static xsltDecimalFormatPtr | 277 static xsltDecimalFormatPtr |
278 xsltNewDecimalFormat(xmlChar *name) | 278 xsltNewDecimalFormat(const xmlChar *nsUri, xmlChar *name) |
279 { | 279 { |
280 xsltDecimalFormatPtr self; | 280 xsltDecimalFormatPtr self; |
281 /* UTF-8 for 0x2030 */ | 281 /* UTF-8 for 0x2030 */ |
282 static const xmlChar permille[4] = {0xe2, 0x80, 0xb0, 0}; | 282 static const xmlChar permille[4] = {0xe2, 0x80, 0xb0, 0}; |
283 | 283 |
284 self = xmlMalloc(sizeof(xsltDecimalFormat)); | 284 self = xmlMalloc(sizeof(xsltDecimalFormat)); |
285 if (self != NULL) { | 285 if (self != NULL) { |
286 self->next = NULL; | 286 self->next = NULL; |
| 287 self->nsUri = nsUri; |
287 self->name = name; | 288 self->name = name; |
288 | 289 |
289 /* Default values */ | 290 /* Default values */ |
290 self->digit = xmlStrdup(BAD_CAST("#")); | 291 self->digit = xmlStrdup(BAD_CAST("#")); |
291 self->patternSeparator = xmlStrdup(BAD_CAST(";")); | 292 self->patternSeparator = xmlStrdup(BAD_CAST(";")); |
292 self->decimalPoint = xmlStrdup(BAD_CAST(".")); | 293 self->decimalPoint = xmlStrdup(BAD_CAST(".")); |
293 self->grouping = xmlStrdup(BAD_CAST(",")); | 294 self->grouping = xmlStrdup(BAD_CAST(",")); |
294 self->percent = xmlStrdup(BAD_CAST("%")); | 295 self->percent = xmlStrdup(BAD_CAST("%")); |
295 self->permille = xmlStrdup(BAD_CAST(permille)); | 296 self->permille = xmlStrdup(BAD_CAST(permille)); |
296 self->zeroDigit = xmlStrdup(BAD_CAST("0")); | 297 self->zeroDigit = xmlStrdup(BAD_CAST("0")); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 { | 363 { |
363 xsltDecimalFormatPtr result = NULL; | 364 xsltDecimalFormatPtr result = NULL; |
364 | 365 |
365 if (name == NULL) | 366 if (name == NULL) |
366 return style->decimalFormat; | 367 return style->decimalFormat; |
367 | 368 |
368 while (style != NULL) { | 369 while (style != NULL) { |
369 for (result = style->decimalFormat->next; | 370 for (result = style->decimalFormat->next; |
370 result != NULL; | 371 result != NULL; |
371 result = result->next) { | 372 result = result->next) { |
372 » if (xmlStrEqual(name, result->name)) | 373 » if ((result->nsUri == NULL) && xmlStrEqual(name, result->name)) |
373 return result; | 374 return result; |
374 } | 375 } |
375 style = xsltNextImport(style); | 376 style = xsltNextImport(style); |
| 377 } |
| 378 return result; |
| 379 } |
| 380 |
| 381 /** |
| 382 * xsltDecimalFormatGetByQName: |
| 383 * @style: the XSLT stylesheet |
| 384 * @nsUri: the namespace URI of the QName |
| 385 * @name: the local part of the QName |
| 386 * |
| 387 * Find decimal-format by QName |
| 388 * |
| 389 * Returns the xsltDecimalFormatPtr |
| 390 */ |
| 391 xsltDecimalFormatPtr |
| 392 xsltDecimalFormatGetByQName(xsltStylesheetPtr style, const xmlChar *nsUri, |
| 393 const xmlChar *name) |
| 394 { |
| 395 xsltDecimalFormatPtr result = NULL; |
| 396 |
| 397 if (name == NULL) |
| 398 return style->decimalFormat; |
| 399 |
| 400 while (style != NULL) { |
| 401 for (result = style->decimalFormat->next; |
| 402 result != NULL; |
| 403 result = result->next) { |
| 404 if (xmlStrEqual(nsUri, result->nsUri) && |
| 405 xmlStrEqual(name, result->name)) |
| 406 return result; |
| 407 } |
| 408 style = xsltNextImport(style); |
376 } | 409 } |
377 return result; | 410 return result; |
378 } | 411 } |
379 | 412 |
380 | 413 |
381 /** | 414 /** |
382 * xsltNewTemplate: | 415 * xsltNewTemplate: |
383 * | 416 * |
384 * Create a new XSLT Template | 417 * Create a new XSLT Template |
385 * | 418 * |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 ret = (xsltStylesheetPtr) xmlMalloc(sizeof(xsltStylesheet)); | 773 ret = (xsltStylesheetPtr) xmlMalloc(sizeof(xsltStylesheet)); |
741 if (ret == NULL) { | 774 if (ret == NULL) { |
742 xsltTransformError(NULL, NULL, NULL, | 775 xsltTransformError(NULL, NULL, NULL, |
743 "xsltNewStylesheet : malloc failed\n"); | 776 "xsltNewStylesheet : malloc failed\n"); |
744 goto internal_err; | 777 goto internal_err; |
745 } | 778 } |
746 memset(ret, 0, sizeof(xsltStylesheet)); | 779 memset(ret, 0, sizeof(xsltStylesheet)); |
747 | 780 |
748 ret->omitXmlDeclaration = -1; | 781 ret->omitXmlDeclaration = -1; |
749 ret->standalone = -1; | 782 ret->standalone = -1; |
750 ret->decimalFormat = xsltNewDecimalFormat(NULL); | 783 ret->decimalFormat = xsltNewDecimalFormat(NULL, NULL); |
751 ret->indent = -1; | 784 ret->indent = -1; |
752 ret->errors = 0; | 785 ret->errors = 0; |
753 ret->warnings = 0; | 786 ret->warnings = 0; |
754 ret->exclPrefixNr = 0; | 787 ret->exclPrefixNr = 0; |
755 ret->exclPrefixMax = 0; | 788 ret->exclPrefixMax = 0; |
756 ret->exclPrefixTab = NULL; | 789 ret->exclPrefixTab = NULL; |
757 ret->extInfos = NULL; | 790 ret->extInfos = NULL; |
758 ret->extrasNr = 0; | 791 ret->extrasNr = 0; |
759 ret->internalized = 1; | 792 ret->internalized = 1; |
760 ret->literal_result = 0; | 793 ret->literal_result = 0; |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 xsltDecimalFormatPtr format; | 1410 xsltDecimalFormatPtr format; |
1378 xsltDecimalFormatPtr iter; | 1411 xsltDecimalFormatPtr iter; |
1379 | 1412 |
1380 if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) | 1413 if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) |
1381 return; | 1414 return; |
1382 | 1415 |
1383 format = style->decimalFormat; | 1416 format = style->decimalFormat; |
1384 | 1417 |
1385 prop = xmlGetNsProp(cur, BAD_CAST("name"), NULL); | 1418 prop = xmlGetNsProp(cur, BAD_CAST("name"), NULL); |
1386 if (prop != NULL) { | 1419 if (prop != NULL) { |
1387 » format = xsltDecimalFormatGetByName(style, prop); | 1420 const xmlChar *nsUri; |
| 1421 |
| 1422 if (xmlValidateQName(prop, 0) != 0) { |
| 1423 xsltTransformError(NULL, style, cur, |
| 1424 "xsl:decimal-format: Invalid QName '%s'.\n", prop); |
| 1425 » style->warnings++; |
| 1426 xmlFree(prop); |
| 1427 return; |
| 1428 } |
| 1429 /* |
| 1430 * TODO: Don't use xsltGetQNameURI(). |
| 1431 */ |
| 1432 nsUri = xsltGetQNameURI(cur, &prop); |
| 1433 if (prop == NULL) { |
| 1434 » style->warnings++; |
| 1435 return; |
| 1436 } |
| 1437 » format = xsltDecimalFormatGetByQName(style, nsUri, prop); |
1388 if (format != NULL) { | 1438 if (format != NULL) { |
1389 xsltTransformError(NULL, style, cur, | 1439 xsltTransformError(NULL, style, cur, |
1390 "xsltParseStylestyleDecimalFormat: %s already exists\n", prop); | 1440 "xsltParseStylestyleDecimalFormat: %s already exists\n", prop); |
1391 » if (style != NULL) style->warnings++; | 1441 » style->warnings++; |
| 1442 xmlFree(prop); |
1392 return; | 1443 return; |
1393 } | 1444 } |
1394 » format = xsltNewDecimalFormat(prop); | 1445 » format = xsltNewDecimalFormat(nsUri, prop); |
1395 if (format == NULL) { | 1446 if (format == NULL) { |
1396 xsltTransformError(NULL, style, cur, | 1447 xsltTransformError(NULL, style, cur, |
1397 "xsltParseStylestyleDecimalFormat: failed creating new decimal-format\n"); | 1448 "xsltParseStylestyleDecimalFormat: failed creating new decimal-format\n"); |
1398 » if (style != NULL) style->errors++; | 1449 » style->errors++; |
| 1450 xmlFree(prop); |
1399 return; | 1451 return; |
1400 } | 1452 } |
1401 /* Append new decimal-format structure */ | 1453 /* Append new decimal-format structure */ |
1402 for (iter = style->decimalFormat; iter->next; iter = iter->next) | 1454 for (iter = style->decimalFormat; iter->next; iter = iter->next) |
1403 ; | 1455 ; |
1404 if (iter) | 1456 if (iter) |
1405 iter->next = format; | 1457 iter->next = format; |
1406 } | 1458 } |
1407 | 1459 |
1408 prop = xmlGetNsProp(cur, (const xmlChar *)"decimal-separator", NULL); | 1460 prop = xmlGetNsProp(cur, (const xmlChar *)"decimal-separator", NULL); |
(...skipping 5572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6981 ret = xsltParseStylesheetFile(href); | 7033 ret = xsltParseStylesheetFile(href); |
6982 } | 7034 } |
6983 if (base != NULL) | 7035 if (base != NULL) |
6984 xmlFree(base); | 7036 xmlFree(base); |
6985 } | 7037 } |
6986 xmlFreeURI(URI); | 7038 xmlFreeURI(URI); |
6987 xmlFree(href); | 7039 xmlFree(href); |
6988 } | 7040 } |
6989 return(ret); | 7041 return(ret); |
6990 } | 7042 } |
OLD | NEW |