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