|
|
| version 1.48, 2002/08/15 09:07:49 | version 1.78, 2007/08/20 08:56:46 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: @b dom parser class. | Parser: @b dom parser class. |
| Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| #include "classes.h" | #include "classes.h" |
| #ifdef XML | #ifdef XML |
| static const char* IDENT_XNODE_C="$Date$"; | static const char * const IDENT_XNODE_C="$Date$"; |
| #include "pa_vmethod_frame.h" | |
| #include "pa_charset.h" | #include "pa_charset.h" |
| #include "pa_request.h" | #include "pa_request.h" |
| #include "pa_vxnode.h" | #include "pa_vxnode.h" |
| #include "pa_vxdoc.h" | #include "pa_vxdoc.h" |
| #include "pa_vvoid.h" | #include "pa_vvoid.h" |
| #include "pa_xml_exception.h" | |
| #include "pa_vbool.h" | |
| #include "xnode.h" | #include "xnode.h" |
| extern "C" { | |
| #include "gdomecore/gdome-xml-node.h" | |
| #include "gdomecore/gdome-xml-document.h" | |
| }; | |
| #include "gdome.h" | |
| #include "libxml/xpath.h" | #include "libxml/xpath.h" |
| #include "libxml/xpathInternals.h" | |
| // global variable | |
| DECLARE_CLASS_VAR(xnode, new MXnode, 0); | |
| // classes | // classes |
| Line 94 private: | Line 97 private: |
| // helpers | // helpers |
| GdomeNode *as_node(const String& method_name, MethodParams *params, | xmlNode& as_node(MethodParams& params, int index, const char* msg) { |
| int index, const char *msg) { | Value& value=params.as_no_junction(index, msg); |
| Value& value=params->as_no_junction(index, msg); | if(Value* vxnode=value.as(VXNODE_TYPE, false)) |
| if(Value *vxnode=value.as(VXNODE_TYPE, false)) | return static_cast<VXnode*>(vxnode)->get_xmlnode(); |
| return static_cast<VXnode *>(vxnode)->get_node(&method_name); | |
| else | else |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &method_name, | 0, |
| msg); | msg); |
| } | } |
| // helpers | xmlChar* as_xmlchar(Request& r, MethodParams& params, int index, const char* msg) { |
| return r.transcode(params.as_string(index, msg)); | |
| } | |
| GdomeAttr * as_attr(Pool& pool, const String& method_name, MethodParams *params, | xmlAttr& as_attr(MethodParams& params, int index, const char* msg) { |
| int index, const char *msg) { | xmlNode& xmlnode=as_node(params, index, msg); |
| GdomeNode *node=as_node(method_name, params, index, msg); | if(xmlnode.type!=XML_ATTRIBUTE_NODE) |
| GdomeException exc; | throw Exception(PARSER_RUNTIME, |
| if(gdome_n_nodeType(node, &exc)!=GDOME_ATTRIBUTE_NODE) | 0, |
| throw Exception("parser.runtime", | |
| &method_name, | |
| msg); | msg); |
| return GDOME_A(node); | return *(xmlAttr*)&xmlnode; |
| } | } |
| static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) { | |
| if(!node|| xmlHaveGenericErrors()) | |
| throw XmlException(0); // OOM, bad name, things like that | |
| // write out result | |
| r.write_no_lang(xdoc.wrap(*node)); | |
| } | |
| static xmlNode* pa_getAttributeNodeNS(xmlNode& selfNode, | |
| const xmlChar* localName, | |
| const xmlChar* namespaceURI) | |
| { | |
| for(xmlNode* currentNode=(xmlNode*)selfNode.properties; | |
| currentNode; | |
| currentNode=currentNode->next) | |
| { | |
| if(!namespaceURI || currentNode->ns && xmlStrEqual(currentNode->ns->href, namespaceURI)) | |
| if(!localName || xmlStrEqual(currentNode->name, localName)) | |
| return currentNode; | |
| } | |
| return 0; | |
| } | |
| xmlNs& pa_xmlMapNs(xmlDoc& doc, const xmlChar *href, const xmlChar *prefix) { | |
| assert(href); | |
| // prefix can be null | |
| xmlNs *cur=doc.oldNs; | |
| while (cur != NULL && | |
| ((cur->prefix == NULL && prefix != NULL) || | |
| (cur->prefix != NULL && prefix == NULL) || | |
| !xmlStrEqual (cur->prefix, prefix)) && | |
| !xmlStrEqual (cur->href, href)) | |
| cur = cur->next; | |
| if (cur == NULL) { | |
| cur = xmlNewNs (NULL, href, prefix); | |
| if(!cur || xmlHaveGenericErrors()) | |
| throw XmlException(0); | |
| cur->next = doc.oldNs; | |
| doc.oldNs = cur; | |
| } | |
| return *cur; | |
| } | |
| /// todo: проверить, обновляется ли parent! | |
| static void pa_addAttributeNode(xmlNode& selfNode, xmlAttr& attrNode) | |
| { | |
| if(attrNode.type!=XML_ATTRIBUTE_NODE) | |
| throw Exception(PARSER_RUNTIME, | |
| 0, | |
| "must be ATTRIBUTE_NODE"); | |
| /* | |
| * Add it at the end to preserve parsing order ... | |
| */ | |
| if (selfNode.properties == NULL) { | |
| selfNode.properties = &attrNode; | |
| } else { | |
| xmlAttrPtr prev = selfNode.properties; | |
| while (prev->next != NULL) | |
| prev = prev->next; | |
| prev->next = &attrNode; | |
| attrNode.prev = prev; | |
| } | |
| if (xmlIsID(selfNode.doc, &selfNode, &attrNode) == 1) | |
| xmlAddID(NULL, selfNode.doc, xmlNodeGetContent((xmlNode*)&attrNode), &attrNode); | |
| } | |
| static const xmlChar * | |
| pa_xmlGetNsURI(xmlNode *node) { | |
| if (node == NULL || node->ns == NULL) | |
| return NULL; | |
| return node->ns->href; | |
| } | |
| #ifndef DOXYGEN | |
| struct AccumulateFoundInfo | |
| { | |
| HashStringValue* hash; | |
| VXdoc* vdoc; | |
| int index; | |
| }; | |
| #endif | |
| static void AccumulateFound(xmlNode& node, AccumulateFoundInfo* info) | |
| { | |
| info->hash->put( | |
| String::Body::Format(info->index++), | |
| &info->vdoc->wrap(node)); | |
| } | |
| template<typename I> static void | |
| pa_xmlNamedPreorderTraversal ( | |
| xmlNode *root, | |
| xmlChar *tagURI, | |
| xmlChar *tagName, | |
| void callback(xmlNode& node, I info), | |
| I info) | |
| { | |
| for(xmlNode *iter=root->children; iter; iter = iter->next) { | |
| if(iter->type == XML_ELEMENT_NODE && | |
| (xmlStrEqual(iter->name, tagName) || | |
| xmlStrEqual(tagName, (const xmlChar*)"*"))) { | |
| if(tagURI != NULL && | |
| (xmlStrEqual(pa_xmlGetNsURI(iter), tagURI) || | |
| xmlStrEqual(tagURI, (const xmlChar*)"*"))) | |
| callback(*iter, info); | |
| else if(tagURI == NULL) | |
| callback(*iter, info); | |
| } | |
| pa_xmlNamedPreorderTraversal(iter, tagURI, tagName, callback, info); | |
| } | |
| return; | |
| } | |
| // methods | // methods |
| // DOM1 node | // DOM1 node |
| // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); | // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); |
| static void _insertBefore(Request& r, const String& method_name, MethodParams *params) { | static void _insertBefore(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | |
| GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); | //xmlNode& selfNode=vnode.get_xmlnode(); |
| GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node"); | xmlNode& newChild=as_node(params, 0, "newChild must be node"); |
| xmlNode& refChild=as_node(params, 1, "refChild must be node"); | |
| GdomeException exc; | xmlNode* retNode=xmlAddPrevSibling(&refChild, &newChild); |
| if(GdomeNode *retNode=gdome_n_insertBefore(selfNode, newChild, refChild, &exc)) { | // write out result |
| // write out result | writeNode(r, vxdoc, retNode); |
| VXnode& result=*new(pool) VXnode(pool, retNode); | |
| r.write_no_lang(result); | |
| } else | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| } | } |
| // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException); | // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException); |
| static void _replaceChild(Request& r, const String& method_name, MethodParams *params) { | static void _replaceChild(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | xmlDoc& xmldoc=vxdoc.get_xmldoc(); |
| GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); | xmlNode& selfNode=vnode.get_xmlnode(); |
| GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node"); | xmlNode& newChild=as_node(params, 0, "newChild must be node"); |
| xmlNode& oldChild=as_node(params, 1, "oldChild must be node"); | |
| GdomeException exc; | |
| if(GdomeNode *retNode=gdome_n_replaceChild(selfNode, newChild, refChild, &exc)) { | if(newChild.doc!=&xmldoc) |
| // write out result | throw Exception("xml.dom", |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | 0, |
| } else | "WRONG_DOCUMENT_ERR"); |
| throw Exception( | if(oldChild.doc!=&xmldoc) |
| &method_name, | throw Exception("xml.dom", |
| exc); | 0, |
| "WRONG_DOCUMENT_ERR"); | |
| if(oldChild.parent!=&selfNode) | |
| throw Exception("xml.dom", | |
| 0, | |
| "NOT_FOUND_ERR"); | |
| xmlNode* refChild=oldChild.next; | |
| xmlUnlinkNode(&oldChild); | |
| xmlNode* retNode; | |
| if(refChild) | |
| retNode=xmlAddPrevSibling(refChild, &newChild); | |
| else | |
| retNode=xmlAddChild(&selfNode, &newChild); | |
| // write out result | |
| writeNode(r, vxdoc, retNode); | |
| } | } |
| // Node removeChild(in Node oldChild) raises(DOMException); | // Node removeChild(in Node oldChild) raises(DOMException); |
| static void _removeChild(Request& r, const String& method_name, MethodParams *params) { | static void _removeChild(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | xmlDoc& xmldoc=vxdoc.get_xmldoc(); |
| GdomeNode *oldChild=as_node(method_name, params, 0, "oldChild must be node"); | // xmlNode& selfNode=vnode.get_xmlnode(); |
| xmlNode& oldChild=as_node(params, 0, "refChild must be node"); | |
| GdomeException exc; | if(oldChild.doc!=&xmldoc) |
| if(GdomeNode *retNode=gdome_n_removeChild(selfNode, oldChild, &exc)) { | throw Exception("xml.dom", |
| // write out result | 0, |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | "WRONG_DOCUMENT_ERR"); |
| } else | |
| throw Exception( | xmlUnlinkNode(&oldChild); |
| &method_name, | // write out result |
| exc); | writeNode(r, vxdoc, &oldChild); |
| } | } |
| // Node appendChild(in Node newChild) raises(DOMException); | // Node appendChild(in Node newChild) raises(DOMException); |
| static void _appendChild(Request& r, const String& method_name, MethodParams *params) { | static void _appendChild(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | xmlNode& selfNode=vnode.get_xmlnode(); |
| GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); | xmlNode& newChild=as_node(params, 0, "newChild must be node"); |
| GdomeException exc; | xmlNode* retNode=xmlAddChild(&selfNode, &newChild); |
| if(GdomeNode *retNode=gdome_n_appendChild(selfNode, newChild, &exc)) { | // write out result |
| // write out result | writeNode(r, vxdoc, retNode); |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | |
| } else | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| } | } |
| // boolean hasChildNodes(); | // boolean hasChildNodes(); |
| static void _hasChildNodes(Request& r, const String& method_name, MethodParams *) { | static void _hasChildNodes(Request& r, MethodParams&) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | xmlNode& node=vnode.get_xmlnode(); |
| GdomeNode *node=vnode.get_node(&method_name); | |
| GdomeException exc; | |
| // write out result | // write out result |
| bool result=gdome_n_hasChildNodes(node, &exc)!=0; | bool result=node.children!=0; |
| r.write_no_lang(*new(pool) VBool(pool, result)); | r.write_no_lang(*new VBool(result)); |
| } | } |
| // Node cloneNode(in boolean deep); | // Node cloneNode(in boolean deep); |
| static void _cloneNode(Request& r, const String& method_name, MethodParams *params) { | static void _cloneNode(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | xmlNode& selfNode=vnode.get_xmlnode(); |
| GdomeNode *node=vnode.get_node(&method_name); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| xmlDoc& xmldoc=vxdoc.get_xmldoc(); | |
| bool deep=params->as_bool(0, "deep must be bool", r); | bool deep=params.as_bool(0, "deep must be bool", r); |
| GdomeException exc; | xmlNode* retNode=xmlDocCopyNode(&selfNode, &xmldoc, deep?1: 0); |
| // write out result | // write out result |
| r.write_no_lang(*new(pool) VXnode(pool, gdome_n_cloneNode(node, deep, &exc))); | writeNode(r, vxdoc, retNode); |
| } | } |
| // DOM1 element | // DOM1 element |
| GdomeElement *get_self_element(Request& r, const String& method_name) { | xmlNode& get_self_element(VXnode& vnode) { |
| Pool& pool=r.pool(); | xmlNode& node=vnode.get_xmlnode(); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | |
| GdomeNode *node=vnode.get_node(&method_name); | if(node.type!=XML_ELEMENT_NODE) |
| throw Exception(PARSER_RUNTIME, | |
| GdomeException exc; | 0, |
| if(gdome_n_nodeType(node, &exc)!=GDOME_ELEMENT_NODE) | "method can only be called on nodes of ELEMENT type"); |
| throw Exception("parser.runtime", | |
| &method_name, | return node; |
| "method can be called on node of ELEMENT type"); | } |
| return GDOME_EL(node); | |
| } | static void _getAttribute(Request& r, MethodParams& params) { |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| // DOMString getAttribute(in DOMString name); | xmlNode& element=get_self_element(vnode); |
| static void _getAttribute(Request& r, const String& method_name, MethodParams *params) { | const xmlChar* name=as_xmlchar(r, params, 0, "name must be string"); |
| Pool& pool=r.pool(); | |
| GdomeElement *element=get_self_element(r, method_name); | // todo: when name="xmlns" |
| const String& name=params->as_string(0, "name must be string"); | xmlChar* attribute_value=xmlGetProp(&element, name); |
| GdomeException exc; | |
| GdomeDOMString *attribute_value= | |
| gdome_el_getAttribute(element, pool.transcode(name).get(), &exc); | |
| // write out result | // write out result |
| r.write_no_lang(pool.transcode(attribute_value)); | r.write_pass_lang(r.transcode(attribute_value)); |
| } | } |
| // void setAttribute(in DOMString name, in DOMString value) raises(DOMException); | // void setAttribute(in DOMString name, in DOMString value) raises(DOMException); |
| static void _setAttribute(Request& r, const String& method_name, MethodParams *params) { | static void _setAttribute(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeElement *element=get_self_element(r, method_name); | xmlNode& element=get_self_element(vnode); |
| const String& name=params->as_string(0, "name must be string"); | const xmlChar* name=as_xmlchar(r, params, 0, "name must be string"); |
| const String& attribute_value=params->as_string(1, "value must be string"); | const xmlChar* attribute_value=as_xmlchar(r, params, 1, "value must be string"); |
| GdomeException exc; | // todo: when name="xmlns" |
| gdome_el_setAttribute(element, | if(!xmlSetProp(&element, name, attribute_value)) |
| pool.transcode(name).get(), | throw XmlException(0); |
| pool.transcode(attribute_value).get(), | |
| &exc); | |
| if(exc) | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| } | } |
| // void removeAttribute(in DOMString name) raises(DOMException); | // void removeAttribute(in DOMString name) raises(DOMException); |
| static void _removeAttribute(Request& r, const String& method_name, MethodParams *params) { | static void _removeAttribute(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeElement *element=get_self_element(r, method_name); | xmlNode& element=get_self_element(vnode); |
| const String& name=params->as_string(0, "name must be string"); | const xmlChar* name=as_xmlchar(r, params, 0, "name must be string"); |
| GdomeException exc; | // todo: when name="xmlns" |
| gdome_el_removeAttribute(element, pool.transcode(name).get(), &exc); | xmlUnsetProp(&element, name); |
| if(exc) | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| } | } |
| // Attr getAttributeNode(in DOMString name); | // Attr getAttributeNode(in DOMString name); |
| static void _getAttributeNode(Request& r, const String& method_name, MethodParams *params) { | static void _getAttributeNode(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeElement *element=get_self_element(r, method_name); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| const String& name=params->as_string(0, "name must be string"); | xmlNode& element=get_self_element(vnode); |
| const xmlChar* localName=as_xmlchar(r, params, 0, "name must be string"); | |
| GdomeException exc; | if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, 0)){ |
| if(GdomeAttr *attr=gdome_el_getAttributeNode(element, pool.transcode(name).get(), &exc)) { | |
| // write out result | // write out result |
| VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)attr); | writeNode(r, vxdoc, retNode); |
| r.write_no_lang(result); | } |
| } else if(exc) | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| } | } |
| // Attr setAttributeNode(in Attr newAttr) raises(DOMException); | // Attr setAttributeNode(in Attr newAttr) raises(DOMException); |
| static void _setAttributeNode(Request& r, const String& method_name, MethodParams *params) { | // Attr setAttributeNodeNS(in Attr newAttr) raises(DOMException); |
| Pool& pool=r.pool(); | static void _setAttributeNode(Request& r, MethodParams& params) { |
| GdomeElement *element=get_self_element(r, method_name); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeAttr * newAttr=as_attr(pool, method_name, params, 0, "newAttr must be ATTRIBUTE node"); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| xmlNode& element=get_self_element(vnode); | |
| GdomeException exc; | xmlDoc& xmldoc=vxdoc.get_xmldoc(); |
| if(GdomeAttr *returnAttr=gdome_el_setAttributeNode(element, newAttr, &exc)) { | xmlAttr& newAttr=as_attr(params, 0, "newAttr must be ATTRIBUTE node"); |
| if(newAttr.doc!=&xmldoc) | |
| throw Exception("xml.dom", | |
| 0, | |
| "WRONG_DOCUMENT_ERR"); | |
| if(newAttr.parent) | |
| throw Exception("xml.dom", | |
| 0, | |
| "INUSE_ATTRIBUTE_ERR"); | |
| if(xmlNode* retNode=pa_getAttributeNodeNS(element, newAttr.name, pa_xmlGetNsURI((xmlNode*)&newAttr))) { | |
| // write out result | // write out result |
| VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)returnAttr); | writeNode(r, vxdoc, retNode); |
| r.write_no_lang(result); | xmlUnlinkNode(retNode); |
| } else | } |
| throw Exception( | |
| &method_name, | pa_addAttributeNode(element, newAttr); |
| exc); | |
| } | } |
| // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException); | // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException); |
| static void _removeAttributeNode(Request& r, const String& method_name, MethodParams *params) { | static void _removeAttributeNode(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeElement *element=get_self_element(r, method_name); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| GdomeAttr * oldAttr=as_attr(pool, method_name, params, 0, "oldAttr must be ATTRIBUTE node"); | xmlNode& element=get_self_element(vnode); |
| xmlAttr& oldAttr=as_attr(params, 0, "oldAttr must be ATTRIBUTE node"); | |
| if(oldAttr.parent!=&element) | |
| throw Exception("xml.dom", | |
| 0, | |
| "NOT_FOUND_ERR"); | |
| GdomeException exc; | xmlUnlinkNode((xmlNode*)&oldAttr); |
| gdome_el_removeAttributeNode(element, oldAttr, &exc); | |
| if(exc) | // write out result |
| throw Exception( | writeNode(r, vxdoc, (xmlNode*)&oldAttr); |
| &method_name, | |
| exc); | |
| } | } |
| // NodeList getElementsByTagName(in DOMString name); | // NodeList getElementsByTagName(in DOMString name); |
| static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) { | static void _getElementsByTagName(Request& r, MethodParams& params) { |
| Pool& pool=r.pool(); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeElement *element=get_self_element(r, method_name); | VXdoc& vxdoc=vnode.get_vxdoc(); |
| xmlNode& xmlnode=vnode.get_xmlnode(); | |
| const String& name=params->as_string(0, "name must be string"); | |
| xmlChar* tagName=as_xmlchar(r, params, 0, "name must be string"); | |
| VHash& result=*new(pool) VHash(pool); | |
| GdomeException exc; | VHash& result=*new VHash; |
| if(GdomeNodeList *nodes= | AccumulateFoundInfo info={&result.hash(), &vxdoc, 0}; |
| gdome_el_getElementsByTagName(element, pool.transcode(name).get(), &exc)) { | pa_xmlNamedPreorderTraversal(&xmlnode, |
| gulong length=gdome_nl_length(nodes, &exc); | 0, |
| for(gulong i=0; i<length; i++) { | tagName, |
| String& skey=*new(pool) String(pool); | AccumulateFound, |
| { | &info); |
| char *buf=(char *)pool.malloc(MAX_NUMBER); | |
| snprintf(buf, MAX_NUMBER, "%d", i); | |
| skey << buf; | |
| } | |
| result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc))); | |
| } | |
| } else if(exc) | |
| throw Exception( | |
| &method_name, | |
| exc); | |
| // write out result | // write out result |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } | } |
| static void _getElementsByTagNameNS(Request& r, const String& method_name, MethodParams *params) { | // DOM 2 |
| Pool& pool=r.pool(); | |
| GdomeElement *element=get_self_element(r, method_name); | |
| // namespaceURI;localName | // DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName); |
| const String& namespaceURI=params->as_string(0, "namespaceURI must be string"); | static void _getAttributeNS(Request& r, MethodParams& params) { |
| const String& localName=params->as_string(1, "localName must be string"); | VXnode& vnode=GET_SELF(r, VXnode); |
| xmlNode& element=get_self_element(vnode); | |
| xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string"); | |
| GdomeException exc; | // todo: when name="xmlns" |
| VHash& result=*new(pool) VHash(pool); | xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI); |
| if(GdomeNodeList *nodes= | // write out result |
| gdome_el_getElementsByTagNameNS( | r.write_pass_lang(r.transcode(attribute_value)); |
| element, | } |
| pool.transcode(namespaceURI).get(), | |
| pool.transcode(localName).get(), | |
| &exc)) { | |
| gulong length=gdome_nl_length(nodes, &exc); | |
| for(gulong i=0; i<length; i++) { | |
| String& skey=*new(pool) String(pool); | |
| { | |
| char *buf=(char *)pool.malloc(MAX_NUMBER); | |
| snprintf(buf, MAX_NUMBER, "%d", i); | |
| skey << buf; | |
| } | |
| result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc))); | |
| } | // void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException); |
| static void _setAttributeNS(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| xmlNode& element=get_self_element(vnode); | |
| VXdoc& vxdoc=vnode.get_vxdoc(); | |
| xmlDoc& xmldoc=vxdoc.get_xmldoc(); | |
| const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| const xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string"); | |
| const xmlChar* attribute_value=as_xmlchar(r, params, 2, "value must be string"); | |
| xmlChar* prefix=0; | |
| xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix); | |
| // todo: name=xmlns | |
| xmlAttr* attrNode; | |
| if(localName) { | |
| xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix); | |
| attrNode=xmlSetNsProp(&element, &ns, | |
| localName, | |
| attribute_value); | |
| } else { | |
| attrNode=xmlSetProp(&element, | |
| qualifiedName/*unqualified, actually*/, | |
| attribute_value); | |
| } | } |
| if(!attrNode) | |
| throw XmlException(0); | |
| } | |
| // void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException); | |
| static void _removeAttributeNS(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| xmlNode& element=get_self_element(vnode); | |
| VXdoc& vxdoc=vnode.get_vxdoc(); | |
| xmlDoc& xmldoc=vxdoc.get_xmldoc(); | |
| const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string"); | |
| // todo: when name="xmlns" | |
| xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0); | |
| xmlUnsetNsProp(&element, &ns, localName); | |
| } | |
| // Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName); | |
| static void _getAttributeNodeNS(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| VXdoc& vxdoc=vnode.get_vxdoc(); | |
| xmlNode& element=get_self_element(vnode); | |
| const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string"); | |
| if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, namespaceURI)){ | |
| // write out result | |
| writeNode(r, vxdoc, retNode); | |
| } | |
| } | |
| // boolean hasAttribute(in DOMString name) raises(DOMException); | |
| static void _hasAttribute(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| xmlNode& element=get_self_element(vnode); | |
| const xmlChar* name=as_xmlchar(r, params, 0, "name must be string"); | |
| xmlChar* prop=xmlGetProp(&element, name); | |
| // todo: when name="xmlns" | |
| // write out result | |
| r.write_no_lang(*new VBool(prop!=0)); | |
| } | |
| // boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException); | |
| static void _hasAttributeNS(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| xmlNode& element=get_self_element(vnode); | |
| const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string"); | |
| xmlChar* prop=xmlGetNsProp(&element, localName, namespaceURI); | |
| // write out result | |
| r.write_no_lang(*new VBool(prop!=0)); | |
| } | |
| // boolean hasAttributes | |
| static void _hasAttributes(Request& r, MethodParams&) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| xmlNode& element=get_self_element(vnode); | |
| // write out result | |
| r.write_no_lang(*new VBool(element.properties!=0)); | |
| } | |
| static void _getElementsByTagNameNS(Request& r, MethodParams& params) { | |
| VXnode& vnode=GET_SELF(r, VXnode); | |
| VXdoc& vdoc=vnode.get_vxdoc(); | |
| xmlDoc& xmldoc=vdoc.get_xmldoc(); | |
| // namespaceURI;localName | |
| xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string"); | |
| xmlChar* localName=as_xmlchar(r, params, 1, "name must be string"); | |
| VHash& result=*new VHash; | |
| AccumulateFoundInfo info={&result.hash(), &vdoc, 0}; | |
| pa_xmlNamedPreorderTraversal((xmlNode*)&xmldoc, | |
| namespaceURI, | |
| localName, | |
| AccumulateFound, | |
| &info); | |
| // write out result | // write out result |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } | } |
| // void normalize(); | // void normalize(); |
| static void _normalize(Request& r, const String& method_name, MethodParams *) { | static void _normalize(Request&, MethodParams&) { |
| Pool& pool=r.pool(); | /*maybe someday |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=GET_SELF(r, VXnode); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | xmlNode& selfNode=vnode.get_xmlnode(); |
| GdomeException exc; | |
| gdome_n_normalize(selfNode, &exc); | gdome_n_normalize(selfNode, &exc); |
| if(exc) | if(exc) |
| throw Exception( | throw XmlException(0, exc); |
| &method_name, | */ |
| exc); | |
| } | } |
| static void _selectX(Request& r, const String& method_name, MethodParams *params, | #ifndef DOXYGEN |
| void (*handler)(Pool& pool, | struct Register_one_ns_info { |
| Request* r; | |
| xmlXPathContextPtr ctxt; | |
| }; | |
| #endif | |
| static void register_one_ns( | |
| HashStringValue::key_type key, | |
| HashStringValue::value_type value, | |
| Register_one_ns_info* info) { | |
| if(const String* svalue=value->get_string()) | |
| xmlXPathRegisterNs(info->ctxt, | |
| info->r->transcode(key), | |
| info->r->transcode(*svalue)); | |
| else | |
| throw Exception(PARSER_RUNTIME, | |
| new String(key, String::L_TAINTED), | |
| "value is %s, must be string or number", value->type()); | |
| } | |
| static void _selectX(Request& r, MethodParams& params, | |
| void (*handler)(Request& r, | |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result)) { | VXdoc& xdoc, |
| // _asm int 3; | Value*& result)) |
| Pool& pool=r.pool(); | { |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=GET_SELF(r, VXnode); |
| xmlNode& xmlnode=vnode.get_xmlnode(); | |
| VXdoc& vdoc=vnode.get_vxdoc(); | |
| xmlDoc& xmldoc=vdoc.get_xmldoc(); | |
| // expression | // expression |
| const String& expression=params->as_string(0, "expression must be string"); | const String& expression=params.as_string(0, "expression must be string"); |
| xmlXPathContext_auto_ptr ctxt(xmlXPathNewContext(&xmldoc)); | |
| GdomeException exc; | { |
| GdomeNode *dome_node=vnode.get_node(&method_name); | Register_one_ns_info info={&r, ctxt.get()}; |
| GdomeDocument *dome_document=gdome_n_ownerDocument(dome_node, &exc); | vdoc.search_namespaces.hash().for_each<Register_one_ns_info*>(register_one_ns, &info); |
| if(!dome_document) // document does not own itself, so ownerDocument = 0 | } |
| dome_document=GDOME_DOC(dome_node); // and we need downcast | ctxt->node=&xmlnode; |
| xmlDoc *xml_document=gdome_xml_doc_get_xmlDoc(dome_document); | |
| xmlXPathContext_auto_ptr ctxt(xmlXPathNewContext(xml_document)); | |
| ctxt->node=gdome_xml_n_get_xmlNode(dome_node); | |
| /*error to stderr for now*/ | /*error to stderr for now*/ |
| xmlXPathObject_auto_ptr res( | xmlXPathObject_auto_ptr res( |
| xmlXPathEvalExpression(BAD_CAST pool.transcode(expression)->str, ctxt.get())); | xmlXPathEvalExpression(r.transcode(expression), ctxt.get())); |
| if(xmlHaveGenericErrors()) { | if(xmlHaveGenericErrors()) |
| GdomeException exc=0; | throw XmlException(0); |
| throw Exception(&expression, exc); | |
| } | |
| Value *result=0; | Value* result=0; |
| if(res.get()) | if(res.get()) |
| handler(pool, expression, res, result); | handler(r, expression, res, vdoc, result); |
| if(result) | if(result) |
| r.write_no_lang(*result); | r.write_no_lang(*result); |
| } | } |
| static void selectNodesHandler(Pool& pool, | static void selectNodesHandler(Request&, |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result) { | VXdoc& xdoc, |
| VHash *vhash=new(pool) VHash(pool); result=vhash; | Value*& result) { |
| VHash& vhash=*new VHash; result=&vhash; | |
| switch(res->type) { | switch(res->type) { |
| case XPATH_UNDEFINED: | case XPATH_UNDEFINED: |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(res->nodesetval) | if(res->nodesetval) |
| if(int size=res->nodesetval->nodeNr) { | if(int size=res->nodesetval->nodeNr) { |
| Hash& hash=vhash->hash(0); | HashStringValue& hash=vhash.hash(); |
| for(int i=0; i<size; i++) { | for(int i=0; i<size; i++) |
| String& skey=*new(pool) String(pool); | hash.put( |
| { | String::Body::Format(i), |
| char *buf=(char *)pool.malloc(MAX_NUMBER); | &xdoc.wrap(*res->nodesetval->nodeTab[i])); |
| snprintf(buf, MAX_NUMBER, "%d", i); | |
| skey << buf; | |
| } | |
| hash.put(skey, new(pool) VXnode(pool, | |
| gdome_xml_n_mkref(res->nodesetval->nodeTab[i]))); | |
| } | |
| } | } |
| break; | break; |
| default: | default: |
| throw Exception(0, | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| } | } |
| } | } |
| static void selectNodeHandler(Pool& pool, | static void selectNodeHandler(Request& r, |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result) { | VXdoc& xdoc, |
| Value*& result) { | |
| switch(res->type) { | switch(res->type) { |
| case XPATH_UNDEFINED: | case XPATH_UNDEFINED: |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(res->nodesetval && res->nodesetval->nodeNr) { // empty result strangly has NODESET res->type | if(res->nodesetval && res->nodesetval->nodeNr) { // empty result strangly has NODESET res->type |
| if(res->nodesetval->nodeNr>1) | if(res->nodesetval->nodeNr>1) |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "resulted not in a single node (%d)", res->nodesetval->nodeNr); | "resulted not in a single node (%d)", res->nodesetval->nodeNr); |
| result=new(pool) VXnode(pool, gdome_xml_n_mkref(res->nodesetval->nodeTab[0])); | result=&xdoc.wrap(*res->nodesetval->nodeTab[0]); |
| } | } |
| break; | break; |
| case XPATH_BOOLEAN: | case XPATH_BOOLEAN: |
| result=new(pool) VBool(pool, res->boolval!=0); | result=new VBool(res->boolval!=0); |
| break; | break; |
| case XPATH_NUMBER: | case XPATH_NUMBER: |
| result=new(pool) VDouble(pool, res->floatval); | result=new VDouble(res->floatval); |
| break; | break; |
| case XPATH_STRING: | case XPATH_STRING: |
| result=new(pool) VString( | result=new VString(r.transcode((xmlChar*)res->stringval)); |
| pool.transcode( | |
| GdomeDOMString_auto_ptr( | |
| gdome_str_mkref_dup((const gchar *)res->stringval)).get())); | |
| break; | break; |
| default: | default: |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | |
| } | } |
| } | } |
| static void selectBoolHandler(Pool& pool, | static void selectBoolHandler(Request&, |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result) { | VXdoc& /*xdoc*/, |
| Value*& result) { | |
| switch(res->type) { | switch(res->type) { |
| case XPATH_BOOLEAN: | case XPATH_BOOLEAN: |
| result=new(pool) VBool(pool, res->boolval!=0); | result=new VBool(res->boolval!=0); |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!(res->nodesetval && res->nodesetval->nodeNr)) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| } | } |
| } | } |
| static void selectNumberHandler(Pool& pool, | static void selectNumberHandler(Request&, |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result) { | VXdoc& /*xdoc*/, |
| Value*& result) { | |
| switch(res->type) { | switch(res->type) { |
| case XPATH_NUMBER: | case XPATH_NUMBER: |
| result=new(pool) VDouble(pool, res->floatval); | result=new VDouble(res->floatval); |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!(res->nodesetval && res->nodesetval->nodeNr)) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| } | } |
| } | } |
| static void selectStringHandler(Pool& pool, | static void selectStringHandler(Request& r, |
| const String& expression, | const String& expression, |
| xmlXPathObject_auto_ptr res, | xmlXPathObject_auto_ptr res, |
| Value *& result) { | VXdoc& /*xdoc*/, |
| Value*& result) { | |
| switch(res->type) { | switch(res->type) { |
| case XPATH_UNDEFINED: | case XPATH_UNDEFINED: |
| break; | break; |
| case XPATH_STRING: | case XPATH_STRING: |
| result=new(pool) VString( | result=new VString(r.transcode((xmlChar*)res->stringval)); |
| pool.transcode( | |
| GdomeDOMString_auto_ptr( | |
| gdome_str_mkref_dup((const gchar *)res->stringval)).get())); | |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!(res->nodesetval && res->nodesetval->nodeNr)) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception("parser.runtime", | throw Exception(PARSER_RUNTIME, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| } | } |
| } | } |
| static void _select(Request& r, const String& method_name, MethodParams *params) { | static void _select(Request& r, MethodParams& params) { |
| _selectX(r, method_name, params, | _selectX(r, params, |
| selectNodesHandler); | selectNodesHandler); |
| } | } |
| static void _selectSingle(Request& r, const String& method_name, MethodParams *params) { | static void _selectSingle(Request& r, MethodParams& params) { |
| _selectX(r, method_name, params, | _selectX(r, params, |
| selectNodeHandler); | selectNodeHandler); |
| } | } |
| static void _selectBool(Request& r, const String& method_name, MethodParams *params) { | static void _selectBool(Request& r, MethodParams& params) { |
| _selectX(r, method_name, params, | _selectX(r, params, |
| selectBoolHandler); | selectBoolHandler); |
| } | } |
| static void _selectNumber(Request& r, const String& method_name, MethodParams *params) { | static void _selectNumber(Request& r, MethodParams& params) { |
| _selectX(r, method_name, params, | _selectX(r, params, |
| selectNumberHandler); | selectNumberHandler); |
| } | } |
| static void _selectString(Request& r, const String& method_name, MethodParams *params) { | static void _selectString(Request& r, MethodParams& params) { |
| _selectX(r, method_name, params, | _selectX(r, params, |
| selectStringHandler); | selectStringHandler); |
| } | } |
| // constructor | // constructor |
| MXnode::MXnode(Pool& apool, const char *aname, VStateless_class *abase) : | /// @bug one can change const and ruin other's work, we need unchangable VIntConst class |
| Methoded(apool, aname?aname:"xnode", abase), | MXnode::MXnode(const char* aname, VStateless_class *abase): |
| Methoded(aname?aname:"xnode", abase) | |
| consts(apool) | |
| { | { |
| /// DOM1 node | /// DOM1 node |
| Line 645 MXnode::MXnode(Pool& apool, const char * | Line 865 MXnode::MXnode(Pool& apool, const char * |
| // void normalize(); | // void normalize(); |
| add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0); | add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0); |
| /// DOM2 element | |
| // DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName); | |
| add_native_method("getAttributeNS", Method::CT_DYNAMIC, _getAttributeNS, 2, 2); | |
| // void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException); | |
| add_native_method("setAttributeNS", Method::CT_DYNAMIC, _setAttributeNS, 3, 3); | |
| // void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException); | |
| add_native_method("removeAttributeNS", Method::CT_DYNAMIC, _removeAttributeNS, 2, 2); | |
| // Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName); | |
| add_native_method("getAttributeNodeNS", Method::CT_DYNAMIC, _getAttributeNodeNS, 2, 2); | |
| // Attr setAttributeNodeNS(in Attr newAttr) raises(DOMException); | |
| add_native_method("setAttributeNodeNS", Method::CT_DYNAMIC, _setAttributeNode, 1, 1); | |
| // boolean hasAttribute(in DOMString name) raises(DOMException); | |
| add_native_method("hasAttribute", Method::CT_DYNAMIC, _hasAttribute, 1, 1); | |
| // boolean hasAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException); | |
| add_native_method("hasAttributeNS", Method::CT_DYNAMIC, _hasAttributeNS, 2, 2); | |
| // boolean hasAttributes | |
| add_native_method("hasAttributes", Method::CT_DYNAMIC, _hasAttributes, 0, 0); | |
| /// parser | /// parser |
| // ^node.select[/some/xpath/query] = hash $.#[dnode] | // ^node.select[/some/xpath/query] = hash $.#[dnode] |
| add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1); | add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1); |
| Line 661 MXnode::MXnode(Pool& apool, const char * | Line 901 MXnode::MXnode(Pool& apool, const char * |
| // consts | // consts |
| #define CONST(name) \ | #define CONST(name) \ |
| consts.put(*new(pool()) String(pool(), #name), new(pool()) VInt(pool(), GDOME_##name)) | consts.put(String::Body(#name), new VInt(XML_##name)) |
| #define CONST2(name, value) \ | |
| consts.put(String::Body(#name), new VInt(value)) | |
| CONST(ELEMENT_NODE); | CONST(ELEMENT_NODE); |
| CONST(ATTRIBUTE_NODE); | CONST(ATTRIBUTE_NODE); |
| CONST(TEXT_NODE); | CONST(TEXT_NODE); |
| CONST(CDATA_SECTION_NODE); | CONST(CDATA_SECTION_NODE); |
| CONST(ENTITY_REFERENCE_NODE); | CONST2(ENTITY_REFERENCE_NODE, XML_ENTITY_REF_NODE); |
| CONST(ENTITY_NODE); | CONST(ENTITY_NODE); |
| CONST(PROCESSING_INSTRUCTION_NODE); | CONST2(PROCESSING_INSTRUCTION_NODE, XML_PI_NODE); |
| CONST(COMMENT_NODE); | CONST(COMMENT_NODE); |
| CONST(DOCUMENT_NODE); | CONST(DOCUMENT_NODE); |
| CONST(DOCUMENT_TYPE_NODE); | CONST(DOCUMENT_TYPE_NODE); |
| CONST(DOCUMENT_FRAGMENT_NODE); | CONST2(DOCUMENT_FRAGMENT_NODE, XML_DOCUMENT_FRAG_NODE); |
| CONST(NOTATION_NODE); | CONST(NOTATION_NODE); |
| } | } |
| // global variable | #else |
| Methoded *Xnode_class; | // global variable |
| #endif | DECLARE_CLASS_VAR(xnode, 0, 0); // fictive |
| // creator | |
| Methoded *MXnode_create(Pool& pool) { | |
| return | |
| #ifdef XML | |
| Xnode_class=new(pool) MXnode(pool) | |
| #else | |
| 0 | |
| #endif | #endif |
| ; | |
| } |