Annotation of parser3/src/classes/xnode.C, revision 1.52
1.1 parser 1: /** @file
2: Parser: @b dom parser class.
3:
1.37 paf 4: Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.38 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 parser 6: */
7: #include "classes.h"
8: #ifdef XML
1.46 paf 9:
1.52 ! paf 10: static const char* IDENT_XNODE_C="$Date: 2002/08/19 09:37:05 $";
1.1 parser 11:
1.21 paf 12: #include "pa_charset.h"
1.1 parser 13: #include "pa_request.h"
14: #include "pa_vxnode.h"
1.34 paf 15: #include "pa_vxdoc.h"
1.23 paf 16: #include "pa_vvoid.h"
1.1 parser 17:
18: #include "xnode.h"
19:
1.21 paf 20: extern "C" {
21: #include "gdomecore/gdome-xml-node.h"
1.27 paf 22: #include "gdomecore/gdome-xml-document.h"
1.21 paf 23: };
1.19 paf 24: #include "gdome.h"
1.21 paf 25: #include "libxml/xpath.h"
26:
27: // classes
28:
29: class xmlXPathObject_auto_ptr {
30: public:
1.29 paf 31: explicit xmlXPathObject_auto_ptr(xmlXPathObject *_APtr = 0)
32: : _Owns(_APtr != 0), _Ptr(_APtr) {}
1.21 paf 33: xmlXPathObject_auto_ptr(const xmlXPathObject_auto_ptr& _Y)
34: : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
35: xmlXPathObject_auto_ptr& operator=(const xmlXPathObject_auto_ptr& _Y)
36: {if (this != &_Y)
37: {if (_Ptr != _Y.get())
38: {if (_Owns && _Ptr)
39: xmlXPathFreeObject(_Ptr);
40: _Owns = _Y._Owns; }
41: else if (_Y._Owns)
42: _Owns = true;
43: _Ptr = _Y.release(); }
44: return (*this); }
45: ~xmlXPathObject_auto_ptr()
46: {if (_Owns && _Ptr)
47: xmlXPathFreeObject(_Ptr); }
48: xmlXPathObject& operator*() const
49: {return (*get()); }
50: xmlXPathObject *operator->() const
51: {return (get()); }
52: xmlXPathObject *get() const
53: {return (_Ptr); }
54: xmlXPathObject *release() const
55: {((xmlXPathObject_auto_ptr *)this)->_Owns = false;
56: return (_Ptr); }
57: private:
58: bool _Owns;
59: xmlXPathObject *_Ptr;
60: };
61:
62: class xmlXPathContext_auto_ptr {
63: public:
1.29 paf 64: explicit xmlXPathContext_auto_ptr(xmlXPathContext *_APtr = 0)
65: : _Owns(_APtr != 0), _Ptr(_APtr) {}
1.21 paf 66: xmlXPathContext_auto_ptr(const xmlXPathContext_auto_ptr& _Y)
67: : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
68: xmlXPathContext_auto_ptr& operator=(const xmlXPathContext_auto_ptr& _Y)
69: {if (this != &_Y)
70: {if (_Ptr != _Y.get())
71: {if (_Owns && _Ptr)
72: xmlXPathFreeContext(_Ptr);
73: _Owns = _Y._Owns; }
74: else if (_Y._Owns)
75: _Owns = true;
76: _Ptr = _Y.release(); }
77: return (*this); }
78: ~xmlXPathContext_auto_ptr()
79: {if (_Owns && _Ptr)
80: xmlXPathFreeContext(_Ptr); }
81: xmlXPathContext& operator*() const
82: {return (*get()); }
83: xmlXPathContext *operator->() const
84: {return (get()); }
85: xmlXPathContext *get() const
86: {return (_Ptr); }
87: xmlXPathContext *release() const
88: {((xmlXPathContext_auto_ptr *)this)->_Owns = false;
89: return (_Ptr); }
90: private:
91: bool _Owns;
92: xmlXPathContext *_Ptr;
93: };
1.1 parser 94:
1.6 parser 95: // helpers
96:
1.42 paf 97: GdomeNode *as_node(const String& method_name, MethodParams *params,
1.6 parser 98: int index, const char *msg) {
99: Value& value=params->as_no_junction(index, msg);
1.48 paf 100: if(Value *vxnode=value.as(VXNODE_TYPE, false))
101: return static_cast<VXnode *>(vxnode)->get_node(&method_name);
102: else
1.41 paf 103: throw Exception("parser.runtime",
1.6 parser 104: &method_name,
105: msg);
106: }
107:
108: // helpers
109:
1.19 paf 110: GdomeAttr * as_attr(Pool& pool, const String& method_name, MethodParams *params,
1.6 parser 111: int index, const char *msg) {
1.42 paf 112: GdomeNode *node=as_node(method_name, params, index, msg);
1.19 paf 113: GdomeException exc;
114: if(gdome_n_nodeType(node, &exc)!=GDOME_ATTRIBUTE_NODE)
1.41 paf 115: throw Exception("parser.runtime",
1.6 parser 116: &method_name,
117: msg);
118:
1.19 paf 119: return GDOME_A(node);
1.6 parser 120: }
1.1 parser 121:
122: // methods
123:
1.6 parser 124: // DOM1 node
125:
126: // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
127: static void _insertBefore(Request& r, const String& method_name, MethodParams *params) {
128: Pool& pool=r.pool();
1.52 ! paf 129: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 130: GdomeNode *selfNode=vnode.get_node(&method_name);
1.42 paf 131: GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node");
132: GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node");
1.6 parser 133:
1.19 paf 134: GdomeException exc;
135: if(GdomeNode *retNode=gdome_n_insertBefore(selfNode, newChild, refChild, &exc)) {
136: // write out result
137: VXnode& result=*new(pool) VXnode(pool, retNode);
138: r.write_no_lang(result);
139: } else
1.41 paf 140: throw Exception(
1.19 paf 141: &method_name,
142: exc);
1.6 parser 143: }
144:
145: // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
146: static void _replaceChild(Request& r, const String& method_name, MethodParams *params) {
147: Pool& pool=r.pool();
1.52 ! paf 148: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 149: GdomeNode *selfNode=vnode.get_node(&method_name);
1.42 paf 150: GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node");
151: GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node");
1.6 parser 152:
1.19 paf 153: GdomeException exc;
154: if(GdomeNode *retNode=gdome_n_replaceChild(selfNode, newChild, refChild, &exc)) {
155: // write out result
156: r.write_no_lang(*new(pool) VXnode(pool, retNode));
157: } else
1.41 paf 158: throw Exception(
1.19 paf 159: &method_name,
160: exc);
1.6 parser 161: }
162:
163: // Node removeChild(in Node oldChild) raises(DOMException);
164: static void _removeChild(Request& r, const String& method_name, MethodParams *params) {
165: Pool& pool=r.pool();
1.52 ! paf 166: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 167: GdomeNode *selfNode=vnode.get_node(&method_name);
1.42 paf 168: GdomeNode *oldChild=as_node(method_name, params, 0, "oldChild must be node");
1.6 parser 169:
1.19 paf 170: GdomeException exc;
171: if(GdomeNode *retNode=gdome_n_removeChild(selfNode, oldChild, &exc)) {
172: // write out result
173: r.write_no_lang(*new(pool) VXnode(pool, retNode));
174: } else
1.41 paf 175: throw Exception(
1.19 paf 176: &method_name,
177: exc);
1.6 parser 178: }
179:
180: // Node appendChild(in Node newChild) raises(DOMException);
181: static void _appendChild(Request& r, const String& method_name, MethodParams *params) {
182: Pool& pool=r.pool();
1.52 ! paf 183: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 184: GdomeNode *selfNode=vnode.get_node(&method_name);
1.42 paf 185: GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node");
1.6 parser 186:
1.19 paf 187: GdomeException exc;
188: if(GdomeNode *retNode=gdome_n_appendChild(selfNode, newChild, &exc)) {
189: // write out result
190: r.write_no_lang(*new(pool) VXnode(pool, retNode));
191: } else
1.41 paf 192: throw Exception(
1.19 paf 193: &method_name,
194: exc);
1.6 parser 195: }
196:
197: // boolean hasChildNodes();
198: static void _hasChildNodes(Request& r, const String& method_name, MethodParams *) {
199: Pool& pool=r.pool();
1.52 ! paf 200: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 201: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 202:
1.19 paf 203: GdomeException exc;
1.6 parser 204: // write out result
1.44 paf 205: bool result=gdome_n_hasChildNodes(node, &exc)!=0;
206: r.write_no_lang(*new(pool) VBool(pool, result));
1.6 parser 207: }
208:
209: // Node cloneNode(in boolean deep);
210: static void _cloneNode(Request& r, const String& method_name, MethodParams *params) {
211: Pool& pool=r.pool();
1.52 ! paf 212: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 213: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 214:
215: bool deep=params->as_bool(0, "deep must be bool", r);
216:
1.19 paf 217: GdomeException exc;
1.6 parser 218: // write out result
1.44 paf 219: r.write_no_lang(*new(pool) VXnode(pool, gdome_n_cloneNode(node, deep, &exc)));
1.6 parser 220: }
221:
222: // DOM1 element
223:
1.19 paf 224: GdomeElement *get_self_element(Request& r, const String& method_name) {
1.6 parser 225: Pool& pool=r.pool();
1.52 ! paf 226: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 227: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 228:
1.19 paf 229: GdomeException exc;
1.50 paf 230: if(gdome_n_nodeType(node, &exc)!=GDOME_ELEMENT_NODE)
1.41 paf 231: throw Exception("parser.runtime",
1.6 parser 232: &method_name,
1.51 paf 233: "method can only be called on nodes of ELEMENT type");
1.6 parser 234:
1.19 paf 235: return GDOME_EL(node);
1.6 parser 236: }
237:
238: // DOMString getAttribute(in DOMString name);
239: static void _getAttribute(Request& r, const String& method_name, MethodParams *params) {
240: Pool& pool=r.pool();
1.19 paf 241: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 242: const String& name=params->as_string(0, "name must be string");
1.6 parser 243:
1.19 paf 244: GdomeException exc;
245: GdomeDOMString *attribute_value=
1.21 paf 246: gdome_el_getAttribute(element, pool.transcode(name).get(), &exc);
1.6 parser 247: // write out result
1.43 paf 248: r.write_no_lang(pool.transcode(attribute_value));
1.6 parser 249: }
250:
251: // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
252: static void _setAttribute(Request& r, const String& method_name, MethodParams *params) {
253: Pool& pool=r.pool();
1.19 paf 254: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 255: const String& name=params->as_string(0, "name must be string");
256: const String& attribute_value=params->as_string(1, "value must be string");
1.6 parser 257:
1.19 paf 258: GdomeException exc;
259: gdome_el_setAttribute(element,
1.21 paf 260: pool.transcode(name).get(),
261: pool.transcode(attribute_value).get(),
1.19 paf 262: &exc);
263: if(exc)
1.41 paf 264: throw Exception(
1.19 paf 265: &method_name,
266: exc);
1.6 parser 267: }
268:
269: // void removeAttribute(in DOMString name) raises(DOMException);
270: static void _removeAttribute(Request& r, const String& method_name, MethodParams *params) {
271: Pool& pool=r.pool();
1.19 paf 272: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 273: const String& name=params->as_string(0, "name must be string");
1.6 parser 274:
1.19 paf 275: GdomeException exc;
1.21 paf 276: gdome_el_removeAttribute(element, pool.transcode(name).get(), &exc);
1.19 paf 277: if(exc)
1.41 paf 278: throw Exception(
1.19 paf 279: &method_name,
280: exc);
1.6 parser 281: }
282:
283: // Attr getAttributeNode(in DOMString name);
284: static void _getAttributeNode(Request& r, const String& method_name, MethodParams *params) {
285: Pool& pool=r.pool();
1.19 paf 286: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 287: const String& name=params->as_string(0, "name must be string");
1.6 parser 288:
1.19 paf 289: GdomeException exc;
1.21 paf 290: if(GdomeAttr *attr=gdome_el_getAttributeNode(element, pool.transcode(name).get(), &exc)) {
1.6 parser 291: // write out result
1.19 paf 292: VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)attr);
1.6 parser 293: r.write_no_lang(result);
1.19 paf 294: } else if(exc)
1.41 paf 295: throw Exception(
1.19 paf 296: &method_name,
297: exc);
1.6 parser 298: }
299:
300: // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
301: static void _setAttributeNode(Request& r, const String& method_name, MethodParams *params) {
302: Pool& pool=r.pool();
1.19 paf 303: GdomeElement *element=get_self_element(r, method_name);
304: GdomeAttr * newAttr=as_attr(pool, method_name, params, 0, "newAttr must be ATTRIBUTE node");
1.6 parser 305:
1.19 paf 306: GdomeException exc;
307: if(GdomeAttr *returnAttr=gdome_el_setAttributeNode(element, newAttr, &exc)) {
308: // write out result
309: VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)returnAttr);
310: r.write_no_lang(result);
311: } else
1.41 paf 312: throw Exception(
1.19 paf 313: &method_name,
314: exc);
1.6 parser 315: }
316:
317: // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
318: static void _removeAttributeNode(Request& r, const String& method_name, MethodParams *params) {
319: Pool& pool=r.pool();
1.19 paf 320: GdomeElement *element=get_self_element(r, method_name);
321: GdomeAttr * oldAttr=as_attr(pool, method_name, params, 0, "oldAttr must be ATTRIBUTE node");
1.6 parser 322:
1.19 paf 323: GdomeException exc;
324: gdome_el_removeAttributeNode(element, oldAttr, &exc);
325: if(exc)
1.41 paf 326: throw Exception(
1.26 paf 327: &method_name,
328: exc);
1.6 parser 329: }
330:
331: // NodeList getElementsByTagName(in DOMString name);
332: static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) {
333: Pool& pool=r.pool();
1.19 paf 334: GdomeElement *element=get_self_element(r, method_name);
1.6 parser 335:
1.11 parser 336: const String& name=params->as_string(0, "name must be string");
1.6 parser 337:
338: VHash& result=*new(pool) VHash(pool);
1.19 paf 339: GdomeException exc;
340: if(GdomeNodeList *nodes=
1.21 paf 341: gdome_el_getElementsByTagName(element, pool.transcode(name).get(), &exc)) {
1.19 paf 342: gulong length=gdome_nl_length(nodes, &exc);
343: for(gulong i=0; i<length; i++) {
1.6 parser 344: String& skey=*new(pool) String(pool);
345: {
346: char *buf=(char *)pool.malloc(MAX_NUMBER);
347: snprintf(buf, MAX_NUMBER, "%d", i);
348: skey << buf;
349: }
350:
1.19 paf 351: result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc)));
1.6 parser 352: }
1.19 paf 353: } else if(exc)
1.41 paf 354: throw Exception(
1.26 paf 355: &method_name,
356: exc);
1.6 parser 357:
358: // write out result
359: r.write_no_lang(result);
360: }
361:
1.39 paf 362: static void _getElementsByTagNameNS(Request& r, const String& method_name, MethodParams *params) {
363: Pool& pool=r.pool();
364: GdomeElement *element=get_self_element(r, method_name);
365:
366: // namespaceURI;localName
367: const String& namespaceURI=params->as_string(0, "namespaceURI must be string");
368: const String& localName=params->as_string(1, "localName must be string");
369:
370: GdomeException exc;
371: VHash& result=*new(pool) VHash(pool);
372: if(GdomeNodeList *nodes=
373: gdome_el_getElementsByTagNameNS(
374: element,
375: pool.transcode(namespaceURI).get(),
376: pool.transcode(localName).get(),
377: &exc)) {
378: gulong length=gdome_nl_length(nodes, &exc);
379: for(gulong i=0; i<length; i++) {
380: String& skey=*new(pool) String(pool);
381: {
382: char *buf=(char *)pool.malloc(MAX_NUMBER);
383: snprintf(buf, MAX_NUMBER, "%d", i);
384: skey << buf;
385: }
386:
387: result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc)));
388: }
389: }
390:
391: // write out result
392: r.write_no_lang(result);
393: }
394:
1.6 parser 395: // void normalize();
396: static void _normalize(Request& r, const String& method_name, MethodParams *) {
1.19 paf 397: Pool& pool=r.pool();
1.52 ! paf 398: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.19 paf 399: GdomeNode *selfNode=vnode.get_node(&method_name);
1.6 parser 400:
1.19 paf 401: GdomeException exc;
402: gdome_n_normalize(selfNode, &exc);
403: if(exc)
1.41 paf 404: throw Exception(
1.26 paf 405: &method_name,
406: exc);
1.6 parser 407: }
1.25 paf 408:
1.26 paf 409: static void _selectX(Request& r, const String& method_name, MethodParams *params,
410: void (*handler)(Pool& pool,
411: const String& expression,
412: xmlXPathObject_auto_ptr res,
413: Value *& result)) {
1.1 parser 414: // _asm int 3;
415: Pool& pool=r.pool();
1.52 ! paf 416: VXnode& vnode=*static_cast<VXnode *>(r.get_self());
1.1 parser 417:
418: // expression
1.9 parser 419: const String& expression=params->as_string(0, "expression must be string");
1.1 parser 420:
1.25 paf 421: GdomeException exc;
422: GdomeNode *dome_node=vnode.get_node(&method_name);
423: GdomeDocument *dome_document=gdome_n_ownerDocument(dome_node, &exc);
1.32 paf 424: if(!dome_document) // document does not own itself, so ownerDocument = 0
425: dome_document=GDOME_DOC(dome_node); // and we need downcast
1.33 paf 426: xmlDoc *xml_document=gdome_xml_doc_get_xmlDoc(dome_document);
1.25 paf 427: xmlXPathContext_auto_ptr ctxt(xmlXPathNewContext(xml_document));
1.32 paf 428: ctxt->node=gdome_xml_n_get_xmlNode(dome_node);
1.25 paf 429: /*error to stderr for now*/
430: xmlXPathObject_auto_ptr res(
431: xmlXPathEvalExpression(BAD_CAST pool.transcode(expression)->str, ctxt.get()));
1.28 paf 432:
433: if(xmlHaveGenericErrors()) {
434: GdomeException exc=0;
1.41 paf 435: throw Exception(&expression, exc);
1.28 paf 436: }
1.25 paf 437:
438: Value *result=0;
439: if(res.get())
1.26 paf 440: handler(pool, expression, res, result);
1.44 paf 441: if(result)
1.26 paf 442: r.write_no_lang(*result);
443: }
1.25 paf 444:
1.26 paf 445: static void selectNodesHandler(Pool& pool,
446: const String& expression,
447: xmlXPathObject_auto_ptr res,
448: Value *& result) {
1.31 paf 449: VHash *vhash=new(pool) VHash(pool); result=vhash;
1.26 paf 450: switch(res->type) {
451: case XPATH_UNDEFINED:
452: break;
453: case XPATH_NODESET:
1.40 paf 454: if(res->nodesetval)
455: if(int size=res->nodesetval->nodeNr) {
456: Hash& hash=vhash->hash(0);
457: for(int i=0; i<size; i++) {
458: String& skey=*new(pool) String(pool);
459: {
460: char *buf=(char *)pool.malloc(MAX_NUMBER);
461: snprintf(buf, MAX_NUMBER, "%d", i);
462: skey << buf;
463: }
464:
465: hash.put(skey, new(pool) VXnode(pool,
466: gdome_xml_n_mkref(res->nodesetval->nodeTab[i])));
1.25 paf 467: }
1.1 parser 468: }
1.26 paf 469: break;
470: default:
1.41 paf 471: throw Exception(0,
1.26 paf 472: &expression,
473: "wrong xmlXPathEvalExpression result type (%d)", res->type);
474: break; // never
475: }
476: }
477:
478: static void selectNodeHandler(Pool& pool,
479: const String& expression,
480: xmlXPathObject_auto_ptr res,
481: Value *& result) {
482: switch(res->type) {
483: case XPATH_UNDEFINED:
484: break;
485: case XPATH_NODESET:
1.40 paf 486: if(res->nodesetval && res->nodesetval->nodeNr) { // empty result strangly has NODESET res->type
1.26 paf 487: if(res->nodesetval->nodeNr>1)
1.41 paf 488: throw Exception("parser.runtime",
1.25 paf 489: &expression,
1.26 paf 490: "resulted not in a single node (%d)", res->nodesetval->nodeNr);
491:
492: result=new(pool) VXnode(pool, gdome_xml_n_mkref(res->nodesetval->nodeTab[0]));
1.25 paf 493: }
1.26 paf 494: break;
495: case XPATH_BOOLEAN:
496: result=new(pool) VBool(pool, res->boolval!=0);
497: break;
498: case XPATH_NUMBER:
499: result=new(pool) VDouble(pool, res->floatval);
500: break;
501: case XPATH_STRING:
502: result=new(pool) VString(
503: pool.transcode(
504: GdomeDOMString_auto_ptr(
505: gdome_str_mkref_dup((const gchar *)res->stringval)).get()));
506: break;
507: default:
1.41 paf 508: throw Exception("parser.runtime",
1.26 paf 509: &expression,
510: "wrong xmlXPathEvalExpression result type (%d)", res->type);
511: break; // never
512: }
513: }
514:
515: static void selectBoolHandler(Pool& pool,
516: const String& expression,
517: xmlXPathObject_auto_ptr res,
518: Value *& result) {
519: switch(res->type) {
520: case XPATH_BOOLEAN:
521: result=new(pool) VBool(pool, res->boolval!=0);
522: break;
523: case XPATH_NODESET:
1.40 paf 524: if(!(res->nodesetval && res->nodesetval->nodeNr))
1.26 paf 525: break;
526: // else[nodeset] fall down to default
527: default:
1.41 paf 528: throw Exception("parser.runtime",
1.26 paf 529: &expression,
530: "wrong xmlXPathEvalExpression result type (%d)", res->type);
531: break; // never
532: }
533: }
1.1 parser 534:
1.26 paf 535: static void selectNumberHandler(Pool& pool,
536: const String& expression,
537: xmlXPathObject_auto_ptr res,
538: Value *& result) {
539: switch(res->type) {
540: case XPATH_NUMBER:
541: result=new(pool) VDouble(pool, res->floatval);
542: break;
543: case XPATH_NODESET:
1.40 paf 544: if(!(res->nodesetval && res->nodesetval->nodeNr))
1.26 paf 545: break;
546: // else[nodeset] fall down to default
547: default:
1.41 paf 548: throw Exception("parser.runtime",
1.26 paf 549: &expression,
550: "wrong xmlXPathEvalExpression result type (%d)", res->type);
551: break; // never
552: }
553: }
554:
555: static void selectStringHandler(Pool& pool,
556: const String& expression,
557: xmlXPathObject_auto_ptr res,
558: Value *& result) {
559: switch(res->type) {
560: case XPATH_UNDEFINED:
561: break;
562: case XPATH_STRING:
563: result=new(pool) VString(
564: pool.transcode(
565: GdomeDOMString_auto_ptr(
566: gdome_str_mkref_dup((const gchar *)res->stringval)).get()));
567: break;
568: case XPATH_NODESET:
1.40 paf 569: if(!(res->nodesetval && res->nodesetval->nodeNr))
1.26 paf 570: break;
571: // else[nodeset] fall down to default
572: default:
1.41 paf 573: throw Exception("parser.runtime",
1.26 paf 574: &expression,
575: "wrong xmlXPathEvalExpression result type (%d)", res->type);
576: break; // never
1.1 parser 577: }
578: }
1.25 paf 579:
1.26 paf 580: static void _select(Request& r, const String& method_name, MethodParams *params) {
581: _selectX(r, method_name, params,
582: selectNodesHandler);
583: }
584:
1.9 parser 585: static void _selectSingle(Request& r, const String& method_name, MethodParams *params) {
1.26 paf 586: _selectX(r, method_name, params,
587: selectNodeHandler);
588: }
1.1 parser 589:
1.26 paf 590: static void _selectBool(Request& r, const String& method_name, MethodParams *params) {
591: _selectX(r, method_name, params,
592: selectBoolHandler);
593: }
1.20 paf 594:
1.26 paf 595: static void _selectNumber(Request& r, const String& method_name, MethodParams *params) {
596: _selectX(r, method_name, params,
597: selectNumberHandler);
598: }
1.24 paf 599:
1.26 paf 600: static void _selectString(Request& r, const String& method_name, MethodParams *params) {
601: _selectX(r, method_name, params,
602: selectStringHandler);
1.1 parser 603: }
1.20 paf 604:
1.1 parser 605: // constructor
606:
1.45 paf 607: MXnode::MXnode(Pool& apool, const char *aname, VStateless_class *abase) :
608: Methoded(apool, aname?aname:"xnode", abase),
609:
1.44 paf 610: consts(apool)
611: {
1.6 parser 612: /// DOM1 node
613:
614: // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
615: add_native_method("insertBefore", Method::CT_DYNAMIC, _insertBefore, 2, 2);
616: // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
617: add_native_method("replaceChild", Method::CT_DYNAMIC, _replaceChild, 2, 2);
618: // Node removeChild(in Node oldChild) raises(DOMException);
619: add_native_method("removeChild", Method::CT_DYNAMIC, _removeChild, 1, 1);
620: // Node appendChild(in Node newChild) raises(DOMException);
621: add_native_method("appendChild", Method::CT_DYNAMIC, _appendChild, 1, 1);
622: // boolean hasChildNodes();
623: add_native_method("hasChildNodes", Method::CT_DYNAMIC, _hasChildNodes, 0, 0);
624: // Node cloneNode(in boolean deep);
625: add_native_method("cloneNode", Method::CT_DYNAMIC, _cloneNode, 1, 1);
626:
627: /// DOM1 element
628:
629: // DOMString getAttribute(in DOMString name);
630: add_native_method("getAttribute", Method::CT_DYNAMIC, _getAttribute, 1, 1);
631: // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
632: add_native_method("setAttribute", Method::CT_DYNAMIC, _setAttribute, 2, 2);
633: // void removeAttribute(in DOMString name) raises(DOMException);
634: add_native_method("removeAttribute", Method::CT_DYNAMIC, _removeAttribute, 1, 1);
635: // Attr getAttributeNode(in DOMString name);
636: add_native_method("getAttributeNode", Method::CT_DYNAMIC, _getAttributeNode, 1, 1);
637: // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
638: add_native_method("setAttributeNode", Method::CT_DYNAMIC, _setAttributeNode, 1, 1);
639: // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
640: add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1);
641: // NodeList getElementsByTagName(in DOMString name);
642: add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
1.39 paf 643: // NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName);
644: add_native_method("getElementsByTagNameNS", Method::CT_DYNAMIC, _getElementsByTagNameNS, 2, 2);
1.6 parser 645: // void normalize();
646: add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0);
647:
648: /// parser
1.1 parser 649: // ^node.select[/some/xpath/query] = hash $.#[dnode]
1.25 paf 650: add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);
1.1 parser 651:
1.26 paf 652: // ^node.selectSingle[/some/xpath/query] = first node [if any]
1.9 parser 653: add_native_method("selectSingle", Method::CT_DYNAMIC, _selectSingle, 1, 1);
1.26 paf 654: // ^node.selectBool[/some/xpath/query] = bool value [if any]
655: add_native_method("selectBool", Method::CT_DYNAMIC, _selectBool, 1, 1);
656: // ^node.selectNumber[/some/xpath/query] = double value [if any]
657: add_native_method("selectNumber", Method::CT_DYNAMIC, _selectNumber, 1, 1);
658: // ^node.selectString[/some/xpath/query] = strinv value [if any]
659: add_native_method("selectString", Method::CT_DYNAMIC, _selectString, 1, 1);
1.20 paf 660:
1.2 parser 661: // consts
662:
1.19 paf 663: #define CONST(name) \
664: consts.put(*new(pool()) String(pool(), #name), new(pool()) VInt(pool(), GDOME_##name))
1.2 parser 665:
1.19 paf 666: CONST(ELEMENT_NODE);
667: CONST(ATTRIBUTE_NODE);
668: CONST(TEXT_NODE);
669: CONST(CDATA_SECTION_NODE);
670: CONST(ENTITY_REFERENCE_NODE);
671: CONST(ENTITY_NODE);
672: CONST(PROCESSING_INSTRUCTION_NODE);
673: CONST(COMMENT_NODE);
674: CONST(DOCUMENT_NODE);
675: CONST(DOCUMENT_TYPE_NODE);
676: CONST(DOCUMENT_FRAGMENT_NODE);
677: CONST(NOTATION_NODE);
1.1 parser 678:
679: }
1.3 parser 680:
1.1 parser 681: // global variable
682:
683: Methoded *Xnode_class;
684:
685: #endif
686:
687: // creator
688: Methoded *MXnode_create(Pool& pool) {
689: return
690: #ifdef XML
691: Xnode_class=new(pool) MXnode(pool)
692: #else
693: 0
694: #endif
695: ;
696: }
E-mail: