JSDOMNode.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:17k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #include "JSDOMNode.hpp"
  23. #include "JSDOMNodeList.hpp"
  24. #include "JSDOMNamedNodeMap.hpp"
  25. #include "JSDOMDocument.hpp"
  26. #include "JSDOMElement.hpp"
  27. #include "JSDOMAttr.hpp"
  28. #include "JSDOMCharacterData.hpp"
  29. #include "JSDOMText.hpp"
  30. #include "JSDOMComment.hpp"
  31. #include "JSDOMCDATA.hpp"
  32. #include "JSDOMEntityReference.hpp"
  33. #include "JSDOMProcessingInstruction.hpp"
  34. #include <xercesc/dom/DOMException.hpp>
  35. // JavaScript class definition
  36. JSClass JSDOMNode::_jsClass = {
  37.   "Node", JSCLASS_HAS_PRIVATE,
  38.   JS_PropertyStub, JS_PropertyStub,
  39.   JSDOMNode::JSGetProperty, JS_PropertyStub,
  40.   JS_EnumerateStub, JS_ResolveStub,
  41.   JS_ConvertStub, JSDOMNode::JSDestructor,
  42.   0, 0, 0, 0, 
  43.   0, 0, 0, 0
  44. };
  45. bool JSDOMNode::InitNodeObject(JSContext *cx, JSObject *obj)
  46. {
  47.   JS_DefineProperties( cx, obj, JSDOMNode::_JSPropertySpec );
  48.   JS_DefineFunctions( cx, obj, JSDOMNode::_JSFunctionSpec );
  49.   return true;
  50. }
  51. // JavaScript Initialization Method
  52. JSObject *JSDOMNode::JSInit(JSContext *cx, JSObject *obj) {
  53.   if (obj==NULL)
  54.     obj = JS_GetGlobalObject(cx);
  55.   jsval oldobj;
  56.   if (JS_TRUE == JS_LookupProperty(cx, obj, JSDOMNode::_jsClass.name, &oldobj) && JSVAL_IS_OBJECT(oldobj))
  57.     return JSVAL_TO_OBJECT(oldobj);
  58.   return JS_InitClass(cx, obj, NULL, &JSDOMNode::_jsClass,
  59.                       JSDOMNode::JSConstructor, 0,
  60.                       JSDOMNode::_JSPropertySpec, JSDOMNode::_JSFunctionSpec,
  61.                       JSDOMNode::_JSPropertySpec_static, NULL);
  62. }
  63. // JavaScript Constructor
  64. JSBool JSDOMNode::JSConstructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
  65.   JSDOMNode *p = NULL;
  66.   if (argc == 0) {
  67.     p = new JSDOMNode;
  68.   }
  69.   if (!p || !JS_SetPrivate(cx, obj, p)) return JS_FALSE;
  70.   p->_JSinternal.o = obj;
  71.   p->_JSinternal.c = cx;
  72.   *rval = OBJECT_TO_JSVAL(obj);
  73.   return JS_TRUE;
  74. }
  75. // JavaScript Destructor
  76. void JSDOMNode::JSDestructor(JSContext *cx, JSObject *obj) {
  77.   JSDOMNode *p = (JSDOMNode*)JS_GetPrivate(cx, obj);
  78.   if (p) delete p;
  79. }
  80. // JavaScript Object Linking
  81. JSObject *JSDOMNode::getJSObject(JSContext *cx) {
  82.   if (!cx) return NULL;
  83.   if (!_JSinternal.o) {
  84.     _JSinternal.o = newJSObject(cx);
  85.     _JSinternal.c = cx;
  86.     if (!JS_SetPrivate(cx, _JSinternal.o, this)) return NULL;
  87.   }
  88.   return _JSinternal.o;
  89. }
  90. JSObject *JSDOMNode::newJSObject(JSContext *cx) {
  91.   return JS_NewObject(cx, &JSDOMNode::_jsClass, NULL, NULL);
  92. }
  93. // JavaScript Variable Table
  94. JSPropertySpec JSDOMNode::_JSPropertySpec[] = {
  95.     { "ELEMENT_NODE", JSDOMNode::JSVAR_ELEMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  96.     { "ATTRIBUTE_NODE", JSDOMNode::JSVAR_ATTRIBUTE_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  97.     { "TEXT_NODE", JSDOMNode::JSVAR_TEXT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  98.     { "CDATA_SECTION_NODE", JSDOMNode::JSVAR_CDATA_SECTION_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  99.     { "ENTITY_REFERENCE_NODE", JSDOMNode::JSVAR_ENTITY_REFERENCE_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  100.     { "ENTITY_NODE", JSDOMNode::JSVAR_ENTITY_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  101.     { "PROCESSING_INSTRUCTION_NODE", JSDOMNode::JSVAR_PROCESSING_INSTRUCTION_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  102.     { "COMMENT_NODE", JSDOMNode::JSVAR_COMMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  103.     { "DOCUMENT_NODE", JSDOMNode::JSVAR_DOCUMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  104.     { "nodeName", JSDOMNode::JSVAR_nodeName, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  105.     { "nodeValue", JSDOMNode::JSVAR_nodeValue, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  106.     { "nodeType", JSDOMNode::JSVAR_nodeType, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  107.     { "parentNode", JSDOMNode::JSVAR_parentNode, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  108.     { "childNodes", JSDOMNode::JSVAR_childNodes, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  109.     { "firstChild", JSDOMNode::JSVAR_firstChild, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  110.     { "lastChild", JSDOMNode::JSVAR_lastChild, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  111.     { "previousSibling", JSDOMNode::JSVAR_previousSibling, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  112.     { "nextSibling", JSDOMNode::JSVAR_nextSibling, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  113.     { "attributes", JSDOMNode::JSVAR_attributes, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  114.     { "ownerDocument", JSDOMNode::JSVAR_ownerDocument, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  115.     { "namespaceURI", JSDOMNode::JSVAR_namespaceURI, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  116.     { "prefix", JSDOMNode::JSVAR_prefix, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  117.     { "localName", JSDOMNode::JSVAR_localName, JSPROP_ENUMERATE | JSPROP_READONLY, 0, 0},
  118.     { 0, 0, 0, 0, 0 }
  119. };
  120. JSPropertySpec JSDOMNode::_JSPropertySpec_static[] = {
  121.     { "ELEMENT_NODE", JSDOMNode::JSVAR_ELEMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  122.     { "ATTRIBUTE_NODE", JSDOMNode::JSVAR_ATTRIBUTE_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  123.     { "TEXT_NODE", JSDOMNode::JSVAR_TEXT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  124.     { "CDATA_SECTION_NODE", JSDOMNode::JSVAR_CDATA_SECTION_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  125.     { "ENTITY_REFERENCE_NODE", JSDOMNode::JSVAR_ENTITY_REFERENCE_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  126.     { "ENTITY_NODE", JSDOMNode::JSVAR_ENTITY_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  127.     { "PROCESSING_INSTRUCTION_NODE", JSDOMNode::JSVAR_PROCESSING_INSTRUCTION_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  128.     { "COMMENT_NODE", JSDOMNode::JSVAR_COMMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  129.     { "DOCUMENT_NODE", JSDOMNode::JSVAR_DOCUMENT_NODE, JSPROP_ENUMERATE | JSPROP_READONLY, JSDOMNode::JSGetProperty, 0},
  130.     { 0, 0, 0, 0, 0 }
  131. };
  132. // JavaScript Get Property Wrapper
  133. JSBool JSDOMNode::JSGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
  134.    try {
  135.       if (JSVAL_IS_INT(id)) {
  136.    
  137.          JSDOMNode *priv = (JSDOMNode*)JS_GetPrivate(cx, obj);
  138.          if (priv==NULL)
  139.            *vp = JSVAL_NULL;
  140.          switch(JSVAL_TO_INT(id)) {
  141.          case JSVAR_ELEMENT_NODE:
  142.             *vp = __int_TO_JSVal(cx,JSDOMNode::ELEMENT_NODE);
  143.             break;
  144.          case JSVAR_ATTRIBUTE_NODE:
  145.             *vp = __int_TO_JSVal(cx,JSDOMNode::ATTRIBUTE_NODE);
  146.             break;
  147.          case JSVAR_TEXT_NODE:
  148.             *vp = __int_TO_JSVal(cx,JSDOMNode::TEXT_NODE);
  149.             break;
  150.          case JSVAR_CDATA_SECTION_NODE:
  151.             *vp = __int_TO_JSVal(cx,JSDOMNode::CDATA_SECTION_NODE);
  152.             break;
  153.          case JSVAR_ENTITY_REFERENCE_NODE:
  154.             *vp = __int_TO_JSVal(cx,JSDOMNode::ENTITY_REFERENCE_NODE);
  155.             break;
  156.          case JSVAR_ENTITY_NODE:
  157.             *vp = __int_TO_JSVal(cx,JSDOMNode::ENTITY_NODE);
  158.             break;
  159.          case JSVAR_PROCESSING_INSTRUCTION_NODE:
  160.             *vp = __int_TO_JSVal(cx,JSDOMNode::PROCESSING_INSTRUCTION_NODE);
  161.             break;
  162.          case JSVAR_COMMENT_NODE:
  163.             *vp = __int_TO_JSVal(cx,JSDOMNode::COMMENT_NODE);
  164.             break;
  165.          case JSVAR_DOCUMENT_NODE:
  166.             *vp = __int_TO_JSVal(cx,JSDOMNode::DOCUMENT_NODE);
  167.             break;
  168.          case JSVAR_nodeName:
  169.             if (priv)
  170.                *vp = __STRING_TO_JSVAL(priv->getNodeName());
  171.             break;
  172.          case JSVAR_nodeValue:
  173.             if (priv)
  174.                *vp = __STRING_TO_JSVAL(priv->getNodeValue());
  175.             break;
  176.          case JSVAR_nodeType:
  177.             if (priv)
  178.                *vp = __int_TO_JSVal(cx,priv->getNodeType());
  179.             break;
  180.          case JSVAR_parentNode:
  181.             if (priv) {
  182.                JSDOMNode *n = priv->getParentNode();
  183.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  184.             }
  185.             break;
  186.          case JSVAR_childNodes:
  187.             if (priv) {
  188.                JSDOMNodeList *nl = priv->getChildNodes();
  189.                *vp = (nl ? __objectp_TO_JSVal(cx,nl) : JSVAL_NULL);
  190.             }
  191.             break;
  192.          case JSVAR_firstChild:
  193.             if (priv){
  194.                JSDOMNode *n = priv->getFirstChild();
  195.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  196.             }
  197.             break;
  198.          case JSVAR_lastChild:
  199.             if (priv){
  200.                JSDOMNode *n = priv->getLastChild();
  201.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  202.             }
  203.             break;
  204.          case JSVAR_previousSibling:
  205.             if (priv){
  206.                JSDOMNode *n = priv->getPreviousSibling();
  207.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  208.             }
  209.             break;
  210.          case JSVAR_nextSibling:
  211.             if (priv){
  212.                JSDOMNode *n = priv->getNextSibling();
  213.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  214.             }
  215.             break;
  216.          case JSVAR_attributes:
  217.             if (priv){
  218.                JSDOMNamedNodeMap *nm = priv->getAttributes();
  219.                *vp = (nm ? __objectp_TO_JSVal(cx,nm) : JSVAL_NULL);
  220.             }
  221.             break;
  222.          case JSVAR_ownerDocument:
  223.             if (priv){
  224.                JSDOMNode *n = priv->getOwnerDocument();
  225.                *vp = (n ? __objectp_TO_JSVal(cx,n) : JSVAL_NULL);
  226.             }
  227.             break;
  228.          case JSVAR_namespaceURI:
  229.             if (priv)
  230.                *vp = __STRING_TO_JSVAL(priv->getNamespaceURI());
  231.             break;
  232.          case JSVAR_prefix:
  233.             if (priv)
  234.                *vp = __STRING_TO_JSVAL(priv->getPrefix());
  235.             break;
  236.          case JSVAR_localName:
  237.             if (priv)
  238.                *vp = __STRING_TO_JSVAL(priv->getLocalName());
  239.             break;
  240.          }
  241.      }
  242.   }
  243.   catch(const DOMException &dome) {
  244.     return js_throw_dom_error(cx, obj, dome.code);
  245.   }
  246.   catch( ... ) {
  247.     return js_throw_error(cx, obj, "unknown exception" );
  248.   }
  249.   return JS_TRUE;
  250. }
  251. // JavaScript Function Table
  252. JSFunctionSpec JSDOMNode::_JSFunctionSpec[] = {
  253.     { "hasAttributes", JSFUNC_hasAttributes, 0, 0, 0 },
  254.     { "hasChildNodes", JSFUNC_hasChildNodes, 0, 0, 0 },
  255.     { 0, 0, 0, 0, 0 }
  256. };
  257. // JavaScript Function Wrappers
  258. JSBool JSDOMNode::JSFUNC_hasAttributes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
  259.   JSDOMNode *p = (JSDOMNode*)JS_GetPrivate(cx, obj);
  260.   if (argc == 0) {
  261.     *rval = __bool_TO_JSVal(cx,p->hasAttributes());
  262.     return JS_TRUE;
  263.   }
  264.   return JS_FALSE;
  265. }
  266. JSBool JSDOMNode::JSFUNC_hasChildNodes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
  267.   JSDOMNode *p = (JSDOMNode*)JS_GetPrivate(cx, obj);
  268.   if (argc == 0) {
  269.     *rval = __bool_TO_JSVal(cx,p->hasChildNodes());
  270.     return JS_TRUE;
  271.   }
  272.   return JS_FALSE;
  273. }
  274. JSDOMNode *JSDOMNode::createNode(DOMNode *node, JSDOMDocument *doc, JSDOMNode *ownerNode)
  275. {
  276.   if (!node) return NULL;
  277.   JSDOMNode *jsnode = NULL;
  278.   int type = node->getNodeType();
  279.   switch( type )
  280.   {
  281.   case JSDOMNode::ELEMENT_NODE:
  282.     jsnode = new JSDOMElement( reinterpret_cast<DOMElement *>(node), doc);
  283.     break;
  284.   case JSDOMNode::ATTRIBUTE_NODE:
  285.     jsnode = new JSDOMAttr( reinterpret_cast<DOMAttr *>(node), doc, (JSDOMElement*) ownerNode );
  286.     break;
  287.   case JSDOMNode::TEXT_NODE:
  288.     jsnode = new JSDOMText( reinterpret_cast<DOMText *>(node), doc );
  289.     break;
  290.   case JSDOMNode::CDATA_SECTION_NODE:
  291.     jsnode = new JSDOMCDATA( reinterpret_cast<DOMCDATASection *>(node), doc );
  292.     break;
  293.   case JSDOMNode::ENTITY_REFERENCE_NODE:
  294.     jsnode = new JSDOMEntityReference( reinterpret_cast<DOMEntityReference *>(node), doc );
  295.     break;
  296.   case JSDOMNode::PROCESSING_INSTRUCTION_NODE:
  297.     jsnode = new JSDOMProcessingInstruction( reinterpret_cast<DOMProcessingInstruction *>(node), doc );
  298.     break;
  299.   case JSDOMNode::COMMENT_NODE:
  300.     jsnode = new JSDOMComment( reinterpret_cast<DOMComment *>(node), doc );
  301.     break;
  302.   case JSDOMNode::DOCUMENT_NODE:
  303.     jsnode = new JSDOMDocument( reinterpret_cast<DOMDocument *>(node));
  304.     break;
  305.   // !!! not it the VXML spec
  306.   //case JSDOMNode::ENTITY_NODE:  
  307.   //case DOCUMENT_TYPE_NODE:
  308.   //case DOCUMENT_FRAGMENT_NODE:
  309.   //case NOTATION_NODE:
  310.   default:
  311.     jsnode = new JSDOMNode( node, doc ); 
  312.     break;
  313.   };
  314.   return jsnode;
  315. }
  316. JSDOMNode::JSDOMNode( DOMNode *node, JSDOMDocument *owner ) : _node(node), _owner(owner)
  317. {
  318. }
  319. JSString* JSDOMNode::getNodeName()
  320. {
  321.   if (_node == NULL) return NULL;
  322.   XMLChToVXIchar name(_node->getNodeName());
  323.   GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, name.c_str());
  324.   return JS_NewUCStringCopyZ(_JSinternal.c, tmpvalue);
  325. }
  326. JSString* JSDOMNode::getNodeValue()
  327. {
  328.   if (_node == NULL) return NULL;
  329.   XMLChToVXIchar value(_node->getNodeValue());
  330.   GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, value.c_str());
  331.   return JS_NewUCStringCopyZ(_JSinternal.c, tmpvalue);
  332. }
  333. int JSDOMNode::getNodeType()
  334. {
  335.   return ( _node ? _node->getNodeType() : 0 );
  336. }
  337. JSDOMNode* JSDOMNode::getParentNode()
  338. {
  339.   return JSDOMNode::createNode(_node->getParentNode(),_owner);
  340. }
  341. JSDOMNodeList* JSDOMNode::getChildNodes()
  342. {
  343.   return new JSDOMNodeList((_node ? _node->getChildNodes() : NULL), _owner);
  344. }
  345. JSDOMNode* JSDOMNode::getFirstChild()
  346. {
  347.   return JSDOMNode::createNode(_node->getFirstChild(),_owner);
  348. }
  349. JSDOMNode* JSDOMNode::getLastChild()
  350. {
  351.   return JSDOMNode::createNode(_node->getLastChild(),_owner);
  352. }
  353. JSDOMNode* JSDOMNode::getPreviousSibling()
  354. {
  355.   return JSDOMNode::createNode(_node->getPreviousSibling(),_owner);
  356. }
  357. JSDOMNode* JSDOMNode::getNextSibling()
  358. {
  359.   return JSDOMNode::createNode(_node->getNextSibling(),_owner);
  360. }
  361. JSDOMNamedNodeMap* JSDOMNode::getAttributes()
  362. {
  363.   if (!_node) return NULL;
  364.   DOMNamedNodeMap *attrs = _node->getAttributes();
  365.   if (!attrs) return NULL;
  366.   return new JSDOMNamedNodeMap(attrs, this);
  367. }
  368. JSDOMDocument* JSDOMNode::getOwnerDocument()
  369. {
  370.   /*DOMDocument *owner = _node->getOwnerDocument();
  371.   if (!owner) return NULL;
  372.   return new JSDOMDocument(_node->getOwnerDocument());*/
  373.   return _owner;
  374. }
  375. JSString* JSDOMNode::getNamespaceURI()
  376. {
  377.   if (_node == NULL) return NULL;
  378.   const XMLCh *p = _node->getNamespaceURI();
  379.   if (!p) return NULL;
  380.   XMLChToVXIchar ns(_node->getNamespaceURI());
  381.   GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, ns.c_str());
  382.   return JS_NewUCStringCopyZ(_JSinternal.c, tmpvalue);
  383. }
  384. JSString* JSDOMNode::getPrefix()
  385. {
  386.   if (_node == NULL) return NULL;
  387.   const XMLCh *p = _node->getPrefix();
  388.   if (!p) return NULL;
  389.   XMLChToVXIchar prefix(p);
  390.   GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, prefix.c_str());
  391.   return JS_NewUCStringCopyZ(_JSinternal.c, tmpvalue);
  392. }
  393. JSString* JSDOMNode::getLocalName()
  394. {
  395.   if (_node == NULL) return NULL;
  396.   XMLChToVXIchar name(_node->getLocalName());
  397.   GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, name.c_str());
  398.   return JS_NewUCStringCopyZ(_JSinternal.c, tmpvalue);
  399. }
  400. bool JSDOMNode::hasChildNodes()
  401. {
  402.   return ( _node ? _node->hasChildNodes() : false );
  403. }
  404.  
  405. bool JSDOMNode::hasAttributes()
  406. {
  407.   return ( _node ? _node->hasAttributes() : false );
  408. }