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

📄 sax2.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	ret->content = (xmlChar *) intern;

    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
	xmlRegisterNodeDefaultValue(ret);
    return(ret);
}

#ifdef LIBXML_VALID_ENABLED
/*
 * xmlSAX2DecodeAttrEntities:
 * @ctxt:  the parser context
 * @str:  the input string
 * @len: the string length
 * 
 * Remove the entities from an attribute value
 *
 * Returns the newly allocated string or NULL if not needed or error
 */
static xmlChar *
xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
                          const xmlChar *end) {
    const xmlChar *in;
    xmlChar *ret;

    in = str;
    while (in < end)
        if (*in++ == '&')
	    goto decode;
    return(NULL);
decode:
    ctxt->depth++;
    ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
				     XML_SUBSTITUTE_REF, 0,0,0);
    ctxt->depth--;
    return(ret);
}
#endif /* LIBXML_VALID_ENABLED */

/**
 * 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 void
xmlSAX2AttributeNs(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 (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);
        } else 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);
	}
    }
    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.
 */
void
xmlSAX2StartElementNs(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) {
	    ns = xmlNewNs(ret, NULL, prefix);
	    if (ns == NULL) {
	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
		return;
	    }
	    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
		ctxt->sax->warning(ctxt->userData, 
		     "Namespace prefix %s was not found\n", prefix);
	}
    }

    /*
     * 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-

⌨️ 快捷键说明

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