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

📄 c14n.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 4 页
字号:
 * with href="http://www.w3.org/XML/1998/namespace" * * Returns 1 if the node is default or 0 otherwise *//* todo: make it a define? */static intxmlC14NIsXmlNs(xmlNsPtr ns){    return ((ns != NULL) &&            (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&            (xmlStrEqual(ns->href,                         BAD_CAST                         "http://www.w3.org/XML/1998/namespace")));}/** * xmlC14NNsCompare: * @ns1:		the pointer to first namespace * @ns2: 		the pointer to second namespace * * Compares the namespaces by names (prefixes). * * Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2. */static intxmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2){    if (ns1 == ns2)        return (0);    if (ns1 == NULL)        return (-1);    if (ns2 == NULL)        return (1);    return (xmlStrcmp(ns1->prefix, ns2->prefix));}/** * xmlC14NPrintNamespaces: * @ns:			the pointer to namespace * @ctx: 		the C14N context * * Prints the given namespace to the output buffer from C14N context. * * Returns 1 on success or 0 on fail. */static intxmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx){    if ((ns == NULL) || (ctx == NULL)) {        xmlC14NErrParam("writing namespaces");        return 0;    }    if (ns->prefix != NULL) {        xmlOutputBufferWriteString(ctx->buf, " xmlns:");        xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);        xmlOutputBufferWriteString(ctx->buf, "=\"");    } else {        xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");    }    if(ns->href != NULL) {	xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);    }    xmlOutputBufferWriteString(ctx->buf, "\"");    return (1);}/** * xmlC14NProcessNamespacesAxis: * @ctx: 		the C14N context * @node:		the current node * * Prints out canonical namespace axis of the current node to the * buffer from C14N context as follows  * * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n) * * Namespace Axis * Consider a list L containing only namespace nodes in the  * axis and in the node-set in lexicographic order (ascending). To begin  * processing L, if the first node is not the default namespace node (a node  * with no namespace URI and no local name), then generate a space followed  * by xmlns="" if and only if the following conditions are met: *    - the element E that owns the axis is in the node-set *    - The nearest ancestor element of E in the node-set has a default  *	    namespace node in the node-set (default namespace nodes always  *      have non-empty values in XPath) * The latter condition eliminates unnecessary occurrences of xmlns="" in  * the canonical form since an element only receives an xmlns="" if its  * default namespace is empty and if it has an immediate parent in the  * canonical form that has a non-empty default namespace. To finish  * processing  L, simply process every namespace node in L, except omit  * namespace node with local name xml, which defines the xml prefix,  * if its string value is http://www.w3.org/XML/1998/namespace. * * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n) * Canonical XML applied to a document subset requires the search of the  * ancestor nodes of each orphan element node for attributes in the xml  * namespace, such as xml:lang and xml:space. These are copied into the  * element node except if a declaration of the same attribute is already  * in the attribute axis of the element (whether or not it is included in  * the document subset). This search and copying are omitted from the  * Exclusive XML Canonicalization method. * * Returns 0 on success or -1 on fail. */static intxmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible){    xmlNodePtr n;    xmlNsPtr ns, tmp;    xmlListPtr list;    int already_rendered;    int has_empty_ns = 0;        if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {        xmlC14NErrParam("processing namespaces axis (c14n)");        return (-1);    }    /*     * Create a sorted list to store element namespaces     */    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);    if (list == NULL) {        xmlC14NErrInternal("creating namespaces list (c14n)");        return (-1);    }    /* check all namespaces */    for(n = cur; n != NULL; n = n->parent) {	for(ns = n->nsDef; ns != NULL; ns = ns->next) {	    tmp = xmlSearchNs(cur->doc, cur, ns->prefix);	    	    if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);		if(visible) {        	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);		}		if(!already_rendered) {		    xmlListInsert(list, ns); 		}    		if(xmlStrlen(ns->prefix) == 0) {		    has_empty_ns = 1;		}	    }	}    }	    /**     * if the first node is not the default namespace node (a node with no      * namespace URI and no local name), then generate a space followed by      * xmlns="" if and only if the following conditions are met:     *  - the element E that owns the axis is in the node-set     *  - the nearest ancestor element of E in the node-set has a default      *     namespace node in the node-set (default namespace nodes always      *     have non-empty values in XPath)     */    if(visible && !has_empty_ns) {        static xmlNs ns_default;        memset(&ns_default, 0, sizeof(ns_default));        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {    	    xmlC14NPrintNamespaces(&ns_default, ctx);	}    }	        /*      * print out all elements from list      */    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);    /*      * Cleanup     */    xmlListDelete(list);    return (0);}/** * xmlExcC14NProcessNamespacesAxis: * @ctx: 		the C14N context * @node:		the current node * * Prints out exclusive canonical namespace axis of the current node to the * buffer from C14N context as follows  * * Exclusive XML Canonicalization * http://www.w3.org/TR/xml-exc-c14n * * If the element node is in the XPath subset then output the node in  * accordance with Canonical XML except for namespace nodes which are  * rendered as follows: * * 1. Render each namespace node iff: *    * it is visibly utilized by the immediate parent element or one of  *      its attributes, or is present in InclusiveNamespaces PrefixList, and *    * its prefix and value do not appear in ns_rendered. ns_rendered is  *      obtained by popping the state stack in order to obtain a list of  *      prefixes and their values which have already been rendered by  *      an output ancestor of the namespace node's parent element. * 2. Append the rendered namespace node to the list ns_rendered of namespace  * nodes rendered by output ancestors. Push ns_rendered on state stack and  * recurse. * 3. After the recursion returns, pop thestate stack. * * * Returns 0 on success or -1 on fail. */static intxmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible){    xmlNsPtr ns;    xmlListPtr list;    xmlAttrPtr attr;    int already_rendered;    int has_empty_ns = 0;    int has_visibly_utilized_empty_ns = 0;    int has_empty_ns_in_inclusive_list = 0;            if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {        xmlC14NErrParam("processing namespaces axis (exc c14n)");        return (-1);    }    if(!ctx->exclusive) {        xmlC14NErrParam("processing namespaces axis (exc c14n)");        return (-1);    }    /*     * Create a sorted list to store element namespaces     */    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);    if (list == NULL) {        xmlC14NErrInternal("creating namespaces list (exc c14n)");        return (-1);    }    /*      * process inclusive namespaces:     * All namespace nodes appearing on inclusive ns list are      * handled as provided in Canonical XML     */    if(ctx->inclusive_ns_prefixes != NULL) {	xmlChar *prefix; 	int i;		for (i = 0; ctx->inclusive_ns_prefixes[i] != NULL; ++i) {	    prefix = ctx->inclusive_ns_prefixes[i];	    /*	     * Special values for namespace with empty prefix	     */            if (xmlStrEqual(prefix, BAD_CAST "#default")                || xmlStrEqual(prefix, BAD_CAST "")) {                prefix = NULL;		has_empty_ns_in_inclusive_list = 1;            }		    ns = xmlSearchNs(cur->doc, cur, prefix);	    	    if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {		already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);		if(visible) {    	    	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);		}		if(!already_rendered) {	    	    xmlListInsert(list, ns); 		}    		if(xmlStrlen(ns->prefix) == 0) {		    has_empty_ns = 1;		}	    }	}    }        /* add node namespace */    if(cur->ns != NULL) {	ns = cur->ns;    } else {        ns = xmlSearchNs(cur->doc, cur, NULL);	has_visibly_utilized_empty_ns = 1;    }    if((ns != NULL) && !xmlC14NIsXmlNs(ns)) {	if(visible && xmlC14NIsVisible(ctx, ns, cur)) { 	    if(!xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, ns, ctx)) {		xmlListInsert(list, ns);	    }	}	if(visible) {    	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur); 	}	if(xmlStrlen(ns->prefix) == 0) {	    has_empty_ns = 1;	}    }                /* add attributes */    for(attr = cur->properties; attr != NULL; attr = attr->next) {        /*          * we need to check that attribute is visible and has non         * default namespace (XML Namespaces: "default namespaces     	 * do not apply directly to attributes")	          */	if((attr->ns != NULL) && !xmlC14NIsXmlNs(attr->ns) && xmlC14NIsVisible(ctx, attr, cur)) {	    already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);	    xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, cur); 	    if(!already_rendered && visible) {		xmlListInsert(list, attr->ns); 	    }	    if(xmlStrlen(attr->ns->prefix) == 0) {		has_empty_ns = 1;	    }	} else if((attr->ns != NULL) && (xmlStrlen(attr->ns->prefix) == 0) && (xmlStrlen(attr->ns->href) == 0)) {	    has_visibly_utilized_empty_ns = 1;	}    }    /*     * Process xmlns=""     */    if(visible && has_visibly_utilized_empty_ns && 	    !has_empty_ns && !has_empty_ns_in_inclusive_list) {        static xmlNs ns_default;        memset(&ns_default, 0, sizeof(ns_default));	        already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default, ctx);	if(!already_rendered) {    	    xmlC14NPrintNamespaces(&ns_default, ctx);	}    } else if(visible && !has_empty_ns && has_empty_ns_in_inclusive_list) {        static xmlNs ns_default;        memset(&ns_default, 0, sizeof(ns_default));        if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {    	    xmlC14NPrintNamespaces(&ns_default, ctx);	}    }        /*      * print out all elements from list      */    xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);    /*      * Cleanup     */    xmlListDelete(list);    return (0);}/** * xmlC14NAttrsCompare: * @attr1:		the pointer tls o first attr * @attr2: 		the pointer to second attr * * Prints the given attribute to the output buffer from C14N context. * * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2. */static intxmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2){    int ret = 0;    /*     * Simple cases     */    if (attr1 == attr2)        return (0);    if (attr1 == NULL)        return (-1);    if (attr2 == NULL)        return (1);    if (attr1->ns == attr2->ns) {        return (xmlStrcmp(attr1->name, attr2->name));    }    /*      * Attributes in the default namespace are first     * because the default namespace is not applied to     * unqualified attributes     */    if (attr1->ns == NULL)        return (-1);    if (attr2->ns == NULL)        return (1);    if (attr1->ns->prefix == NULL)        return (-1);    if (attr2->ns->prefix == NULL)        return (1);    ret = xmlStrcmp(attr1->ns->href, attr2->ns->href);    if (ret == 0) {        ret = xmlStrcmp(attr1->name, attr2->name);    }    return (ret);}/** * xmlC14NPrintAttrs: * @attr:		the pointer to attr * @ctx: 		the C14N context * * Prints out canonical attribute urrent node to the * buffer from C14N context as follows  * * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n) * * Returns 1 on success or 0 on fail. */static intxmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx){    xmlChar *value;    xmlChar *buffer;    if ((attr == NULL) || (ctx == NULL)) {        xmlC14NErrParam("writing attributes");        return (0);    }    xmlOutputBufferWriteString(ctx->buf, " ");    if (attr->ns != NULL && xmlStrlen(attr->ns->prefix) > 0) {        xmlOutputBufferWriteString(ctx->buf,                                   (const char *) attr->ns->prefix);        xmlOutputBufferWriteString(ctx->buf, ":");    }    xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);    xmlOutputBufferWriteString(ctx->buf, "=\"");    value = xmlNodeListGetString(attr->doc, attr->children, 1);    /* todo: should we log an error if value==NULL ? */    if (value != NULL) {        buffer = xmlC11NNormalizeAttr(value);        xmlFree(value);        if (buffer != NULL) {            xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);            xmlFree(buffer);        } else {            xmlC14NErrInternal("normalizing attributes axis");            return (0);        }    }    xmlOutputBufferWriteString(ctx->buf, "\"");    return (1);}/** * xmlC14NProcessAttrsAxis: * @ctx: 		the C14N context * @cur:		the current node * @parent_visible:	the visibility of parent node * * Prints out canonical attribute axis of the current node to the * buffer from C14N context as follows  * * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n) * * Attribute Axis  * In lexicographic order (ascending), process each node that  * is in the element's attribute axis and in the node-set. *  * The processing of an element node E MUST be modified slightly  * when an XPath node-set is given as input and the element's  * parent is omitted from the node-set. * * * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n) *

⌨️ 快捷键说明

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