Annotation of parser3/src/classes/xnode.C, revision 1.20
1.1 parser 1: /** @file
2: Parser: @b dom parser class.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.18 paf 5: Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.1 parser 6:
1.20 ! paf 7: $Id: xnode.C,v 1.19 2001/12/28 14:06:50 paf Exp $
1.1 parser 8: */
9: #include "classes.h"
10: #ifdef XML
11:
12: #include "pa_request.h"
13: #include "pa_vxnode.h"
14:
15: #include "xnode.h"
16:
1.19 paf 17: #include "gdome.h"
1.1 parser 18:
19: // defines
20:
21: #define XNODE_CLASS_NAME "xnode"
22:
1.6 parser 23: // helpers
24:
1.19 paf 25: GdomeNode *as_node(Pool& pool, const String& method_name, MethodParams *params,
1.6 parser 26: int index, const char *msg) {
27: Value& value=params->as_no_junction(index, msg);
28: if(strcmp(value.type(), VXNODE_TYPE)!=0)
1.12 parser 29: throw Exception(0, 0,
1.6 parser 30: &method_name,
31: msg);
32:
33: VXnode& vnode=*static_cast<VXnode *>(&value);
1.19 paf 34: return vnode.get_node(&method_name);
1.6 parser 35: }
36:
37: // helpers
38:
1.19 paf 39: GdomeAttr * as_attr(Pool& pool, const String& method_name, MethodParams *params,
1.6 parser 40: int index, const char *msg) {
1.19 paf 41: GdomeNode *node=as_node(pool, method_name, params, index, msg);
42: GdomeException exc;
43: if(gdome_n_nodeType(node, &exc)!=GDOME_ATTRIBUTE_NODE)
1.12 parser 44: throw Exception(0, 0,
1.6 parser 45: &method_name,
46: msg);
47:
1.19 paf 48: return GDOME_A(node);
1.6 parser 49: }
1.1 parser 50:
51: // methods
52:
1.6 parser 53: // DOM1 node
54:
55: // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
56: static void _insertBefore(Request& r, const String& method_name, MethodParams *params) {
57: Pool& pool=r.pool();
58: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 59: GdomeNode *selfNode=vnode.get_node(&method_name);
60: GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node");
61: GdomeNode *refChild=as_node(pool, method_name, params, 1, "refChild must be node");
1.6 parser 62:
1.19 paf 63: GdomeException exc;
64: if(GdomeNode *retNode=gdome_n_insertBefore(selfNode, newChild, refChild, &exc)) {
65: // write out result
66: VXnode& result=*new(pool) VXnode(pool, retNode);
67: r.write_no_lang(result);
68: } else
69: throw Exception(0, 0,
70: &method_name,
71: exc);
1.6 parser 72: }
73:
74: // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
75: static void _replaceChild(Request& r, const String& method_name, MethodParams *params) {
76: Pool& pool=r.pool();
77: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 78: GdomeNode *selfNode=vnode.get_node(&method_name);
79: GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node");
80: GdomeNode *refChild=as_node(pool, method_name, params, 1, "refChild must be node");
1.6 parser 81:
1.19 paf 82: GdomeException exc;
83: if(GdomeNode *retNode=gdome_n_replaceChild(selfNode, newChild, refChild, &exc)) {
84: // write out result
85: r.write_no_lang(*new(pool) VXnode(pool, retNode));
86: } else
87: throw Exception(0, 0,
88: &method_name,
89: exc);
1.6 parser 90: }
91:
92: // Node removeChild(in Node oldChild) raises(DOMException);
93: static void _removeChild(Request& r, const String& method_name, MethodParams *params) {
94: Pool& pool=r.pool();
95: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 96: GdomeNode *selfNode=vnode.get_node(&method_name);
97: GdomeNode *oldChild=as_node(pool, method_name, params, 0, "oldChild must be node");
1.6 parser 98:
1.19 paf 99: GdomeException exc;
100: if(GdomeNode *retNode=gdome_n_removeChild(selfNode, oldChild, &exc)) {
101: // write out result
102: r.write_no_lang(*new(pool) VXnode(pool, retNode));
103: } else
104: throw Exception(0, 0,
105: &method_name,
106: exc);
1.6 parser 107: }
108:
109: // Node appendChild(in Node newChild) raises(DOMException);
110: static void _appendChild(Request& r, const String& method_name, MethodParams *params) {
111: Pool& pool=r.pool();
112: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 113: GdomeNode *selfNode=vnode.get_node(&method_name);
114: GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node");
1.6 parser 115:
1.19 paf 116: GdomeException exc;
117: if(GdomeNode *retNode=gdome_n_appendChild(selfNode, newChild, &exc)) {
118: // write out result
119: r.write_no_lang(*new(pool) VXnode(pool, retNode));
120: } else
121: throw Exception(0, 0,
122: &method_name,
123: exc);
1.6 parser 124: }
125:
126: // boolean hasChildNodes();
127: static void _hasChildNodes(Request& r, const String& method_name, MethodParams *) {
128: Pool& pool=r.pool();
129: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 130: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 131:
1.19 paf 132: GdomeException exc;
1.6 parser 133: // write out result
1.19 paf 134: VBool& result=*new(pool) VBool(pool, gdome_n_hasChildNodes(node, &exc)!=0);
1.6 parser 135: result.set_name(method_name);
136: r.write_no_lang(result);
137: }
138:
139: // Node cloneNode(in boolean deep);
1.14 parser 140: /// @test ownerDocument=?
1.6 parser 141: static void _cloneNode(Request& r, const String& method_name, MethodParams *params) {
142: Pool& pool=r.pool();
143: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 144: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 145:
146: bool deep=params->as_bool(0, "deep must be bool", r);
147:
1.19 paf 148: GdomeException exc;
1.6 parser 149: // write out result
1.19 paf 150: VXnode& result=*new(pool) VXnode(pool, gdome_n_cloneNode(node, deep, &exc));
1.6 parser 151: result.set_name(method_name);
152: r.write_no_lang(result);
153: }
154:
155: // DOM1 element
156:
1.19 paf 157: GdomeElement *get_self_element(Request& r, const String& method_name) {
1.6 parser 158: Pool& pool=r.pool();
159: VXnode& vnode=*static_cast<VXnode *>(r.self);
1.19 paf 160: GdomeNode *node=vnode.get_node(&method_name);
1.6 parser 161:
1.19 paf 162: GdomeException exc;
163: if(gdome_n_nodeType(node, &exc)!=GDOME_ELEMENT_NODE)
1.12 parser 164: throw Exception(0, 0,
1.6 parser 165: &method_name,
166: "method can be called on node of ELEMENT type");
167:
1.19 paf 168: return GDOME_EL(node);
1.6 parser 169: }
170:
171: // DOMString getAttribute(in DOMString name);
172: static void _getAttribute(Request& r, const String& method_name, MethodParams *params) {
173: Pool& pool=r.pool();
1.19 paf 174: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 175: const String& name=params->as_string(0, "name must be string");
1.6 parser 176:
1.19 paf 177: GdomeException exc;
178: GdomeDOMString *attribute_value=
179: gdome_el_getAttribute(element, pool.transcode(name), &exc);
1.6 parser 180: // write out result
181: r.write_no_lang(*new(pool) VString(pool.transcode(attribute_value)));
182: }
183:
184: // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
185: static void _setAttribute(Request& r, const String& method_name, MethodParams *params) {
186: Pool& pool=r.pool();
1.19 paf 187: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 188: const String& name=params->as_string(0, "name must be string");
189: const String& attribute_value=params->as_string(1, "value must be string");
1.6 parser 190:
1.19 paf 191: GdomeException exc;
192: gdome_el_setAttribute(element,
193: pool.transcode(name),
194: pool.transcode(attribute_value),
195: &exc);
196: if(exc)
197: throw Exception(0, 0,
198: &method_name,
199: exc);
1.6 parser 200: }
201:
202: // void removeAttribute(in DOMString name) raises(DOMException);
203: static void _removeAttribute(Request& r, const String& method_name, MethodParams *params) {
204: Pool& pool=r.pool();
1.19 paf 205: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 206: const String& name=params->as_string(0, "name must be string");
1.6 parser 207:
1.19 paf 208: GdomeException exc;
209: gdome_el_removeAttribute(element, pool.transcode(name), &exc);
210: if(exc)
211: throw Exception(0, 0,
212: &method_name,
213: exc);
1.6 parser 214: }
215:
216: // Attr getAttributeNode(in DOMString name);
217: static void _getAttributeNode(Request& r, const String& method_name, MethodParams *params) {
218: Pool& pool=r.pool();
1.19 paf 219: GdomeElement *element=get_self_element(r, method_name);
1.11 parser 220: const String& name=params->as_string(0, "name must be string");
1.6 parser 221:
1.19 paf 222: GdomeException exc;
223: if(GdomeAttr *attr=gdome_el_getAttributeNode(element, pool.transcode(name), &exc)) {
1.6 parser 224: // write out result
1.19 paf 225: VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)attr);
1.6 parser 226: r.write_no_lang(result);
1.19 paf 227: } else if(exc)
228: throw Exception(0, 0,
229: &method_name,
230: exc);
1.6 parser 231: }
232:
233: // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
234: static void _setAttributeNode(Request& r, const String& method_name, MethodParams *params) {
235: Pool& pool=r.pool();
1.19 paf 236: GdomeElement *element=get_self_element(r, method_name);
237: GdomeAttr * newAttr=as_attr(pool, method_name, params, 0, "newAttr must be ATTRIBUTE node");
1.6 parser 238:
1.19 paf 239: GdomeException exc;
240: if(GdomeAttr *returnAttr=gdome_el_setAttributeNode(element, newAttr, &exc)) {
241: // write out result
242: VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)returnAttr);
243: r.write_no_lang(result);
244: } else
245: throw Exception(0, 0,
246: &method_name,
247: exc);
1.6 parser 248: }
249:
250: // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
251: static void _removeAttributeNode(Request& r, const String& method_name, MethodParams *params) {
252: Pool& pool=r.pool();
1.19 paf 253: GdomeElement *element=get_self_element(r, method_name);
254: GdomeAttr * oldAttr=as_attr(pool, method_name, params, 0, "oldAttr must be ATTRIBUTE node");
1.6 parser 255:
1.19 paf 256: GdomeException exc;
257: gdome_el_removeAttributeNode(element, oldAttr, &exc);
258: if(exc)
259: throw Exception(0, 0,
260: &method_name,
261: exc);
1.6 parser 262: }
263:
264: // NodeList getElementsByTagName(in DOMString name);
265: static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) {
266: Pool& pool=r.pool();
1.19 paf 267: GdomeElement *element=get_self_element(r, method_name);
1.6 parser 268:
1.11 parser 269: const String& name=params->as_string(0, "name must be string");
1.6 parser 270:
271: VHash& result=*new(pool) VHash(pool);
1.19 paf 272: GdomeException exc;
273: if(GdomeNodeList *nodes=
274: gdome_el_getElementsByTagName(element, pool.transcode(name), &exc)) {
275: gulong length=gdome_nl_length(nodes, &exc);
276: for(gulong i=0; i<length; i++) {
1.6 parser 277: String& skey=*new(pool) String(pool);
278: {
279: char *buf=(char *)pool.malloc(MAX_NUMBER);
280: snprintf(buf, MAX_NUMBER, "%d", i);
281: skey << buf;
282: }
283:
1.19 paf 284: result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc)));
1.6 parser 285: }
1.19 paf 286: } else if(exc)
287: throw Exception(0, 0,
288: &method_name,
289: exc);
1.6 parser 290:
291: // write out result
292: r.write_no_lang(result);
293: }
294:
295: // void normalize();
296: static void _normalize(Request& r, const String& method_name, MethodParams *) {
1.19 paf 297: Pool& pool=r.pool();
298: VXnode& vnode=*static_cast<VXnode *>(r.self);
299: GdomeNode *selfNode=vnode.get_node(&method_name);
1.6 parser 300:
1.19 paf 301: GdomeException exc;
302: gdome_n_normalize(selfNode, &exc);
303: if(exc)
304: throw Exception(0, 0,
305: &method_name,
306: exc);
1.6 parser 307: }
308:
1.1 parser 309: static void _select(Request& r, const String& method_name, MethodParams *params) {
310: // _asm int 3;
311: Pool& pool=r.pool();
312: VXnode& vnode=*static_cast<VXnode *>(r.self);
313:
314: // expression
1.9 parser 315: const String& expression=params->as_string(0, "expression must be string");
1.16 paf 316: const char *expression_cstr=expression.cstr();
1.1 parser 317: XalanDOMString dstring(expression_cstr);
318: const XalanDOMChar *expression_dcstr=dstring.c_str();
319:
320: XPathEvaluator evaluator;
321: // We'll use these to parse the XML file.
322: XalanSourceTreeDOMSupport dom_support;
323:
324: try {
325: NodeRefList list=evaluator.selectNodeList(dom_support,
1.19 paf 326: &vnode.get_node(&method_name),
1.1 parser 327: expression_dcstr);
328:
329: VHash& result=*new(pool) VHash(pool);
330: for(int i=0; i<list.getLength(); i++) {
331: String& skey=*new(pool) String(pool);
332: {
333: char *buf=(char *)pool.malloc(MAX_NUMBER);
334: snprintf(buf, MAX_NUMBER, "%d", i);
335: skey << buf;
336: }
337:
1.17 paf 338: result.hash(0).put(skey, new(pool) VXnode(pool, list.item(i), false));
1.1 parser 339: }
340: result.set_name(method_name);
341: r.write_no_lang(result);
342: } catch(const XSLException& e) {
1.15 parser 343: Exception::provide_source(pool, &expression, e);
1.1 parser 344: }
345: }
346:
1.9 parser 347: static void _selectSingle(Request& r, const String& method_name, MethodParams *params) {
1.1 parser 348: // _asm int 3;
349: Pool& pool=r.pool();
350: VXnode& vnode=*static_cast<VXnode *>(r.self);
351:
352: // expression
1.9 parser 353: const String& expression=params->as_string(0, "expression must be string");
1.20 ! paf 354:
! 355: GdomeException exc;
! 356: GdomeDocument *document=gdome_n_ownerDocument(vnode, &exc);
! 357: xmlXPathContext *ctxt=xmlXPathNewContext(document);
! 358: ctxt->node = xmlDocGetRootElement(document);
! 359: xmlXPathObject *res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
! 360: if(ctxt->error) {
! 361: if(res)
! 362: xmlXPathFreeObject(res);
! 363: xmlXPathFreeContext(ctxt);
! 364:
! 365: throw Exception(0, 0,
! 366: expression,
! 367: "bad xpath expression (%d)", ctxt->error);
! 368: }
! 369:
! 370: xmlXPathFreeObject(res);
! 371: xmlXPathFreeContext(ctxt);
! 372: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
! 373:
1.16 paf 374: const char *expression_cstr=expression.cstr();
1.1 parser 375: XalanDOMString dstring(expression_cstr);
376: const XalanDOMChar *expression_dcstr=dstring.c_str();
377:
378: XPathEvaluator evaluator;
379: // Initialize the XalanSourceTree subsystem...
380: // XalanSourceTreeInit theSourceTreeInit;
381: // We'll use these to parse the XML file.
382: XalanSourceTreeDOMSupport dom_support;
383:
384: try {
1.19 paf 385: if(GdomeNode *node=evaluator.selectSingleNode(dom_support,
386: &vnode.get_node(&method_name),
1.1 parser 387: expression_dcstr)) {
388:
1.14 parser 389: VXnode& result=*new(pool) VXnode(pool, node, false);
1.1 parser 390: result.set_name(method_name);
391: r.write_no_lang(result);
392: }
393: } catch(const XSLException& e) {
1.15 parser 394: Exception::provide_source(pool, &expression, e);
1.1 parser 395: }
396: }
1.20 ! paf 397:
1.1 parser 398: // constructor
399:
1.2 parser 400: MXnode::MXnode(Pool& apool) : Methoded(apool),
401: consts(apool) {
1.1 parser 402: set_name(*NEW String(pool(), XNODE_CLASS_NAME));
1.6 parser 403:
404: /// DOM1 node
405:
406: // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
407: add_native_method("insertBefore", Method::CT_DYNAMIC, _insertBefore, 2, 2);
408: // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
409: add_native_method("replaceChild", Method::CT_DYNAMIC, _replaceChild, 2, 2);
410: // Node removeChild(in Node oldChild) raises(DOMException);
411: add_native_method("removeChild", Method::CT_DYNAMIC, _removeChild, 1, 1);
412: // Node appendChild(in Node newChild) raises(DOMException);
413: add_native_method("appendChild", Method::CT_DYNAMIC, _appendChild, 1, 1);
414: // boolean hasChildNodes();
415: add_native_method("hasChildNodes", Method::CT_DYNAMIC, _hasChildNodes, 0, 0);
416: // Node cloneNode(in boolean deep);
417: add_native_method("cloneNode", Method::CT_DYNAMIC, _cloneNode, 1, 1);
418:
419: /// DOM1 element
420:
421: // DOMString getAttribute(in DOMString name);
422: add_native_method("getAttribute", Method::CT_DYNAMIC, _getAttribute, 1, 1);
423: // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
424: add_native_method("setAttribute", Method::CT_DYNAMIC, _setAttribute, 2, 2);
425: // void removeAttribute(in DOMString name) raises(DOMException);
426: add_native_method("removeAttribute", Method::CT_DYNAMIC, _removeAttribute, 1, 1);
427: // Attr getAttributeNode(in DOMString name);
428: add_native_method("getAttributeNode", Method::CT_DYNAMIC, _getAttributeNode, 1, 1);
429: // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
430: add_native_method("setAttributeNode", Method::CT_DYNAMIC, _setAttributeNode, 1, 1);
431: // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
432: add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1);
433: // NodeList getElementsByTagName(in DOMString name);
434: add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
435: // void normalize();
436: add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0);
437:
438: /// parser
1.1 parser 439: // ^node.select[/some/xpath/query] = hash $.#[dnode]
440: add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);
441:
1.5 parser 442: // ^node.selectSingle[/some/xpath/query] = first dnode
1.9 parser 443: add_native_method("selectSingle", Method::CT_DYNAMIC, _selectSingle, 1, 1);
1.20 ! paf 444:
1.2 parser 445: // consts
446:
1.19 paf 447: #define CONST(name) \
448: consts.put(*new(pool()) String(pool(), #name), new(pool()) VInt(pool(), GDOME_##name))
1.2 parser 449:
1.19 paf 450: CONST(ELEMENT_NODE);
451: CONST(ATTRIBUTE_NODE);
452: CONST(TEXT_NODE);
453: CONST(CDATA_SECTION_NODE);
454: CONST(ENTITY_REFERENCE_NODE);
455: CONST(ENTITY_NODE);
456: CONST(PROCESSING_INSTRUCTION_NODE);
457: CONST(COMMENT_NODE);
458: CONST(DOCUMENT_NODE);
459: CONST(DOCUMENT_TYPE_NODE);
460: CONST(DOCUMENT_FRAGMENT_NODE);
461: CONST(NOTATION_NODE);
1.1 parser 462:
463: }
1.3 parser 464:
1.1 parser 465: // global variable
466:
467: Methoded *Xnode_class;
468:
469: #endif
470:
471: // creator
472: Methoded *MXnode_create(Pool& pool) {
473: return
474: #ifdef XML
475: Xnode_class=new(pool) MXnode(pool)
476: #else
477: 0
478: #endif
479: ;
480: }
E-mail: