📄 c14n.c.svn-base
字号:
*/ prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix; href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href; has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL)); if (cur->nsTab != NULL) { int start = 0; for (i = cur->nsCurEnd - 1; i >= start; --i) { xmlNsPtr ns1 = cur->nsTab[i]; if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) { if(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL)) { return(xmlC14NIsVisible(ctx, ns1, cur->nodeTab[i])); } else { return(0); } } } } return(has_empty_ns);}/** * xmlC14NIsXmlNs: * @ns: the namespace to check * * Checks whether the given namespace is a default "xml:" namespace * 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)) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlC14NPrintNamespace: namespace or context pointer is null\n");#endif 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)) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlC14NProcessNamespacesAxis: Null context or node pointer or type != XML_ELEMENT_NODE.\n");#endif return (-1); } /* * Create a sorted list to store element namespaces */ list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare); if (list == NULL) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlC14NProcessNamespacesAxis: list creation failed\n");#endif 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)) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlExcC14NProcessNamespacesAxis: Null context or node pointer or type != XML_ELEMENT_NODE.\n");#endif return (-1); } if(!ctx->exclusive) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlExcC14NProcessNamespacesAxis: called for non-exclusive canonization or rendered stack is NULL.\n");#endif return (-1); } /* * Create a sorted list to store element namespaces */ list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare); if (list == NULL) {#ifdef DEBUG_C14N xmlGenericError(xmlGenericErrorContext, "xmlExcC14NProcessNamespacesAxis: list creation failed\n");#endif 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) && xmlC14NIsVisible(ctx, attr, cur)) { already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx); xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, (xmlNodePtr)attr); if(!already_rendered && visible) { xmlListInsert(list, attr->ns); } if(xmlStrlen(attr->ns->prefix) == 0) { has_empty_ns = 1; } } else if(attr->ns == NULL) { 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); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -