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

📄 c14n.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 4 页
字号:
 * 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 intxmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible){    xmlAttrPtr attr;    xmlListPtr list;    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {        xmlC14NErrParam("processing attributes axis");        return (-1);    }    /*     * Create a sorted list to store element attributes     */    list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NAttrsCompare);    if (list == NULL) {        xmlC14NErrInternal("creating attributes list");        return (-1);    }    /*      * Add all visible attributes from current node.      */    attr = cur->properties;    while (attr != NULL) {        /* check that attribute is visible */        if (xmlC14NIsVisible(ctx, attr, cur)) {            xmlListInsert(list, attr);        }        attr = attr->next;    }    /*      * include attributes in "xml" namespace defined in ancestors     * (only for non-exclusive XML Canonicalization)     */    if (parent_visible && (!ctx->exclusive) && (cur->parent != NULL)        && (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) {        /*         * If XPath node-set is not specified then the parent is always          * visible!         */        cur = cur->parent;        while (cur != NULL) {            attr = cur->properties;            while (attr != NULL) {                if ((attr->ns != NULL)                    && (xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {                    if (xmlListSearch(list, attr) == NULL) {                        xmlListInsert(list, attr);                    }                }                attr = attr->next;            }            cur = cur->parent;        }    }    /*      * print out all elements from list      */    xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx);    /*      * Cleanup     */    xmlListDelete(list);    return (0);}/**  * xmlC14NCheckForRelativeNamespaces: * @ctx:		the C14N context * @cur:		the current element node * * Checks that current element node has no relative namespaces defined * * Returns 0 if the node has no relative namespaces or -1 otherwise. */static intxmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur){    xmlNsPtr ns;    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {        xmlC14NErrParam("checking for relative namespaces");        return (-1);    }    ns = cur->nsDef;    while (ns != NULL) {        if (xmlStrlen(ns->href) > 0) {            xmlURIPtr uri;            uri = xmlParseURI((const char *) ns->href);            if (uri == NULL) {                xmlC14NErrInternal("parsing namespace uri");                return (-1);            }            if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {                xmlC14NErrRelativeNamespace(uri->scheme);                xmlFreeURI(uri);                return (-1);            }            if ((xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "urn") != 0)                && (xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "dav") !=0)                && (xmlStrlen((const xmlChar *) uri->server) == 0)) {                xmlC14NErrRelativeNamespace(uri->scheme);                xmlFreeURI(uri);                return (-1);            }            xmlFreeURI(uri);        }        ns = ns->next;    }    return (0);}/** * xmlC14NProcessElementNode: * @ctx: 		the pointer to C14N context object * @cur:		the node to process *  		 * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n) * * Element Nodes * If the element is not in the node-set, then the result is obtained  * by processing the namespace axis, then the attribute axis, then  * processing the child nodes of the element that are in the node-set  * (in document order). If the element is in the node-set, then the result  * is an open angle bracket (<), the element QName, the result of  * processing the namespace axis, the result of processing the attribute  * axis, a close angle bracket (>), the result of processing the child  * nodes of the element that are in the node-set (in document order), an  * open angle bracket, a forward slash (/), the element QName, and a close  * angle bracket. * * Returns non-negative value on success or negative value on fail */static intxmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible){    int ret;    xmlC14NVisibleNsStack state;    int parent_is_doc = 0;    if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {        xmlC14NErrParam("processing element node");        return (-1);    }    /*      * Check relative relative namespaces:     * implementations of XML canonicalization MUST report an operation     * failure on documents containing relative namespace URIs.     */    if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {        xmlC14NErrInternal("checking for relative namespaces");        return (-1);    }    /*      * Save ns_rendered stack position     */    memset(&state, 0, sizeof(state));    xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);    if (visible) {	        if (ctx->parent_is_doc) {	    /* save this flag into the stack */	    parent_is_doc = ctx->parent_is_doc;	    ctx->parent_is_doc = 0;            ctx->pos = XMLC14N_INSIDE_DOCUMENT_ELEMENT;        }        xmlOutputBufferWriteString(ctx->buf, "<");        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {            xmlOutputBufferWriteString(ctx->buf,                                       (const char *) cur->ns->prefix);            xmlOutputBufferWriteString(ctx->buf, ":");        }        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);    }    if (!ctx->exclusive) {        ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);    } else {        ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);    }    if (ret < 0) {        xmlC14NErrInternal("processing namespaces axis");        return (-1);    }    /* todo: shouldn't this go to "visible only"? */    if(visible) {	xmlC14NVisibleNsStackShift(ctx->ns_rendered);    }        ret = xmlC14NProcessAttrsAxis(ctx, cur, visible);    if (ret < 0) {	xmlC14NErrInternal("processing attributes axis");    	return (-1);    }    if (visible) {         xmlOutputBufferWriteString(ctx->buf, ">");    }    if (cur->children != NULL) {        ret = xmlC14NProcessNodeList(ctx, cur->children);        if (ret < 0) {            xmlC14NErrInternal("processing childrens list");            return (-1);        }    }    if (visible) {        xmlOutputBufferWriteString(ctx->buf, "</");        if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {            xmlOutputBufferWriteString(ctx->buf,                                       (const char *) cur->ns->prefix);            xmlOutputBufferWriteString(ctx->buf, ":");        }        xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);        xmlOutputBufferWriteString(ctx->buf, ">");        if (parent_is_doc) {	    /* restore this flag from the stack for next node */            ctx->parent_is_doc = parent_is_doc;	    ctx->pos = XMLC14N_AFTER_DOCUMENT_ELEMENT;        }    }    /*      * Restore ns_rendered stack position     */    xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);    return (0);}/** * xmlC14NProcessNode: * @ctx: 		the pointer to C14N context object * @cur:		the node to process *  		 * Processes the given node * * Returns non-negative value on success or negative value on fail */static intxmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur){    int ret = 0;    int visible;    if ((ctx == NULL) || (cur == NULL)) {        xmlC14NErrParam("processing node");        return (-1);    }    visible = xmlC14NIsVisible(ctx, cur, cur->parent);    switch (cur->type) {        case XML_ELEMENT_NODE:            ret = xmlC14NProcessElementNode(ctx, cur, visible);            break;        case XML_CDATA_SECTION_NODE:        case XML_TEXT_NODE:            /*             * Text Nodes             * the string value, except all ampersands are replaced              * by &amp;, all open angle brackets (<) are replaced by &lt;, all closing              * angle brackets (>) are replaced by &gt;, and all #xD characters are              * replaced by &#xD;.             */            /* cdata sections are processed as text nodes */            /* todo: verify that cdata sections are included in XPath nodes set */            if ((visible) && (cur->content != NULL)) {                xmlChar *buffer;                buffer = xmlC11NNormalizeText(cur->content);                if (buffer != NULL) {                    xmlOutputBufferWriteString(ctx->buf,                                               (const char *) buffer);                    xmlFree(buffer);                } else {                    xmlC14NErrInternal("normalizing text node");                    return (-1);                }            }            break;        case XML_PI_NODE:            /*              * Processing Instruction (PI) Nodes-              * The opening PI symbol (<?), the PI target name of the node,              * a leading space and the string value if it is not empty, and              * the closing PI symbol (?>). If the string value is empty,              * then the leading space is not added. Also, a trailing #xA is              * rendered after the closing PI symbol for PI children of the              * root node with a lesser document order than the document              * element, and a leading #xA is rendered before the opening PI              * symbol of PI children of the root node with a greater document              * order than the document element.             */            if (visible) {                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {                    xmlOutputBufferWriteString(ctx->buf, "\x0A<?");                } else {                    xmlOutputBufferWriteString(ctx->buf, "<?");                }                xmlOutputBufferWriteString(ctx->buf,                                           (const char *) cur->name);                if ((cur->content != NULL) && (*(cur->content) != '\0')) {                    xmlChar *buffer;                    xmlOutputBufferWriteString(ctx->buf, " ");                    /* todo: do we need to normalize pi? */                    buffer = xmlC11NNormalizePI(cur->content);                    if (buffer != NULL) {                        xmlOutputBufferWriteString(ctx->buf,                                                   (const char *) buffer);                        xmlFree(buffer);                    } else {                        xmlC14NErrInternal("normalizing pi node");                        return (-1);                    }                }                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {                    xmlOutputBufferWriteString(ctx->buf, "?>\x0A");                } else {                    xmlOutputBufferWriteString(ctx->buf, "?>");                }            }            break;        case XML_COMMENT_NODE:            /*             * Comment Nodes             * Nothing if generating canonical XML without  comments. For              * canonical XML with comments, generate the opening comment              * symbol (<!--), the string value of the node, and the              * closing comment symbol (-->). Also, a trailing #xA is rendered              * after the closing comment symbol for comment children of the              * root node with a lesser document order than the document              * element, and a leading #xA is rendered before the opening              * comment symbol of comment children of the root node with a              * greater document order than the document element. (Comment              * children of the root node represent comments outside of the              * top-level document element and outside of the document type              * declaration).             */            if (visible && ctx->with_comments) {                if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {                    xmlOutputBufferWriteString(ctx->buf, "\x0A<!--");                } else {                    xmlOutputBufferWriteString(ctx->buf, "<!--");                }                if (cur->content != NULL) {                    xmlChar *buffer;                    /* todo: do we need to normalize comment? */                    buffer = xmlC11NNormalizeComment(cur->content);                    if (buffer != NULL) {                        xmlOutputBufferWriteString(ctx->buf,                                                   (const char *) buffer);                        xmlFree(buffer);                    } else {                        xmlC14NErrInternal("normalizing comment node");                        return (-1);                    }                }                if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {                    xmlOutputBufferWriteString(ctx->buf, "-->\x0A");                } else {                    xmlOutputBufferWriteString(ctx->buf, "-->");                }            }            break;        case XML_DOCUMENT_NODE:        case XML_DOCUMENT_FRAG_NODE:   /* should be processed as document? */#ifdef LIBXML_DOCB_ENABLED        case XML_DOCB_DOCUMENT_NODE:   /* should be processed as document? */#endif#ifdef LIBXML_HTML_ENABLED        case XML_HTML_DOCUMENT_NODE:   /* should be processed as document? */#endif            if (cur->children != NULL) {                ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;                ctx->parent_is_doc = 1;                ret = xmlC14NProcessNodeList(ctx, cur->children);            }            break;        case XML_ATTRIBUTE_NODE:            xmlC14NErrInvalidNode("XML_ATTRIBUTE_NODE", "processing node");            return (-1);        case XML_NAMESPACE_DECL:            xmlC14NErrInvalidNode("XML_NAMESPACE_DECL", "processing node");            return (-1);        case XML_ENTITY_REF_NODE:            xmlC14NErrInvalidNode("XML_ENTITY_REF_NODE", "processing node");            return (-1);        case XML_ENTITY_NODE:            xmlC14NErrInvalidNode("XML_ENTITY_NODE", "processing node");            return (-1);        case XML_DOCUMENT_TYPE_NODE:        case XML_NOTATION_NODE:        case XML_DTD_NODE:        case XML_ELEMENT_DECL:        case XML_ATTRIBUTE_DECL:        case XML_ENTITY_DECL:#ifdef LIBXML_XINCLUDE_ENABLED        case XML_XINCLUDE_START:        case XML_XINCLUDE_END:#endif            /*              * should be ignored according to "W3C Canonical XML"              */            break;        default:            xmlC14NErrUnknownNode(cur->type, "processing node");            return (-1);    }    return (ret);}/** * xmlC14NProcessNodeList: * @ctx: 		the pointer to C14N context object * @cur:		the node to start from *  		 * Processes all nodes in the row starting from cur. * * Returns non-negative value on success or negative value on fail */static intxmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur){    int ret;    if (ctx == NULL) {        xmlC14NErrParam("processing node list");        return (-1);    }    for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {        ret = xmlC14NProcessNode(ctx, cur);    }    return (ret);}/** * xmlC14NFreeCtx: * @ctx: the pointer to C14N context object * 		 * Cleanups the C14N context object. */static voidxmlC14NFreeCtx(xmlC14NCtxPtr ctx){    if (ctx == NULL) {        xmlC14NErrParam("freeing context");        return;    }    if (ctx->ns_rendered != NULL) {        xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);    }

⌨️ 快捷键说明

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