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