OLD | NEW |
1 /* | 1 /* |
2 * functions.c: Implementation of the XSLT extra functions | 2 * functions.c: Implementation of the XSLT extra functions |
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 * Bjorn Reese <breese@users.sourceforge.net> for number formatting | 10 * Bjorn Reese <breese@users.sourceforge.net> for number formatting |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 * xsltGenerateIdFunction: | 647 * xsltGenerateIdFunction: |
648 * @ctxt: the XPath Parser context | 648 * @ctxt: the XPath Parser context |
649 * @nargs: the number of arguments | 649 * @nargs: the number of arguments |
650 * | 650 * |
651 * Implement the generate-id() XSLT function | 651 * Implement the generate-id() XSLT function |
652 * string generate-id(node-set?) | 652 * string generate-id(node-set?) |
653 */ | 653 */ |
654 void | 654 void |
655 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ | 655 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
656 xmlNodePtr cur = NULL; | 656 xmlNodePtr cur = NULL; |
| 657 xmlXPathObjectPtr obj = NULL; |
657 long val; | 658 long val; |
658 xmlChar str[30]; | 659 xmlChar str[30]; |
659 xmlDocPtr doc; | 660 xmlDocPtr doc; |
660 | 661 |
661 if (nargs == 0) { | 662 if (nargs == 0) { |
662 cur = ctxt->context->node; | 663 cur = ctxt->context->node; |
663 } else if (nargs == 1) { | 664 } else if (nargs == 1) { |
664 xmlXPathObjectPtr obj; | |
665 xmlNodeSetPtr nodelist; | 665 xmlNodeSetPtr nodelist; |
666 int i, ret; | 666 int i, ret; |
667 | 667 |
668 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { | 668 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { |
669 ctxt->error = XPATH_INVALID_TYPE; | 669 ctxt->error = XPATH_INVALID_TYPE; |
670 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | 670 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
671 "generate-id() : invalid arg expecting a node-set\n"); | 671 "generate-id() : invalid arg expecting a node-set\n"); |
672 return; | 672 return; |
673 } | 673 } |
674 obj = valuePop(ctxt); | 674 obj = valuePop(ctxt); |
675 nodelist = obj->nodesetval; | 675 nodelist = obj->nodesetval; |
676 if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { | 676 if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { |
677 xmlXPathFreeObject(obj); | 677 xmlXPathFreeObject(obj); |
678 valuePush(ctxt, xmlXPathNewCString("")); | 678 valuePush(ctxt, xmlXPathNewCString("")); |
679 return; | 679 return; |
680 } | 680 } |
681 cur = nodelist->nodeTab[0]; | 681 cur = nodelist->nodeTab[0]; |
682 for (i = 1;i < nodelist->nodeNr;i++) { | 682 for (i = 1;i < nodelist->nodeNr;i++) { |
683 ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); | 683 ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); |
684 if (ret == -1) | 684 if (ret == -1) |
685 cur = nodelist->nodeTab[i]; | 685 cur = nodelist->nodeTab[i]; |
686 } | 686 } |
687 xmlXPathFreeObject(obj); | |
688 } else { | 687 } else { |
689 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | 688 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
690 "generate-id() : invalid number of args %d\n", nargs); | 689 "generate-id() : invalid number of args %d\n", nargs); |
691 ctxt->error = XPATH_INVALID_ARITY; | 690 ctxt->error = XPATH_INVALID_ARITY; |
692 return; | 691 return; |
693 } | 692 } |
694 /* | 693 /* |
695 * Okay this is ugly but should work, use the NodePtr address | 694 * Okay this is ugly but should work, use the NodePtr address |
696 * to forge the ID | 695 * to forge the ID |
697 */ | 696 */ |
698 if (cur->type != XML_NAMESPACE_DECL) | 697 if (cur->type != XML_NAMESPACE_DECL) |
699 doc = cur->doc; | 698 doc = cur->doc; |
700 else { | 699 else { |
701 xmlNsPtr ns = (xmlNsPtr) cur; | 700 xmlNsPtr ns = (xmlNsPtr) cur; |
702 | 701 |
703 if (ns->context != NULL) | 702 if (ns->context != NULL) |
704 doc = ns->context; | 703 doc = ns->context; |
705 else | 704 else |
706 doc = ctxt->context->doc; | 705 doc = ctxt->context->doc; |
707 | 706 |
708 } | 707 } |
709 | 708 |
| 709 if (obj) |
| 710 xmlXPathFreeObject(obj); |
| 711 |
710 val = (long)((char *)cur - (char *)doc); | 712 val = (long)((char *)cur - (char *)doc); |
711 if (val >= 0) { | 713 if (val >= 0) { |
712 sprintf((char *)str, "idp%ld", val); | 714 sprintf((char *)str, "idp%ld", val); |
713 } else { | 715 } else { |
714 sprintf((char *)str, "idm%ld", -val); | 716 sprintf((char *)str, "idm%ld", -val); |
715 } | 717 } |
716 valuePush(ctxt, xmlXPathNewString(str)); | 718 valuePush(ctxt, xmlXPathNewString(str)); |
717 } | 719 } |
718 | 720 |
719 /** | 721 /** |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 xsltFormatNumberFunction); | 984 xsltFormatNumberFunction); |
983 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", | 985 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", |
984 xsltGenerateIdFunction); | 986 xsltGenerateIdFunction); |
985 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", | 987 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", |
986 xsltSystemPropertyFunction); | 988 xsltSystemPropertyFunction); |
987 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", | 989 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", |
988 xsltElementAvailableFunction); | 990 xsltElementAvailableFunction); |
989 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", | 991 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", |
990 xsltFunctionAvailableFunction); | 992 xsltFunctionAvailableFunction); |
991 } | 993 } |
OLD | NEW |