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