--- parser3/src/classes/xnode.C 2007/02/03 18:08:38 1.76 +++ parser3/src/classes/xnode.C 2011/05/25 04:00:40 1.85 @@ -1,13 +1,13 @@ /** @file 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 (http://paf.design.ru) */ #include "classes.h" #ifdef XML -static const char * const IDENT_XNODE_C="$Date: 2007/02/03 18:08:38 $"; +static const char * const IDENT_XNODE_C="$Date: 2011/05/25 04:00:40 $"; #include "pa_vmethod_frame.h" @@ -99,10 +99,10 @@ private: xmlNode& as_node(MethodParams& params, int index, const char* 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)->get_xmlnode(); else - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, msg); } @@ -111,10 +111,35 @@ xmlChar* as_xmlchar(Request& r, MethodPa 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) { xmlNode& xmlnode=as_node(params, index, msg); if(xmlnode.type!=XML_ATTRIBUTE_NODE) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, msg); @@ -167,11 +192,11 @@ xmlNs& pa_xmlMapNs(xmlDoc& doc, const xm return *cur; } -/// todo: проверить, обновляется ли parent! +/// @todo: проверить, обновляется ли parent! static void pa_addAttributeNode(xmlNode& selfNode, xmlAttr& attrNode) { if(attrNode.type!=XML_ATTRIBUTE_NODE) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "must be ATTRIBUTE_NODE"); @@ -330,8 +355,7 @@ static void _hasChildNodes(Request& r, M xmlNode& node=vnode.get_xmlnode(); // write out result - bool result=node.children!=0; - r.write_no_lang(*new VBool(result)); + r.write_no_lang(VBool::get(node.children!=0)); } // Node cloneNode(in boolean deep); @@ -354,7 +378,7 @@ xmlNode& get_self_element(VXnode& vnode) xmlNode& node=vnode.get_xmlnode(); if(node.type!=XML_ELEMENT_NODE) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "method can only be called on nodes of ELEMENT type"); @@ -365,9 +389,9 @@ xmlNode& get_self_element(VXnode& vnode) static void _getAttribute(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"); + 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); // write out result r.write_pass_lang(r.transcode(attribute_value)); @@ -377,10 +401,10 @@ static void _getAttribute(Request& r, Me static void _setAttribute(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"); - const xmlChar* attribute_value=as_xmlchar(r, params, 1, "value 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); - // todo: when name="xmlns" + // @todo: when name="xmlns" if(!xmlSetProp(&element, name, attribute_value)) throw XmlException(0); } @@ -389,9 +413,9 @@ static void _setAttribute(Request& r, Me static void _removeAttribute(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"); + const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); - // todo: when name="xmlns" + // @todo: when name="xmlns" xmlUnsetProp(&element, name); } @@ -400,7 +424,7 @@ static void _getAttributeNode(Request& r VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); 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)){ // write out result @@ -460,7 +484,7 @@ static void _getElementsByTagName(Reques VXdoc& vxdoc=vnode.get_vxdoc(); 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; AccumulateFoundInfo info={&result.hash(), &vxdoc, 0}; @@ -481,8 +505,8 @@ static void _getAttributeNS(Request& r, 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"); + xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); + xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING); // todo: when name="xmlns" xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI); @@ -497,14 +521,14 @@ static void _setAttributeNS(Request& r, 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* 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"); + const xmlChar* attribute_value=as_xmlchar(r, params, 2, VALUE_MUST_BE_STRING); xmlChar* prefix=0; xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix); - // todo: name=xmlns + // @todo: name=xmlns xmlAttr* attrNode; if(localName) { xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix); @@ -528,10 +552,10 @@ static void _removeAttributeNS(Request& 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"); + 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" + // @todo: when name="xmlns" xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0); xmlUnsetNsProp(&element, &ns, localName); } @@ -541,8 +565,8 @@ static void _getAttributeNodeNS(Request& 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"); + 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 @@ -555,12 +579,11 @@ static void _hasAttribute(Request& r, Me VXnode& vnode=GET_SELF(r, VXnode); 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 - 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); @@ -568,12 +591,20 @@ static void _hasAttributeNS(Request& r, 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"); + const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_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 - r.write_no_lang(*new VBool(prop!=0)); + r.write_no_lang(VBool::get(element.properties!=0)); } static void _getElementsByTagNameNS(Request& r, MethodParams& params) { @@ -582,8 +613,8 @@ static void _getElementsByTagNameNS(Requ 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"); + 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}; @@ -625,7 +656,7 @@ static void register_one_ns( info->r->transcode(key), info->r->transcode(*svalue)); else - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, new String(key, String::L_TAINTED), "value is %s, must be string or number", value->type()); } @@ -683,7 +714,7 @@ static void selectNodesHandler(Request&, } break; default: - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "wrong xmlXPathEvalExpression result type (%d)", res->type); break; // never @@ -699,9 +730,9 @@ static void selectNodeHandler(Request& r case XPATH_UNDEFINED: break; 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) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "resulted not in a single node (%d)", res->nodesetval->nodeNr); @@ -709,7 +740,7 @@ static void selectNodeHandler(Request& r } break; case XPATH_BOOLEAN: - result=new VBool(res->boolval!=0); + result=&VBool::get(res->boolval!=0); break; case XPATH_NUMBER: result=new VDouble(res->floatval); @@ -718,7 +749,7 @@ static void selectNodeHandler(Request& r result=new VString(r.transcode((xmlChar*)res->stringval)); break; default: - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "wrong xmlXPathEvalExpression result type (%d)", res->type); } @@ -731,14 +762,14 @@ static void selectBoolHandler(Request&, Value*& result) { switch(res->type) { case XPATH_BOOLEAN: - result=new VBool(res->boolval!=0); + result=&VBool::get(res->boolval!=0); break; case XPATH_NODESET: if(!(res->nodesetval && res->nodesetval->nodeNr)) break; // else[nodeset] fall down to default default: - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "wrong xmlXPathEvalExpression result type (%d)", res->type); break; // never @@ -759,7 +790,7 @@ static void selectNumberHandler(Request& break; // else[nodeset] fall down to default default: - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "wrong xmlXPathEvalExpression result type (%d)", res->type); break; // never @@ -782,7 +813,7 @@ static void selectStringHandler(Request& break; // else[nodeset] fall down to default default: - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &expression, "wrong xmlXPathEvalExpression result type (%d)", res->type); break; // never @@ -872,6 +903,9 @@ MXnode::MXnode(const char* aname, VState 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 // ^node.select[/some/xpath/query] = hash $.#[dnode]