Diff for /parser3/src/classes/xnode.C between versions 1.76 and 1.85

version 1.76, 2007/02/03 18:08:38 version 1.85, 2011/05/25 04:00:40
Line 1 Line 1
 /** @file  /** @file
         Parser: @b dom parser class.          Parser: @b dom parser class.
   
         Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2009 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"
Line 99  private: Line 99  private:
   
 xmlNode& as_node(MethodParams& params, int index, const char* msg) {  xmlNode& as_node(MethodParams& params, 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))
                 return static_cast<VXnode*>(vxnode)->get_xmlnode();                  return static_cast<VXnode*>(vxnode)->get_xmlnode();
         else          else
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         msg);                          msg);
 }  }
Line 111  xmlChar* as_xmlchar(Request& r, MethodPa Line 111  xmlChar* as_xmlchar(Request& r, MethodPa
         return r.transcode(params.as_string(index, msg));          return r.transcode(params.as_string(index, msg));
 }  }
   
   xmlChar* as_xmlqname(Request& r, MethodParams& params, int index, const char* msg) {
           xmlChar* qname=r.transcode(params.as_string(index, msg ? msg : XML_QUALIFIED_NAME_MUST_BE_STRING));
           if(xmlValidateQName(qname, 0))
                   throw XmlException(0, XML_INVALID_QUALIFIED_NAME, qname);
           return qname;
   }
   
   xmlChar* as_xmlncname(Request& r, MethodParams& params, int index, const char* msg) {
           xmlChar* ncname=r.transcode(params.as_string(index, msg ? msg : XML_NC_NAME_MUST_BE_STRING));
           if(xmlValidateNCName(ncname, 0))
                   throw XmlException(0, XML_INVALID_NC_NAME, ncname);
           return ncname;
   }
   
   xmlChar* as_xmlname(Request& r, MethodParams& params, int index, const char* msg) {
           xmlChar* localName=r.transcode(params.as_string(index, msg ? msg : XML_LOCAL_NAME_MUST_BE_STRING));
           if(xmlValidateName(localName, 0))
                   throw XmlException(0, XML_INVALID_LOCAL_NAME, localName);
           return localName;
   }
   
   xmlChar* as_xmlnsuri(Request& r, MethodParams& params, int index) {
           return r.transcode(params.as_string(index, XML_NAMESPACEURI_MUST_BE_STRING));
   }
   
 xmlAttr& as_attr(MethodParams& params, int index, const char* msg) {  xmlAttr& as_attr(MethodParams& params, int index, const char* msg) {
         xmlNode& xmlnode=as_node(params, index, msg);          xmlNode& xmlnode=as_node(params, index, msg);
         if(xmlnode.type!=XML_ATTRIBUTE_NODE)          if(xmlnode.type!=XML_ATTRIBUTE_NODE)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         msg);                          msg);
   
Line 167  xmlNs& pa_xmlMapNs(xmlDoc& doc, const xm Line 192  xmlNs& pa_xmlMapNs(xmlDoc& doc, const xm
         return *cur;          return *cur;
 }  }
   
 /// todo: проверить, обновляется ли parent!  /// @todo: проверить, обновляется ли parent!
 static void pa_addAttributeNode(xmlNode& selfNode, xmlAttr& attrNode)   static void pa_addAttributeNode(xmlNode& selfNode, xmlAttr& attrNode) 
 {  {
         if(attrNode.type!=XML_ATTRIBUTE_NODE)          if(attrNode.type!=XML_ATTRIBUTE_NODE)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         "must be ATTRIBUTE_NODE");                          "must be ATTRIBUTE_NODE");
   
Line 330  static void _hasChildNodes(Request& r, M Line 355  static void _hasChildNodes(Request& r, M
         xmlNode& node=vnode.get_xmlnode();          xmlNode& node=vnode.get_xmlnode();
   
         // write out result          // write out result
         bool result=node.children!=0;          r.write_no_lang(VBool::get(node.children!=0));
         r.write_no_lang(*new VBool(result));  
 }  }
   
 // Node cloneNode(in boolean deep);  // Node cloneNode(in boolean deep);
Line 354  xmlNode& get_self_element(VXnode& vnode) Line 378  xmlNode& get_self_element(VXnode& vnode)
         xmlNode& node=vnode.get_xmlnode();          xmlNode& node=vnode.get_xmlnode();
   
         if(node.type!=XML_ELEMENT_NODE)          if(node.type!=XML_ELEMENT_NODE)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         0,                          0,
                         "method can only be called on nodes of ELEMENT type");                          "method can only be called on nodes of ELEMENT type");
   
Line 365  xmlNode& get_self_element(VXnode& vnode) Line 389  xmlNode& get_self_element(VXnode& vnode)
 static void _getAttribute(Request& r, MethodParams& params) {  static void _getAttribute(Request& r, MethodParams& params) {
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         // todo: when name="xmlns"          // @todo: when name="xmlns"
         xmlChar* attribute_value=xmlGetProp(&element, name);          xmlChar* attribute_value=xmlGetProp(&element, name);
         // write out result          // write out result
         r.write_pass_lang(r.transcode(attribute_value));          r.write_pass_lang(r.transcode(attribute_value));
Line 377  static void _getAttribute(Request& r, Me Line 401  static void _getAttribute(Request& r, Me
 static void _setAttribute(Request& r, MethodParams& params) {  static void _setAttribute(Request& r, MethodParams& params) {
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
         const xmlChar* attribute_value=as_xmlchar(r, params, 1, "value must be string");          const xmlChar* attribute_value=as_xmlchar(r, params, 1, VALUE_MUST_BE_STRING);
   
         // todo: when name="xmlns"          // @todo: when name="xmlns"
         if(!xmlSetProp(&element, name,  attribute_value))          if(!xmlSetProp(&element, name,  attribute_value))
                 throw XmlException(0);                  throw XmlException(0);
 }  }
Line 389  static void _setAttribute(Request& r, Me Line 413  static void _setAttribute(Request& r, Me
 static void _removeAttribute(Request& r, MethodParams& params) {  static void _removeAttribute(Request& r, MethodParams& params) {
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         // todo: when name="xmlns"          // @todo: when name="xmlns"
         xmlUnsetProp(&element, name);          xmlUnsetProp(&element, name);
 }  }
   
Line 400  static void _getAttributeNode(Request& r Line 424  static void _getAttributeNode(Request& r
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         VXdoc& vxdoc=vnode.get_vxdoc();          VXdoc& vxdoc=vnode.get_vxdoc();
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         const xmlChar* localName=as_xmlchar(r, params, 0, "name must be string");          const xmlChar* localName=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, 0)){          if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, 0)){
                 // write out result                  // write out result
Line 460  static void _getElementsByTagName(Reques Line 484  static void _getElementsByTagName(Reques
         VXdoc& vxdoc=vnode.get_vxdoc();          VXdoc& vxdoc=vnode.get_vxdoc();
         xmlNode& xmlnode=vnode.get_xmlnode();          xmlNode& xmlnode=vnode.get_xmlnode();
   
         xmlChar* tagName=as_xmlchar(r, params, 0, "name must be string");          xmlChar* tagName=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         VHash& result=*new VHash;          VHash& result=*new VHash;
         AccumulateFoundInfo info={&result.hash(), &vxdoc, 0};          AccumulateFoundInfo info={&result.hash(), &vxdoc, 0};
Line 481  static void _getAttributeNS(Request& r, Line 505  static void _getAttributeNS(Request& r,
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
                   
         xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");          xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING);
   
         // todo: when name="xmlns"          // todo: when name="xmlns"
         xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI);          xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI);
Line 497  static void _setAttributeNS(Request& r, Line 521  static void _setAttributeNS(Request& r,
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         VXdoc& vxdoc=vnode.get_vxdoc();          VXdoc& vxdoc=vnode.get_vxdoc();
         xmlDoc& xmldoc=vxdoc.get_xmldoc();          xmlDoc& xmldoc=vxdoc.get_xmldoc();
         const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          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* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string");
         const xmlChar* attribute_value=as_xmlchar(r, params, 2, "value must be string");          const xmlChar* attribute_value=as_xmlchar(r, params, 2, VALUE_MUST_BE_STRING);
   
         xmlChar* prefix=0;          xmlChar* prefix=0;
         xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);          xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);
   
         // todo: name=xmlns          // @todo: name=xmlns
         xmlAttr* attrNode;          xmlAttr* attrNode;
         if(localName) {          if(localName) {
                 xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix);                  xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix);
Line 528  static void _removeAttributeNS(Request& Line 552  static void _removeAttributeNS(Request&
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         VXdoc& vxdoc=vnode.get_vxdoc();          VXdoc& vxdoc=vnode.get_vxdoc();
         xmlDoc& xmldoc=vxdoc.get_xmldoc();          xmlDoc& xmldoc=vxdoc.get_xmldoc();
         const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");          const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING);
   
         // todo: when name="xmlns"          // @todo: when name="xmlns"
         xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0);          xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0);
         xmlUnsetNsProp(&element, &ns, localName);          xmlUnsetNsProp(&element, &ns, localName);
 }  }
Line 541  static void _getAttributeNodeNS(Request& Line 565  static void _getAttributeNodeNS(Request&
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         VXdoc& vxdoc=vnode.get_vxdoc();          VXdoc& vxdoc=vnode.get_vxdoc();
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
         const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");          const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING);
   
         if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, namespaceURI)){          if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, namespaceURI)){
                 // write out result                  // write out result
Line 555  static void _hasAttribute(Request& r, Me Line 579  static void _hasAttribute(Request& r, Me
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
   
         const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");          const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING);
   
         xmlChar* prop=xmlGetProp(&element, name);          // @todo: when name="xmlns"
         // todo: when name="xmlns"  
         // write out result          // write out result
         r.write_no_lang(*new VBool(prop!=0));          r.write_no_lang(VBool::get(xmlHasProp(&element, name)!=0));
 }  }
   
 // boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException);  // boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException);
Line 568  static void _hasAttributeNS(Request& r, Line 591  static void _hasAttributeNS(Request& r,
         VXnode& vnode=GET_SELF(r, VXnode);          VXnode& vnode=GET_SELF(r, VXnode);
         xmlNode& element=get_self_element(vnode);          xmlNode& element=get_self_element(vnode);
   
         const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");          const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING);
   
           // write out result
           r.write_no_lang(VBool::get(xmlHasNsProp(&element, localName, namespaceURI)!=0));
   }
   
   // boolean hasAttributes
   static void _hasAttributes(Request& r, MethodParams&) {
           VXnode& vnode=GET_SELF(r, VXnode);
           xmlNode& element=get_self_element(vnode);
   
         xmlChar* prop=xmlGetNsProp(&element, localName, namespaceURI);  
         // write out result          // write out result
         r.write_no_lang(*new VBool(prop!=0));          r.write_no_lang(VBool::get(element.properties!=0));
 }  }
   
 static void _getElementsByTagNameNS(Request& r, MethodParams& params) {  static void _getElementsByTagNameNS(Request& r, MethodParams& params) {
Line 582  static void _getElementsByTagNameNS(Requ Line 613  static void _getElementsByTagNameNS(Requ
         xmlDoc& xmldoc=vdoc.get_xmldoc();          xmlDoc& xmldoc=vdoc.get_xmldoc();
   
         // namespaceURI;localName          // namespaceURI;localName
         xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");          xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING);
         xmlChar* localName=as_xmlchar(r, params, 1, "name must be string");          xmlChar* localName=as_xmlchar(r, params, 1, NAME_MUST_BE_STRING);
   
         VHash& result=*new VHash;          VHash& result=*new VHash;
         AccumulateFoundInfo info={&result.hash(), &vdoc, 0};          AccumulateFoundInfo info={&result.hash(), &vdoc, 0};
Line 625  static void register_one_ns( Line 656  static void register_one_ns(
                         info->r->transcode(key),                           info->r->transcode(key), 
                         info->r->transcode(*svalue));                          info->r->transcode(*svalue));
         else          else
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                         new String(key, String::L_TAINTED),                          new String(key, String::L_TAINTED),
                         "value is %s, must be string or number", value->type());                          "value is %s, must be string or number", value->type());
 }  }
Line 683  static void selectNodesHandler(Request&, Line 714  static void selectNodesHandler(Request&,
                         }                          }
                 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                  break; // never
Line 699  static void selectNodeHandler(Request& r Line 730  static void selectNodeHandler(Request& r
         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 strangely 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);
                                                   
Line 709  static void selectNodeHandler(Request& r Line 740  static void selectNodeHandler(Request& r
                 }                  }
                 break;                  break;
         case XPATH_BOOLEAN:           case XPATH_BOOLEAN: 
                 result=new VBool(res->boolval!=0);                  result=&VBool::get(res->boolval!=0);
                 break;                  break;
         case XPATH_NUMBER:           case XPATH_NUMBER: 
                 result=new VDouble(res->floatval);                  result=new VDouble(res->floatval);
Line 718  static void selectNodeHandler(Request& r Line 749  static void selectNodeHandler(Request& r
                 result=new VString(r.transcode((xmlChar*)res->stringval));                  result=new VString(r.transcode((xmlChar*)res->stringval));
                 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);
         }          }
Line 731  static void selectBoolHandler(Request&, Line 762  static void selectBoolHandler(Request&,
                               Value*& result) {                                Value*& result) {
         switch(res->type) {          switch(res->type) {
         case XPATH_BOOLEAN:           case XPATH_BOOLEAN: 
                 result=new VBool(res->boolval!=0);                  result=&VBool::get(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
Line 759  static void selectNumberHandler(Request& Line 790  static void selectNumberHandler(Request&
                         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
Line 782  static void selectStringHandler(Request& Line 813  static void selectStringHandler(Request&
                         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
Line 872  MXnode::MXnode(const char* aname, VState Line 903  MXnode::MXnode(const char* aname, VState
         add_native_method("hasAttribute", Method::CT_DYNAMIC, _hasAttribute, 1, 1);          add_native_method("hasAttribute", Method::CT_DYNAMIC, _hasAttribute, 1, 1);
         // boolean hasAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);          // boolean hasAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
         add_native_method("hasAttributeNS", Method::CT_DYNAMIC, _hasAttributeNS, 2, 2);          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]

Removed from v.1.76  
changed lines
  Added in v.1.85


E-mail: