VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libexslt/dynamic.c@ 7296

最後變更 在這個檔案從7296是 7296,由 vboxsync 提交於 17 年 前

Added libxslt-1.1.22 sources.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Date Revision Author Id
檔案大小: 8.6 KB
 
1/*
2 * dynamic.c: Implementation of the EXSLT -- Dynamic module
3 *
4 * References:
5 * http://www.exslt.org/dyn/dyn.html
6 *
7 * See Copyright for the status of this software.
8 *
9 * Authors:
10 * Mark Vakoc <[email protected]>
11 * Thomas Broyer <[email protected]>
12 *
13 * TODO:
14 * elements:
15 * functions:
16 * min
17 * max
18 * sum
19 * map
20 * closure
21 */
22
23#define IN_LIBEXSLT
24#include "libexslt/libexslt.h"
25
26#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
27#include <win32config.h>
28#else
29#include "config.h"
30#endif
31
32#include <libxml/tree.h>
33#include <libxml/xpath.h>
34#include <libxml/xpathInternals.h>
35
36#include <libxslt/xsltconfig.h>
37#include <libxslt/xsltutils.h>
38#include <libxslt/xsltInternals.h>
39#include <libxslt/extensions.h>
40
41#include "exslt.h"
42
43/**
44 * exsltDynEvaluateFunction:
45 * @ctxt: an XPath parser context
46 * @nargs: the number of arguments
47 *
48 * Evaluates the string as an XPath expression and returns the result
49 * value, which may be a boolean, number, string, node set, result tree
50 * fragment or external object.
51 */
52
53static void
54exsltDynEvaluateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
55 xmlChar *str = NULL;
56 xmlXPathObjectPtr ret = NULL;
57
58 if (ctxt == NULL)
59 return;
60 if (nargs != 1) {
61 xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
62 xsltGenericError(xsltGenericErrorContext,
63 "dyn:evalute() : invalid number of args %d\n", nargs);
64 ctxt->error = XPATH_INVALID_ARITY;
65 return;
66 }
67 str = xmlXPathPopString(ctxt);
68 /* return an empty node-set if an empty string is passed in */
69 if (!str||!xmlStrlen(str)) {
70 if (str) xmlFree(str);
71 valuePush(ctxt,xmlXPathNewNodeSet(NULL));
72 return;
73 }
74 ret = xmlXPathEval(str,ctxt->context);
75 if (ret)
76 valuePush(ctxt,ret);
77 else {
78 xsltGenericError(xsltGenericErrorContext,
79 "dyn:evaluate() : unable to evaluate expression '%s'\n",str);
80 valuePush(ctxt,xmlXPathNewNodeSet(NULL));
81 }
82 xmlFree(str);
83 return;
84}
85
86/**
87 * exsltDynMapFunction:
88 * @ctxt: an XPath parser context
89 * @nargs: the number of arguments
90 *
91 * Evaluates the string as an XPath expression and returns the result
92 * value, which may be a boolean, number, string, node set, result tree
93 * fragment or external object.
94 */
95
96static void
97exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
98{
99 xmlChar *str = NULL;
100 xmlNodeSetPtr nodeset = NULL;
101 xmlXPathCompExprPtr comp = NULL;
102 xmlXPathObjectPtr ret = NULL;
103 xmlDocPtr oldDoc, container;
104 xmlNodePtr oldNode;
105 int oldContextSize;
106 int oldProximityPosition;
107 int i, j;
108
109
110 if (nargs != 2) {
111 xmlXPathSetArityError(ctxt);
112 return;
113 }
114 str = xmlXPathPopString(ctxt);
115 if (xmlXPathCheckError(ctxt)) {
116 xmlXPathSetTypeError(ctxt);
117 return;
118 }
119
120 nodeset = xmlXPathPopNodeSet(ctxt);
121 if (xmlXPathCheckError(ctxt)) {
122 xmlXPathSetTypeError(ctxt);
123 return;
124 }
125 if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
126 if (nodeset != NULL)
127 xmlXPathFreeNodeSet(nodeset);
128 if (str != NULL)
129 xmlFree(str);
130 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
131 return;
132 }
133
134 ret = xmlXPathNewNodeSet(NULL);
135 if (ret == NULL) {
136 xsltGenericError(xsltGenericErrorContext,
137 "exsltDynMapFunctoin: ret == NULL\n");
138 goto cleanup;
139 }
140
141 oldDoc = ctxt->context->doc;
142 oldNode = ctxt->context->node;
143 oldContextSize = ctxt->context->contextSize;
144 oldProximityPosition = ctxt->context->proximityPosition;
145
146 /**
147 * since we really don't know we're going to be adding node(s)
148 * down the road we create the RVT regardless
149 */
150 container = xsltCreateRVT(xsltXPathGetTransformContext(ctxt));
151 if (container != NULL)
152 xsltRegisterLocalRVT(xsltXPathGetTransformContext(ctxt), container);
153
154 if (nodeset && nodeset->nodeNr > 0) {
155 xmlXPathNodeSetSort(nodeset);
156 ctxt->context->contextSize = nodeset->nodeNr;
157 ctxt->context->proximityPosition = 0;
158 for (i = 0; i < nodeset->nodeNr; i++) {
159 xmlXPathObjectPtr subResult = NULL;
160
161 ctxt->context->proximityPosition++;
162 ctxt->context->node = nodeset->nodeTab[i];
163 ctxt->context->doc = nodeset->nodeTab[i]->doc;
164
165 subResult = xmlXPathCompiledEval(comp, ctxt->context);
166 if (subResult != NULL) {
167 switch (subResult->type) {
168 case XPATH_NODESET:
169 if (subResult->nodesetval != NULL)
170 for (j = 0; j < subResult->nodesetval->nodeNr;
171 j++)
172 xmlXPathNodeSetAdd(ret->nodesetval,
173 subResult->nodesetval->
174 nodeTab[j]);
175 break;
176 case XPATH_BOOLEAN:
177 if (container != NULL) {
178 xmlNodePtr cur =
179 xmlNewChild((xmlNodePtr) container, NULL,
180 BAD_CAST "boolean",
181 BAD_CAST (subResult->
182 boolval ? "true" : ""));
183 if (cur != NULL) {
184 cur->ns =
185 xmlNewNs(cur,
186 BAD_CAST
187 "http://exslt.org/common",
188 BAD_CAST "exsl");
189 xmlXPathNodeSetAddUnique(ret->nodesetval,
190 cur);
191 }
192 }
193 break;
194 case XPATH_NUMBER:
195 if (container != NULL) {
196 xmlChar *val =
197 xmlXPathCastNumberToString(subResult->
198 floatval);
199 xmlNodePtr cur =
200 xmlNewChild((xmlNodePtr) container, NULL,
201 BAD_CAST "number", val);
202 if (val != NULL)
203 xmlFree(val);
204
205 if (cur != NULL) {
206 cur->ns =
207 xmlNewNs(cur,
208 BAD_CAST
209 "http://exslt.org/common",
210 BAD_CAST "exsl");
211 xmlXPathNodeSetAddUnique(ret->nodesetval,
212 cur);
213 }
214 }
215 break;
216 case XPATH_STRING:
217 if (container != NULL) {
218 xmlNodePtr cur =
219 xmlNewChild((xmlNodePtr) container, NULL,
220 BAD_CAST "string",
221 subResult->stringval);
222 if (cur != NULL) {
223 cur->ns =
224 xmlNewNs(cur,
225 BAD_CAST
226 "http://exslt.org/common",
227 BAD_CAST "exsl");
228 xmlXPathNodeSetAddUnique(ret->nodesetval,
229 cur);
230 }
231 }
232 break;
233 default:
234 break;
235 }
236 xmlXPathFreeObject(subResult);
237 }
238 }
239 }
240 ctxt->context->doc = oldDoc;
241 ctxt->context->node = oldNode;
242 ctxt->context->contextSize = oldContextSize;
243 ctxt->context->proximityPosition = oldProximityPosition;
244
245
246 cleanup:
247 /* restore the xpath context */
248 if (comp != NULL)
249 xmlXPathFreeCompExpr(comp);
250 if (nodeset != NULL)
251 xmlXPathFreeNodeSet(nodeset);
252 if (str != NULL)
253 xmlFree(str);
254 valuePush(ctxt, ret);
255 return;
256}
257
258
259/**
260 * exsltDynRegister:
261 *
262 * Registers the EXSLT - Dynamic module
263 */
264
265void
266exsltDynRegister (void) {
267 xsltRegisterExtModuleFunction ((const xmlChar *) "evaluate",
268 EXSLT_DYNAMIC_NAMESPACE,
269 exsltDynEvaluateFunction);
270 xsltRegisterExtModuleFunction ((const xmlChar *) "map",
271 EXSLT_DYNAMIC_NAMESPACE,
272 exsltDynMapFunction);
273
274}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette