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