1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_forms.hxx"
27 #include <string.h>
28 #include <sal/types.h>
29 #include <rtl/alloc.h>
30 #include <rtl/ustring.hxx>
31 #include <rtl/string.hxx>
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/strbuf.hxx>
34 #include <tools/date.hxx>
35 #include <tools/time.hxx>
36 #include <tools/datetime.hxx>
37
38 #include <com/sun/star/uno/Reference.hxx>
39 #include <com/sun/star/uno/Sequence.hxx>
40 #include <com/sun/star/uno/Any.hxx>
41 #include <com/sun/star/xforms/XModel.hpp>
42 #include <com/sun/star/xml/dom/XNode.hpp>
43 #include <com/sun/star/xml/dom/XDocument.hpp>
44 #include <com/sun/star/lang/XUnoTunnel.hpp>
45
46 #include "xpathlib.hxx"
47
48 #include "extension.hxx"
49
50 // C interface
51
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::xml::dom;
54 using namespace com::sun::star::xforms;
55 using namespace com::sun::star::lang;
56
xforms_lookupFunc(void *,const xmlChar * xname,const xmlChar *)57 xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
58 {
59
60 const char *name = (char *)xname;
61 if (strcmp("boolean-from-string", name)==0)
62 return xforms_booleanFromStringFunction;
63 else if ((strcmp("if", name))==0)
64 return xforms_ifFunction;
65 else if ((strcmp("avg", name))==0)
66 return xforms_avgFunction;
67 else if ((strcmp("min", name))==0)
68 return xforms_minFunction;
69 else if ((strcmp("max", name))==0)
70 return xforms_maxFunction;
71 else if ((strcmp("count-non-empty", name))==0)
72 return xforms_countNonEmptyFunction;
73 else if ((strcmp("index", name))==0)
74 return xforms_indexFunction;
75 else if ((strcmp("property", name))==0)
76 return xforms_propertyFunction;
77 else if ((strcmp("now", name))==0)
78 return xforms_nowFunction;
79 else if ((strcmp("days-from-date", name))==0)
80 return xforms_daysFromDateFunction;
81 else if ((strcmp("seconds-from-dateTime", name))==0)
82 return xforms_secondsFromDateTimeFunction;
83 else if ((strcmp("seconds", name))==0)
84 return xforms_secondsFuction;
85 else if ((strcmp("months", name))==0)
86 return xforms_monthsFuction;
87 else if ((strcmp("instance", name))==0)
88 return xforms_instanceFuction;
89 else if ((strcmp("current", name))==0)
90 return xforms_currentFunction;
91 else
92 return NULL;
93 }
94
95 // boolean functions
xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt,int nargs)96 void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
97 {
98 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
99 xmlChar *pString = xmlXPathPopString(ctxt);
100 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
101 ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
102 if (aString.equalsIgnoreAsciiCaseAscii("true") || aString.equalsIgnoreAsciiCaseAscii("1"))
103 xmlXPathReturnTrue(ctxt);
104 else if (aString.equalsIgnoreAsciiCaseAscii("false") || aString.equalsIgnoreAsciiCaseAscii("0"))
105 xmlXPathReturnFalse(ctxt);
106 else
107 XP_ERROR(XPATH_NUMBER_ERROR);
108 }
109
xforms_ifFunction(xmlXPathParserContextPtr ctxt,int nargs)110 void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
111 {
112 if (nargs != 3) XP_ERROR(XPATH_INVALID_ARITY);
113 xmlChar *s2 = xmlXPathPopString(ctxt);
114
115 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
116 xmlChar *s1 = xmlXPathPopString(ctxt);
117 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
118 bool aBool = xmlXPathPopBoolean(ctxt);
119 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
120
121 if (aBool)
122 xmlXPathReturnString(ctxt, s1);
123 else
124 xmlXPathReturnString(ctxt, s2);
125
126 }
127
128 // Number Functions
xforms_avgFunction(xmlXPathParserContextPtr ctxt,int nargs)129 void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
130 {
131 // use sum(), div() and count()
132 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
133
134 // save nodeset
135 xmlXPathObjectPtr pObject = valuePop(ctxt);
136 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
137 //push back a copy
138 valuePush(ctxt, xmlXPathObjectCopy(pObject));
139 // get the Sum
140 xmlXPathSumFunction(ctxt, 1);
141 double nSum = xmlXPathPopNumber(ctxt);
142 // push a copy once more
143 valuePush(ctxt, xmlXPathObjectCopy(pObject));
144 xmlXPathCountFunction(ctxt, 1);
145 double nCount = xmlXPathPopNumber(ctxt);
146 // push args for div()
147 xmlXPathReturnNumber(ctxt, nSum);
148 xmlXPathReturnNumber(ctxt, nCount);
149 xmlXPathDivValues(ctxt);
150 // the result is now on the ctxt stack
151 xmlXPathFreeObject(pObject);
152 }
153
xforms_minFunction(xmlXPathParserContextPtr ctxt,int nargs)154 void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
155 {
156 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
157 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
158 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
159 double nMinimum = 0;
160 double nNumber = 0;
161 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
162 {
163 nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
164 if (xmlXPathIsNaN(nNumber))
165 {
166 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
167 return;
168 }
169 if (i == 0)
170 nMinimum = nNumber;
171 else if (nNumber < nMinimum)
172 nMinimum = nNumber;
173 }
174 xmlXPathReturnNumber(ctxt, nMinimum);
175 }
176
xforms_maxFunction(xmlXPathParserContextPtr ctxt,int nargs)177 void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
178 {
179 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
180 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
181 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
182 double nMaximum = 0;
183 double nNumber = 0;
184 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
185 {
186 nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
187 if (xmlXPathIsNaN(nNumber))
188 {
189 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
190 return;
191 }
192 if (i == 0)
193 nMaximum = nNumber;
194 else if (nNumber > nMaximum)
195 nMaximum = nNumber;
196 }
197 xmlXPathReturnNumber(ctxt, nMaximum);
198 }
xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt,int nargs)199 void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
200 {
201 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
202 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
203 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
204 xmlChar *aString;
205 sal_Int32 nNotEmpty = 0;
206 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
207 {
208 aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet, i));
209 if (strlen((char*)aString) > 0) nNotEmpty++;
210 }
211 xmlXPathReturnNumber(ctxt, nNotEmpty);
212 }
xforms_indexFunction(xmlXPathParserContextPtr,int)213 void xforms_indexFunction(xmlXPathParserContextPtr /*ctxt*/, int /*nargs*/)
214 {
215 // function index takes a string argument that is the IDREF of a
216 // 'repeat' and returns the current 1-based position of the repeat
217 // index of the identified repeat -- see xforms/9.3.1
218
219 // doc.getElementByID
220 // (...)
221 }
222
223 // String Functions
224 static const char* _version = "1.0";
225 static const char* _conformance = "conformance";
xforms_propertyFunction(xmlXPathParserContextPtr ctxt,int nargs)226 void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
227 {
228 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
229 xmlChar* pString = xmlXPathPopString(ctxt);
230 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
231 ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
232 if (aString.equalsIgnoreAsciiCaseAscii("version"))
233 xmlXPathReturnString(ctxt, (xmlChar*)_version);
234 else if (aString.equalsIgnoreAsciiCaseAscii("conformance-level"))
235 xmlXPathReturnString(ctxt, (xmlChar*)_conformance);
236 else
237 xmlXPathReturnEmptyString(ctxt);
238 }
239
240 // Date and Time Functions
241
makeDateTimeString(const DateTime & aDateTime,sal_Bool bUTC=sal_True)242 static ::rtl::OString makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_True)
243 {
244 ::rtl::OStringBuffer aDateTimeString;
245 aDateTimeString.append((sal_Int32)aDateTime.GetYear());
246 aDateTimeString.append("-");
247 if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
248 aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
249 aDateTimeString.append("-");
250 if (aDateTime.GetDay()<10) aDateTimeString.append("0");
251 aDateTimeString.append((sal_Int32)aDateTime.GetDay());
252 aDateTimeString.append("T");
253 if (aDateTime.GetHour()<10) aDateTimeString.append("0");
254 aDateTimeString.append((sal_Int32)aDateTime.GetHour());
255 aDateTimeString.append(":");
256 if (aDateTime.GetMin()<10) aDateTimeString.append("0");
257 aDateTimeString.append((sal_Int32)aDateTime.GetMin());
258 aDateTimeString.append(":");
259 if (aDateTime.GetSec()<10) aDateTimeString.append("0");
260 aDateTimeString.append((sal_Int32)aDateTime.GetSec());
261 if (bUTC) aDateTimeString.append("Z");
262
263 return aDateTimeString.makeStringAndClear();
264 }
265
266 // returns current system date and time in canonical xsd:dateTime
267 // format
xforms_nowFunction(xmlXPathParserContextPtr ctxt,int)268 void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int /*nargs*/)
269 {
270 /*
271 A single lexical representation, which is a subset of the lexical representations
272 allowed by [ISO 8601], is allowed for dateTime. This lexical representation is the
273 [ISO 8601] extended format CCYY-MM-DDThh:mm:ss where "CC" represents the century,
274 "YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-"
275 sign to indicate a negative number. If the sign is omitted, "+" is assumed. The letter
276 "T" is the date/time separator and "hh", "mm", "ss" represent hour, minute and second
277 respectively.
278 */
279
280 /*
281 3.2.7.2 Canonical representation
282 The canonical representation for dateTime is defined by prohibiting certain options
283 from the Lexical representation (par.3.2.7.1). Specifically, either the time zone must
284 be omitted or, if present, the time zone must be Coordinated Universal Time (UTC)
285 indicated by a "Z".
286 */
287 DateTime aDateTime;
288 ::rtl::OString aDateTimeString = makeDateTimeString(aDateTime);
289 xmlChar *pString = static_cast<xmlChar*>(xmlMalloc(aDateTimeString.getLength()+1));
290 strncpy((char*)pString, (char*)aDateTimeString.getStr(), aDateTimeString.getLength());
291 pString[aDateTimeString.getLength()] = 0;
292 xmlXPathReturnString(ctxt, pString);
293 }
294
parseDateTime(const::rtl::OUString & aString,DateTime & aDateTime)295 static sal_Bool parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime)
296 {
297 // take apart a canonical literal xsd:dateTime string
298 //CCYY-MM-DDThh:mm:ss(Z)
299
300 ::rtl::OUString aDateTimeString = aString.trim();
301
302 // check length
303 if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
304 return sal_False;
305
306 sal_Int32 nDateLength = 10;
307 sal_Int32 nTimeLength = 8;
308
309 ::rtl::OUString aDateTimeSep = ::rtl::OUString::createFromAscii("T");
310 ::rtl::OUString aDateSep = ::rtl::OUString::createFromAscii("-");
311 ::rtl::OUString aTimeSep = ::rtl::OUString::createFromAscii(":");
312 ::rtl::OUString aUTCString = ::rtl::OUString::createFromAscii("Z");
313
314 ::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength);
315 ::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
316
317 sal_Int32 nIndex = 0;
318 sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
319 sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
320 sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
321 nIndex = 0;
322 sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
323 sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
324 sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
325
326 Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
327 Time tmpTime(nHour, nMinute, nSecond);
328 DateTime tmpDateTime(tmpDate, tmpTime);
329 if (aString.indexOf(aUTCString) < 0)
330 tmpDateTime.ConvertToUTC();
331
332 aDateTime = tmpDateTime;
333
334 return sal_True;
335 }
336
337
xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt,int nargs)338 void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
339 {
340 // number of days from 1970-01-01 to supplied xsd:date(Time)
341
342 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
343 xmlChar* pString = xmlXPathPopString(ctxt);
344 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
345 ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
346
347 DateTime aDateTime;
348 if (parseDateTime(aString, aDateTime))
349 {
350 Date aReferenceDate(1, 1, 1970);
351 sal_Int32 nDays = aDateTime - aReferenceDate;
352 xmlXPathReturnNumber(ctxt, nDays);
353 }
354 else
355 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
356
357
358 }
359
360
xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt,int nargs)361 void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
362 {
363 // number of seconds from 1970-01-01T00:00:00Z to supplied xsd:date(Time)
364
365 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
366 xmlChar* pString = xmlXPathPopString(ctxt);
367 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
368 ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
369
370 DateTime aDateTime;
371
372 if (parseDateTime(aString, aDateTime))
373 {
374 Date aReferenceDate(1, 1, 1970);
375 Time aReferenceTime(0, 0, 0);
376 sal_Int32 nDays = aDateTime - aReferenceDate;
377 sal_Int32 nSeconds = nDays * 24 * 60 * 60;
378 nSeconds += aDateTime.GetHour() * 60 * 60;
379 nSeconds += aDateTime.GetMin() * 60;
380 nSeconds += aDateTime.GetSec();
381 xmlXPathReturnNumber(ctxt, nSeconds);
382 }
383 else
384 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
385
386 }
387
parseDuration(const xmlChar * aString,sal_Bool & bNegative,sal_Int32 & nYears,sal_Int32 & nMonth,sal_Int32 & nDays,sal_Int32 & nHours,sal_Int32 & nMinutes,sal_Int32 & nSeconds)388 static sal_Bool parseDuration(const xmlChar* aString, sal_Bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
389 sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
390 {
391 sal_Bool bTime = sal_False; // in part after T
392 sal_Int32 nLength = strlen((char*)aString)+1;
393 char *pString = (char*)rtl_allocateMemory(nLength);
394 char *pString0 = pString;
395 strncpy(pString, (char*)aString, nLength);
396
397 if (pString[0] == '-') {
398 bNegative = sal_True;
399 pString++;
400 }
401
402 if (pString[0] != 'P')
403 return sal_False;
404 pString++;
405 char* pToken = pString;
406 while(pToken[0] != 0)
407 {
408 switch(pToken[0]) {
409 case 'Y':
410 pToken[0] = 0;
411 nYears = atoi(pString);
412 pString = ++pToken;
413 break;
414 case 'M':
415 pToken[0] = 0;
416 if (!bTime)
417 nMonth = atoi(pString);
418 else
419 nMinutes = atoi(pString);
420 pString = ++pToken;
421 break;
422 case 'D':
423 pToken[0] = 0;
424 nDays = atoi(pString);
425 pString = ++pToken;
426 break;
427 case 'H':
428 pToken[0] = 0;
429 nHours = atoi(pString);
430 pString = ++pToken;
431 break;
432 case 'S':
433 pToken[0] = 0;
434 nSeconds = atoi(pString);
435 pString = ++pToken;
436 break;
437 case 'T':
438 bTime = sal_True;
439 pString = ++pToken;
440 break;
441 default:
442 pToken++;
443 }
444 }
445 rtl_freeMemory(pString0);
446 return sal_True;
447 }
448
xforms_secondsFuction(xmlXPathParserContextPtr ctxt,int nargs)449 void xforms_secondsFuction(xmlXPathParserContextPtr ctxt, int nargs)
450 {
451 // convert a xsd:duration to seconds
452 // (-)PnYnMnDTnHnMnS
453 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
454 xmlChar* pString = xmlXPathPopString(ctxt);
455 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
456
457 sal_Bool bNegative = sal_False;
458 sal_Int32 nYears = 0;
459 sal_Int32 nMonths = 0;
460 sal_Int32 nDays = 0;
461 sal_Int32 nHours = 0;
462 sal_Int32 nMinutes = 0;
463 sal_Int32 nSeconds = 0;
464
465 if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
466 {
467 nSeconds += nMinutes*60;
468 nSeconds += nHours*60*60;
469 nSeconds += nDays*24*60*60;
470 // year and month are ignored according to spec
471 if (bNegative)
472 nSeconds = 0 - nSeconds;
473 xmlXPathReturnNumber(ctxt, nSeconds);
474 }
475 else
476 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
477 }
478
xforms_monthsFuction(xmlXPathParserContextPtr ctxt,int nargs)479 void xforms_monthsFuction(xmlXPathParserContextPtr ctxt, int nargs)
480 {
481 // convert a xsd:duration to seconds
482 // (-)PnYnMnDTnHnMnS
483 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
484 xmlChar* pString = xmlXPathPopString(ctxt);
485 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
486
487 sal_Bool bNegative = sal_False;
488 sal_Int32 nYears = 0;
489 sal_Int32 nMonths = 0;
490 sal_Int32 nDays = 0;
491 sal_Int32 nHours = 0;
492 sal_Int32 nMinutes = 0;
493 sal_Int32 nSeconds = 0;
494
495 if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
496 {
497 nMonths += nYears*12;
498 // Days, Houres, Minutes and seconds are ignored, see spec
499 if (bNegative)
500 nMonths = 0 - nMonths;
501 xmlXPathReturnNumber(ctxt, nMonths);
502 }
503 else
504 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
505
506 }
507
508 // Node-set Functions
xforms_instanceFuction(xmlXPathParserContextPtr ctxt,int nargs)509 void xforms_instanceFuction(xmlXPathParserContextPtr ctxt, int nargs)
510 {
511 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
512 xmlChar *pString = xmlXPathPopString(ctxt);
513 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
514 ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
515
516 Reference< XModel > aModel = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getModel();
517 if (aModel.is())
518 {
519 Reference< XDocument > aInstance = aModel->getInstanceDocument(aString);
520 if (aInstance.is())
521 {
522 try {
523 // xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
524 Reference< XUnoTunnel > aTunnel(aInstance, UNO_QUERY_THROW);
525 xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
526 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
527 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
528 } catch (RuntimeException&)
529 {
530 xmlXPathReturnEmptyNodeSet(ctxt);
531 }
532 }
533 else
534 xmlXPathReturnEmptyNodeSet(ctxt);
535 }
536 else
537 xmlXPathReturnEmptyNodeSet(ctxt);
538
539 }
540
541 // Node-set Functions, XForms 1.1
xforms_currentFunction(xmlXPathParserContextPtr ctxt,int nargs)542 void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
543 {
544 if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
545
546 Reference< XNode > aNode = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getContextNode();
547
548 if (aNode.is())
549 {
550 try {
551 Reference< XUnoTunnel > aTunnel(aNode, UNO_QUERY_THROW);
552 xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
553 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
554 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
555 }
556 catch (RuntimeException&)
557 {
558 xmlXPathReturnEmptyNodeSet(ctxt);
559 }
560 }
561 else
562 xmlXPathReturnEmptyNodeSet(ctxt);
563 }
564