⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sax2.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
 * xmlSAX2AttributeNs: * @ctx: the user data (XML parser context) * @localname:  the local name of the attribute * @prefix:  the attribute namespace prefix if available * @URI:  the attribute namespace name if available * @value:  Start of the attribute value * @valueend: end of the attribute value * * Handle an attribute that has been read by the parser. * The default handling is to convert the attribute into an * DOM subtree and past it in a new xmlAttr element added to * the element. */static voidxmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,                   const xmlChar * localname,                   const xmlChar * prefix,		   const xmlChar * value,		   const xmlChar * valueend){    xmlAttrPtr ret;    xmlNsPtr namespace = NULL;    xmlChar *dup = NULL;    /*     * Note: if prefix == NULL, the attribute is not in the default namespace     */    if (prefix != NULL)	namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);    /*     * allocate the node     */    if (ctxt->freeAttrs != NULL) {        ret = ctxt->freeAttrs;	ctxt->freeAttrs = ret->next;	ctxt->freeAttrsNr--;	memset(ret, 0, sizeof(xmlAttr));	ret->type = XML_ATTRIBUTE_NODE;	ret->parent = ctxt->node; 	ret->doc = ctxt->myDoc;	ret->ns = namespace;	if (ctxt->dictNames)	    ret->name = localname;	else	    ret->name = xmlStrdup(localname);        /* link at the end to preserv order, TODO speed up with a last */	if (ctxt->node->properties == NULL) {	    ctxt->node->properties = ret;	} else {	    xmlAttrPtr prev = ctxt->node->properties;	    while (prev->next != NULL) prev = prev->next;	    prev->next = ret;	    ret->prev = prev;	}	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))	    xmlRegisterNodeDefaultValue((xmlNodePtr)ret);    } else {	if (ctxt->dictNames)	    ret = xmlNewNsPropEatName(ctxt->node, namespace, 	                              (xmlChar *) localname, NULL);	else	    ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);	if (ret == NULL) {	    xmlErrMemory(ctxt, "xmlSAX2AttributeNs");	    return;	}    }    if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {	xmlNodePtr tmp;	/*	 * We know that if there is an entity reference, then	 * the string has been dup'ed and terminates with 0	 * otherwise with ' or "	 */	if (*valueend != 0) {	    tmp = xmlSAX2TextNode(ctxt, value, valueend - value);	    ret->children = tmp;	    ret->last = tmp;	    if (tmp != NULL) {		tmp->doc = ret->doc;		tmp->parent = (xmlNodePtr) ret;	    }	} else {	    ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,						    valueend - value);	    tmp = ret->children;	    while (tmp != NULL) {	        tmp->doc = ret->doc;		tmp->parent = (xmlNodePtr) ret;		if (tmp->next == NULL)		    ret->last = tmp;		tmp = tmp->next;	    }	}    } else if (value != NULL) {	xmlNodePtr tmp;	tmp = xmlSAX2TextNode(ctxt, value, valueend - value);	ret->children = tmp;	ret->last = tmp;	if (tmp != NULL) {	    tmp->doc = ret->doc;	    tmp->parent = (xmlNodePtr) ret;	}    }#ifdef LIBXML_VALID_ENABLED    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&        ctxt->myDoc && ctxt->myDoc->intSubset) {	/*	 * If we don't substitute entities, the validation should be	 * done on a value with replaced entities anyway.	 */        if (!ctxt->replaceEntities) {	    dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);	    if (dup == NULL) {	        if (*valueend == 0) {		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,				    ctxt->myDoc, ctxt->node, ret, value);		} else {		    /*		     * That should already be normalized.		     * cheaper to finally allocate here than duplicate		     * entry points in the full validation code		     */		    dup = xmlStrndup(value, valueend - value);		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,				    ctxt->myDoc, ctxt->node, ret, dup);		}	    } else {	        /*		 * dup now contains a string of the flattened attribute		 * content with entities substitued. Check if we need to		 * apply an extra layer of normalization.		 * It need to be done twice ... it's an extra burden related		 * to the ability to keep references in attributes		 */		if (ctxt->attsSpecial != NULL) {		    xmlChar *nvalnorm;		    xmlChar fn[50];		    xmlChar *fullname;		    		    fullname = xmlBuildQName(localname, prefix, fn, 50);		    if (fullname != NULL) {			ctxt->vctxt.valid = 1;		        nvalnorm = xmlValidCtxtNormalizeAttributeValue(			                 &ctxt->vctxt, ctxt->myDoc,					 ctxt->node, fullname, dup);			if (ctxt->vctxt.valid != 1)			    ctxt->valid = 0;			if ((fullname != fn) && (fullname != localname))			    xmlFree(fullname);			if (nvalnorm != NULL) {			    xmlFree(dup);			    dup = nvalnorm;			}		    }		}		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,			        ctxt->myDoc, ctxt->node, ret, dup);	    }	} else {	    /*	     * if entities already have been substitued, then	     * the attribute as passed is already normalized	     */	    dup = xmlStrndup(value, valueend - value);	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,	                             ctxt->myDoc, ctxt->node, ret, dup);	}    } else#endif /* LIBXML_VALID_ENABLED */           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&	       (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||	        ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {        /*	 * when validating, the ID registration is done at the attribute	 * validation level. Otherwise we have to do specific handling here.	 */        if ((prefix == ctxt->str_xml) &&	           (localname[0] == 'i') && (localname[1] == 'd') &&		   (localname[2] == 0)) {	    /*	     * Add the xml:id value	     *	     * Open issue: normalization of the value.	     */	    if (dup == NULL)	        dup = xmlStrndup(value, valueend - value);#ifdef LIBXML_VALID_ENABLED	    if (xmlValidateNCName(dup, 1) != 0) {	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,		      "xml:id : attribute value %s is not an NCName\n",			    (const char *) dup, NULL);	    }#endif	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {	    /* might be worth duplicate entry points and not copy */	    if (dup == NULL)	        dup = xmlStrndup(value, valueend - value);	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);	} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {	    if (dup == NULL)	        dup = xmlStrndup(value, valueend - value);	    xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);	}    }    if (dup != NULL)	xmlFree(dup);}/** * xmlSAX2StartElementNs: * @ctx:  the user data (XML parser context) * @localname:  the local name of the element * @prefix:  the element namespace prefix if available * @URI:  the element namespace name if available * @nb_namespaces:  number of namespace definitions on that node * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions * @nb_attributes:  the number of attributes on that node * @nb_defaulted:  the number of defaulted attributes. * @attributes:  pointer to the array of (localname/prefix/URI/value/end) *               attribute values. * * SAX2 callback when an element start has been detected by the parser. * It provides the namespace informations for the element, as well as * the new namespace declarations on the element. */voidxmlSAX2StartElementNs(void *ctx,                      const xmlChar *localname,		      const xmlChar *prefix,		      const xmlChar *URI,		      int nb_namespaces,		      const xmlChar **namespaces,		      int nb_attributes,		      int nb_defaulted,		      const xmlChar **attributes){    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;    xmlNodePtr ret;    xmlNodePtr parent;    xmlNsPtr last = NULL, ns;    const xmlChar *uri, *pref;    int i, j;    if (ctx == NULL) return;    parent = ctxt->node;    /*     * First check on validity:     */    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&         ((ctxt->myDoc->intSubset == NULL) ||	 ((ctxt->myDoc->intSubset->notations == NULL) && 	  (ctxt->myDoc->intSubset->elements == NULL) &&	  (ctxt->myDoc->intSubset->attributes == NULL) && 	  (ctxt->myDoc->intSubset->entities == NULL)))) {	xmlErrValid(ctxt, XML_ERR_NO_DTD,	  "Validation failed: no DTD found !", NULL, NULL);	ctxt->validate = 0;    }    /*     * allocate the node     */    if (ctxt->freeElems != NULL) {        ret = ctxt->freeElems;	ctxt->freeElems = ret->next;	ctxt->freeElemsNr--;	memset(ret, 0, sizeof(xmlNode));	ret->type = XML_ELEMENT_NODE;	if (ctxt->dictNames)	    ret->name = localname;	else {	    ret->name = xmlStrdup(localname);	    if (ret->name == NULL) {	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");		return;	    }	}	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))	    xmlRegisterNodeDefaultValue(ret);    } else {	if (ctxt->dictNames)	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 	                               (xmlChar *) localname, NULL);	else	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);	if (ret == NULL) {	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");	    return;	}    }    if (ctxt->linenumbers) {	if (ctxt->input != NULL) {	    if (ctxt->input->line < 65535)		ret->line = (short) ctxt->input->line;	    else	        ret->line = 65535;	}    }    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);    }    /*     * Build the namespace list     */    for (i = 0,j = 0;j < nb_namespaces;j++) {        pref = namespaces[i++];	uri = namespaces[i++];	ns = xmlNewNs(NULL, uri, pref);	if (ns != NULL) {	    if (last == NULL) {	        ret->nsDef = last = ns;	    } else {	        last->next = ns;		last = ns;	    }	    if ((URI != NULL) && (prefix == pref))		ret->ns = ns;	} else {	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");	    return;	}#ifdef LIBXML_VALID_ENABLED	if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&	    ctxt->myDoc && ctxt->myDoc->intSubset) {	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,	                                           ret, prefix, ns, uri);	}#endif /* LIBXML_VALID_ENABLED */    }    ctxt->nodemem = -1;    /*     * We are parsing a new node.     */    nodePush(ctxt, ret);    /*     * Link the child element     */    if (parent != NULL) {        if (parent->type == XML_ELEMENT_NODE) {	    xmlAddChild(parent, ret);	} else {	    xmlAddSibling(parent, ret);	}    }    /*     * Insert the defaulted attributes from the DTD only if requested:     */    if ((nb_defaulted != 0) &&        ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))	nb_attributes -= nb_defaulted;    /*     * Search the namespace if it wasn't already found     * Note that, if prefix is NULL, this searches for the default Ns     */    if ((URI != NULL) && (ret->ns == NULL)) {        ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);	if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {	    ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);	}	if (ret->ns == NULL) {	    ns = xmlNewNs(ret, NULL, prefix);	    if (ns == NULL) {	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");		return;	    }	    xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,			"Namespace prefix %s was not found\n",			prefix, NULL);	}    }    /*     * process all the other attributes     */    if (nb_attributes > 0) {        for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],	                       attributes[j+3], attributes[j+4]);	}    }#ifdef LIBXML_VALID_ENABLED    /*     * If it's the Document root, finish the DTD validation and     * check the document root element for validity     */    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {	int chk;	chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);	if (chk <= 0)	    ctxt->valid = 0;	if (chk < 0)	    ctxt->wellFormed = 0;	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);	ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;    }#endif /* LIBXML_VALID_ENABLED */}/** * xmlSAX2EndElementNs: * @ctx:  the user data (XML parser context) * @localname:  the local name of the element * @prefix:  the element namespace prefix if available * @URI:  the element namespace name if available * * SAX2 callback when an element end has been detected by the parser. * It provides the namespace informations for the element. */voidxmlSAX2EndElementNs(void *ctx,                    const xmlChar * localname ATTRIBUTE_UNUSED,                    const xmlChar * prefix ATTRIBUTE_UNUSED,		    const xmlChar * URI ATTRIBUTE_UNUSED){    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;    xmlParserNodeInfo node_info;    xmlNodePtr cur;    if (ctx == NULL) return;    cur = ctxt->node;    /* Capture end position and add node */    if ((ctxt->record_info) && (cur != NULL)) {        node_info.end_pos = ctxt->input->cur - ctxt->input->base;        node_info.end_line = ctxt->input->line;        node_info.node = cur;        xmlParserAddNodeInfo(ctxt, &node_info);    }    ctxt->nodemem = -1;#ifdef LIBXML_VALID_ENABLED    if (ctxt->validate && ctxt->wellFormed &&        ctxt->myDoc && ctxt->myDoc->intSubset)        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);#endif /* LIBXML_VALID_ENABLED */    /*     * end of parsing of this node.     */    nodePop(ctxt);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -