ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

namespaces.c
Go to the documentation of this file.
00001 /*
00002  * namespaces.c: Implementation of the XSLT namespaces handling
00003  *
00004  * Reference:
00005  *   http://www.w3.org/TR/1999/REC-xslt-19991116
00006  *
00007  * See Copyright for the status of this software.
00008  *
00009  * daniel@veillard.com
00010  */
00011 
00012 #define IN_LIBXSLT
00013 #include "libxslt.h"
00014 
00015 #include <string.h>
00016 
00017 #ifdef HAVE_SYS_TYPES_H
00018 #include <sys/types.h>
00019 #endif
00020 #ifdef HAVE_MATH_H
00021 #include <math.h>
00022 #endif
00023 #ifdef HAVE_FLOAT_H
00024 #include <float.h>
00025 #endif
00026 #ifdef HAVE_IEEEFP_H
00027 #include <ieeefp.h>
00028 #endif
00029 #ifdef HAVE_NAN_H
00030 #include <nan.h>
00031 #endif
00032 #ifdef HAVE_CTYPE_H
00033 #include <ctype.h>
00034 #endif
00035 #ifndef XSLT_NEED_TRIO
00036 #include <stdio.h>
00037 #else
00038 #include <trio.h>
00039 #endif
00040 
00041 #include <libxml/xmlmemory.h>
00042 #include <libxml/tree.h>
00043 #include <libxml/hash.h>
00044 #include <libxml/xmlerror.h>
00045 #include <libxml/uri.h>
00046 #include "xslt.h"
00047 #include "xsltInternals.h"
00048 #include "xsltutils.h"
00049 #include "namespaces.h"
00050 #include "imports.h"
00051 
00052 /************************************************************************
00053  *                                  *
00054  *          Module interfaces               *
00055  *                                  *
00056  ************************************************************************/
00057 
00058 #ifdef XSLT_REFACTORED  
00059 static xsltNsAliasPtr
00060 xsltNewNsAlias(xsltCompilerCtxtPtr cctxt)
00061 {
00062     xsltNsAliasPtr ret;
00063 
00064     if (cctxt == NULL)
00065     return(NULL);
00066 
00067     ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias));
00068     if (ret == NULL) {
00069     xsltTransformError(NULL, cctxt->style, NULL,
00070         "Internal error in xsltNewNsAlias(): Memory allocation failed.\n");
00071     cctxt->style->errors++;
00072     return(NULL);
00073     }
00074     memset(ret, 0, sizeof(xsltNsAlias));    
00075     /*
00076     * TODO: Store the item at current stylesheet-level.
00077     */
00078     ret->next = cctxt->nsAliases;
00079     cctxt->nsAliases = ret;       
00080 
00081     return(ret);
00082 }
00083 #endif /* XSLT_REFACTORED */
00084 
00092 void
00093 xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node)
00094 {
00095     xmlChar *resultPrefix = NULL;
00096     xmlChar *stylePrefix = NULL;
00097     xmlNsPtr literalNs = NULL;
00098     xmlNsPtr targetNs = NULL;
00099  
00100 #ifdef XSLT_REFACTORED 
00101     xsltNsAliasPtr alias;
00102 
00103     if ((style == NULL) || (node == NULL))
00104     return;
00105 
00106     /*
00107     * SPEC XSLT 1.0:
00108     *  "If a namespace URI is declared to be an alias for multiple
00109     *  different namespace URIs, then the declaration with the highest
00110     *  import precedence is used. It is an error if there is more than
00111     *  one such declaration. An XSLT processor may signal the error;
00112     *  if it does not signal the error, it must recover by choosing,
00113     *  from amongst the declarations with the highest import precedence,
00114     *  the one that occurs last in the stylesheet."
00115     *
00116     * SPEC TODO: Check for the errors mentioned above.
00117     */
00118     /*
00119     * NOTE that the XSLT 2.0 also *does* use the NULL namespace if
00120     *  "#default" is used and there's no default namespace is scope.
00121     *  I.e., this is *not* an error. 
00122     *  Most XSLT 1.0 implementations work this way.
00123     *  The XSLT 1.0 spec has nothing to say on the subject. 
00124     */
00125     /*
00126     * Attribute "stylesheet-prefix".
00127     */
00128     stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
00129     if (stylePrefix == NULL) {
00130     xsltTransformError(NULL, style, node,
00131         "The attribute 'stylesheet-prefix' is missing.\n");
00132     return;
00133     }
00134     if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default"))
00135     literalNs = xmlSearchNs(node->doc, node, NULL); 
00136     else {
00137     literalNs = xmlSearchNs(node->doc, node, stylePrefix);
00138     if (literalNs == NULL) {
00139         xsltTransformError(NULL, style, node,
00140             "Attribute 'stylesheet-prefix': There's no namespace "
00141         "declaration in scope for the prefix '%s'.\n",
00142             stylePrefix);
00143         goto error;
00144     }
00145     }
00146     /*
00147     * Attribute "result-prefix".
00148     */
00149     resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
00150     if (resultPrefix == NULL) {
00151     xsltTransformError(NULL, style, node,
00152         "The attribute 'result-prefix' is missing.\n");
00153     goto error;
00154     }        
00155     if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default"))
00156     targetNs = xmlSearchNs(node->doc, node, NULL);
00157     else {
00158     targetNs = xmlSearchNs(node->doc, node, resultPrefix);
00159 
00160         if (targetNs == NULL) {
00161        xsltTransformError(NULL, style, node,
00162             "Attribute 'result-prefix': There's no namespace "
00163         "declaration in scope for the prefix '%s'.\n",
00164             stylePrefix);
00165         goto error;
00166     }
00167     }
00168     /*
00169      *
00170      * Same alias for multiple different target namespace URIs:
00171      *  TODO: The one with the highest import precedence is used.
00172      *  Example:
00173      *  <xsl:namespace-alias stylesheet-prefix="foo"
00174      *                       result-prefix="bar"/>
00175      *
00176      *  <xsl:namespace-alias stylesheet-prefix="foo"
00177      *                       result-prefix="zar"/>
00178      *
00179      * Same target namespace URI for multiple different aliases:
00180      *  All alias-definitions will be used.
00181      *  Example:
00182      *  <xsl:namespace-alias stylesheet-prefix="bar"
00183      *                       result-prefix="foo"/>
00184      *
00185      *  <xsl:namespace-alias stylesheet-prefix="zar"
00186      *                       result-prefix="foo"/>
00187      * Cases using #default:
00188      *  <xsl:namespace-alias stylesheet-prefix="#default"
00189      *                       result-prefix="#default"/>
00190      *  TODO: Has this an effect at all?
00191      *
00192      *  <xsl:namespace-alias stylesheet-prefix="foo"
00193      *                       result-prefix="#default"/>
00194      *  From namespace to no namespace.
00195      *
00196      *  <xsl:namespace-alias stylesheet-prefix="#default"
00197      *                       result-prefix="foo"/>
00198      *  From no namespace to namespace.
00199      */
00200     
00201     
00202      /*
00203      * Store the ns-node in the alias-object.
00204     */
00205     alias = xsltNewNsAlias(XSLT_CCTXT(style));
00206     if (alias == NULL)
00207     return;
00208     alias->literalNs = literalNs;
00209     alias->targetNs = targetNs;
00210     XSLT_CCTXT(style)->hasNsAliases = 1;
00211 
00212 
00213 #else /* XSLT_REFACTORED */
00214     const xmlChar *literalNsName;
00215     const xmlChar *targetNsName;
00216     
00217 
00218     if ((style == NULL) || (node == NULL))
00219     return;
00220 
00221     stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
00222     if (stylePrefix == NULL) {
00223     xsltTransformError(NULL, style, node,
00224         "namespace-alias: stylesheet-prefix attribute missing\n");
00225     return;
00226     }
00227     resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
00228     if (resultPrefix == NULL) {
00229     xsltTransformError(NULL, style, node,
00230         "namespace-alias: result-prefix attribute missing\n");
00231     goto error;
00232     }
00233     
00234     if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) {
00235     literalNs = xmlSearchNs(node->doc, node, NULL);
00236     if (literalNs == NULL) {
00237         literalNsName = NULL;
00238     } else
00239         literalNsName = literalNs->href; /* Yes - set for nsAlias table */
00240     } else {
00241     literalNs = xmlSearchNs(node->doc, node, stylePrefix);
00242  
00243     if ((literalNs == NULL) || (literalNs->href == NULL)) {
00244         xsltTransformError(NULL, style, node,
00245             "namespace-alias: prefix %s not bound to any namespace\n",
00246                     stylePrefix);
00247         goto error;
00248     } else
00249         literalNsName = literalNs->href;
00250     }
00251 
00252     /*
00253      * When "#default" is used for result, if a default namespace has not
00254      * been explicitly declared the special value UNDEFINED_DEFAULT_NS is
00255      * put into the nsAliases table
00256      */
00257     if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) {
00258     targetNs = xmlSearchNs(node->doc, node, NULL);
00259     if (targetNs == NULL) {
00260         targetNsName = UNDEFINED_DEFAULT_NS;
00261     } else
00262         targetNsName = targetNs->href;
00263     } else {
00264     targetNs = xmlSearchNs(node->doc, node, resultPrefix);
00265 
00266         if ((targetNs == NULL) || (targetNs->href == NULL)) {
00267         xsltTransformError(NULL, style, node,
00268             "namespace-alias: prefix %s not bound to any namespace\n",
00269                     resultPrefix);
00270         goto error;
00271     } else
00272         targetNsName = targetNs->href;
00273     }
00274     /*
00275      * Special case: if #default is used for
00276      *  the stylesheet-prefix (literal namespace) and there's no default
00277      *  namespace in scope, we'll use style->defaultAlias for this.
00278      */   
00279     if (literalNsName == NULL) {
00280         if (targetNs != NULL) {
00281         /*
00282         * BUG TODO: Is it not sufficient to have only 1 field for
00283         *  this, since subsequently alias declarations will
00284         *  overwrite this.      
00285         *  Example:
00286         *   <xsl:namespace-alias result-prefix="foo"
00287         *                        stylesheet-prefix="#default"/>
00288         *   <xsl:namespace-alias result-prefix="bar"
00289         *                        stylesheet-prefix="#default"/>
00290         *  The mapping for "foo" won't be visible anymore.
00291         */
00292             style->defaultAlias = targetNs->href;
00293     }
00294     } else {
00295         if (style->nsAliases == NULL)
00296         style->nsAliases = xmlHashCreate(10);
00297         if (style->nsAliases == NULL) {
00298         xsltTransformError(NULL, style, node,
00299             "namespace-alias: cannot create hash table\n");
00300         goto error;
00301         }
00302     xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
00303         literalNsName, (void *) targetNsName);
00304     }
00305 #endif /* else of XSLT_REFACTORED */
00306 
00307 error:
00308     if (stylePrefix != NULL)
00309     xmlFree(stylePrefix);
00310     if (resultPrefix != NULL)
00311     xmlFree(resultPrefix);
00312 }
00313 
00336 xmlNsPtr
00337 xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode,
00338         const xmlChar *nsName, const xmlChar *nsPrefix,
00339         xmlNodePtr target)
00340 {
00341     xmlNsPtr ns;
00342     int prefixOccupied = 0;
00343 
00344     if ((ctxt == NULL) || (target == NULL) ||
00345     (target->type != XML_ELEMENT_NODE))
00346     return(NULL);
00347 
00348     /*
00349     * NOTE: Namespace exclusion and ns-aliasing is performed at
00350     *  compilation-time in the refactored code; so this need not be done
00351     *  here (it was in the old code).
00352     * NOTE: @invocNode was named @cur in the old code and was documented to
00353     *  be an input node; since it was only used to anchor an error report
00354     *  somewhere, we can safely change this to @invocNode, which now
00355     *  will be the XSLT instruction (also a literal result element/attribute),
00356     *  which was responsible for this call.
00357     */
00358     /*
00359     * OPTIMIZE TODO: This all could be optimized by keeping track of
00360     *  the ns-decls currently in-scope via a specialized context.
00361     */    
00362     if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) {
00363     /*
00364     * NOTE: the "undeclaration" of the default namespace was
00365     * part of the logic of the old xsltGetSpecialNamespace() code,
00366     * so we'll keep that mechanism.
00367     * Related to the old code: bug #302020:
00368     */
00369     /*
00370     * OPTIMIZE TODO: This all could be optimized by keeping track of
00371     *  the ns-decls currently in-scope via a specialized context.
00372     */
00373     /*
00374     * Search on the result element itself.
00375     */
00376     if (target->nsDef != NULL) {
00377         ns = target->nsDef;
00378         do {
00379         if (ns->prefix == NULL) {
00380             if ((ns->href != NULL) && (ns->href[0] != 0)) {
00381             /*
00382             * Raise a namespace normalization error.
00383             */
00384             xsltTransformError(ctxt, NULL, invocNode,
00385                 "Namespace normalization error: Cannot undeclare "
00386                 "the default namespace, since the default namespace "
00387                 "'%s' is already declared on the result element "
00388                 "'%s'.\n", ns->href, target->name);
00389             return(NULL);
00390             } else {
00391             /*
00392             * The default namespace was undeclared on the
00393             * result element.
00394             */
00395             return(NULL);
00396             }
00397             break;
00398         }
00399         ns = ns->next;
00400         } while (ns != NULL);
00401     }   
00402     if ((target->parent != NULL) &&
00403         (target->parent->type == XML_ELEMENT_NODE))
00404     {
00405         /*
00406         * The parent element is in no namespace, so assume
00407         * that there is no default namespace in scope.
00408         */
00409         if (target->parent->ns == NULL)
00410         return(NULL);
00411         
00412         ns = xmlSearchNs(target->doc, target->parent,
00413         NULL);
00414         /*
00415         * Fine if there's no default ns is scope, or if the
00416         * default ns was undeclared.
00417         */
00418         if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0))
00419         return(NULL);
00420         
00421         /*
00422         * Undeclare the default namespace.
00423         */
00424         xmlNewNs(target, BAD_CAST "", NULL);
00425         /* TODO: Check result */    
00426         return(NULL);
00427     }
00428     return(NULL);
00429     }
00430     /*
00431     * Handle the XML namespace.
00432     * QUESTION: Is this faster than using xmlStrEqual() anyway?
00433     */
00434     if ((nsPrefix != NULL) &&
00435     (nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') &&
00436     (nsPrefix[2] == 'l') && (nsPrefix[3] == 0))
00437     {
00438     return(xmlSearchNs(target->doc, target, nsPrefix));
00439     }
00440     /*
00441     * First: search on the result element itself.
00442     */
00443     if (target->nsDef != NULL) {
00444     ns = target->nsDef;
00445     do {
00446         if ((ns->prefix == NULL) == (nsPrefix == NULL)) {
00447         if (ns->prefix == nsPrefix) {
00448             if (xmlStrEqual(ns->href, nsName))
00449             return(ns);
00450             prefixOccupied = 1;
00451             break;
00452         } else if (xmlStrEqual(ns->prefix, nsPrefix)) {
00453             if (xmlStrEqual(ns->href, nsName))
00454             return(ns);
00455             prefixOccupied = 1;
00456             break;
00457         }
00458         }
00459         ns = ns->next;
00460     } while (ns != NULL);
00461     }
00462     if (prefixOccupied) {
00463     /*
00464     * If the ns-prefix is occupied by an other ns-decl on the
00465     * result element, then this means:
00466     * 1) The desired prefix is shadowed
00467     * 2) There's no way around changing the prefix  
00468     *
00469     * Try a desperate search for an in-scope ns-decl
00470     * with a matching ns-name before we use the last option,
00471     * which is to recreate the ns-decl with a modified prefix.
00472     */
00473     ns = xmlSearchNsByHref(target->doc, target, nsName);
00474     if (ns != NULL)
00475         return(ns);
00476 
00477     /*
00478     * Fallback to changing the prefix.
00479     */    
00480     } else if ((target->parent != NULL) &&
00481     (target->parent->type == XML_ELEMENT_NODE))
00482     {
00483     /*
00484     * Try to find a matching ns-decl in the ancestor-axis.
00485     *
00486     * Check the common case: The parent element of the current
00487     * result element is in the same namespace (with an equal ns-prefix).
00488     */     
00489     if ((target->parent->ns != NULL) &&
00490         ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL)))
00491     {
00492         ns = target->parent->ns;
00493         
00494         if (nsPrefix == NULL) {
00495         if (xmlStrEqual(ns->href, nsName))
00496             return(ns);
00497         } else if (xmlStrEqual(ns->prefix, nsPrefix) &&
00498         xmlStrEqual(ns->href, nsName))
00499         {
00500         return(ns);
00501         }
00502     }
00503     /*
00504     * Lookup the remaining in-scope namespaces.
00505     */    
00506     ns = xmlSearchNs(target->doc, target->parent, nsPrefix);
00507     if (ns != NULL) {
00508         if (xmlStrEqual(ns->href, nsName))
00509         return(ns);     
00510         /*
00511         * Now check for a nasty case: We need to ensure that the new
00512         * ns-decl won't shadow a prefix in-use by an existing attribute.
00513         * <foo xmlns:a="urn:test:a">
00514         *   <bar a:a="val-a">
00515         *     <xsl:attribute xmlns:a="urn:test:b" name="a:b">
00516         *        val-b</xsl:attribute>
00517         *   </bar>
00518         * </foo>
00519         */
00520         if (target->properties) {
00521         xmlAttrPtr attr = target->properties;
00522         do {
00523             if ((attr->ns) &&
00524             xmlStrEqual(attr->ns->prefix, nsPrefix))
00525             {
00526             /*
00527             * Bad, this prefix is already in use.
00528             * Since we'll change the prefix anyway, try
00529             * a search for a matching ns-decl based on the
00530             * namespace name.
00531             */
00532             ns = xmlSearchNsByHref(target->doc, target, nsName);
00533             if (ns != NULL)
00534                 return(ns);
00535             goto declare_new_prefix;
00536             }
00537             attr = attr->next;
00538         } while (attr != NULL);
00539         }
00540     } else {
00541         /*
00542         * Either no matching ns-prefix was found or the namespace is
00543         * shadowed.
00544         * Create a new ns-decl on the current result element.
00545         *
00546         * Hmm, we could also try to reuse an in-scope
00547         * namespace with a matching ns-name but a different
00548         * ns-prefix.
00549         * What has higher priority?
00550         *  1) If keeping the prefix: create a new ns-decl.
00551         *  2) If reusal: first lookup ns-names; then fallback
00552         *     to creation of a new ns-decl.
00553         * REVISIT: this currently uses case 1) although
00554         *  the old way was use xmlSearchNsByHref() and to let change
00555         *  the prefix.
00556         */
00557 #if 0
00558         ns = xmlSearchNsByHref(target->doc, target, nsName);
00559         if (ns != NULL)
00560         return(ns);
00561 #endif
00562     }
00563     /*
00564     * Create the ns-decl on the current result element.
00565     */
00566     ns = xmlNewNs(target, nsName, nsPrefix);
00567     /* TODO: check errors */
00568     return(ns);
00569     } else {
00570     /*
00571     * This is either the root of the tree or something weird is going on.
00572     */
00573     ns = xmlNewNs(target, nsName, nsPrefix);
00574     /* TODO: Check result */
00575     return(ns);
00576     }
00577 
00578 declare_new_prefix:
00579     /*
00580     * Fallback: we need to generate a new prefix and declare the namespace
00581     * on the result element.
00582     */
00583     {
00584     xmlChar pref[30];
00585     int counter = 1;
00586 
00587     if (nsPrefix == NULL) {
00588         nsPrefix = "ns";
00589     }
00590 
00591     do {
00592         snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++);
00593         ns = xmlSearchNs(target->doc, target, BAD_CAST pref);
00594         if (counter > 1000) {
00595         xsltTransformError(ctxt, NULL, invocNode,
00596             "Internal error in xsltAcquireResultInScopeNs(): "
00597             "Failed to compute a unique ns-prefix for the "
00598             "generated element");
00599         return(NULL);
00600         }
00601     } while (ns != NULL);
00602     ns = xmlNewNs(target, nsName, BAD_CAST pref);
00603     /* TODO: Check result */
00604     return(ns);
00605     }
00606     return(NULL);
00607 }
00608 
00633 xmlNsPtr
00634 xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns,
00635              xmlNodePtr out)
00636 {    
00637     
00638     if (ns == NULL)
00639     return(NULL);
00640 
00641 #ifdef XSLT_REFACTORED
00642     /*
00643     * Namespace exclusion and ns-aliasing is performed at
00644     * compilation-time in the refactored code.
00645     * Additionally, aliasing is not intended for non Literal
00646     * Result Elements.
00647     */
00648     return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out));
00649 #else
00650     {
00651     xsltStylesheetPtr style;
00652     const xmlChar *URI = NULL; /* the replacement URI */
00653 
00654     if ((ctxt == NULL) || (cur == NULL) || (out == NULL))
00655         return(NULL);
00656 
00657     style = ctxt->style;
00658     while (style != NULL) {
00659         if (style->nsAliases != NULL)
00660         URI = (const xmlChar *) 
00661         xmlHashLookup(style->nsAliases, ns->href);
00662         if (URI != NULL)
00663         break;
00664         
00665         style = xsltNextImport(style);
00666     }
00667     
00668     
00669     if (URI == UNDEFINED_DEFAULT_NS) {
00670         return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out));
00671 #if 0
00672         /*
00673         * TODO: Removed, since wrong. If there was no default
00674         * namespace in the stylesheet then this must resolve to
00675         * the NULL namespace.
00676         */
00677         xmlNsPtr dflt;      
00678         dflt = xmlSearchNs(cur->doc, cur, NULL);
00679         if (dflt != NULL)
00680         URI = dflt->href;
00681         else
00682         return NULL;
00683 #endif
00684     } else if (URI == NULL)
00685         URI = ns->href;
00686 
00687     return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out));
00688     }
00689 #endif
00690 }
00691 
00706 xmlNsPtr
00707 xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur,
00708                       xmlNsPtr ns, xmlNodePtr out)
00709 {    
00710     return(xsltGetNamespace(ctxt, cur, ns, out));
00711 }
00712 
00734 xmlNsPtr
00735 xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node,
00736                   xmlNsPtr cur) {
00737     xmlNsPtr ret = NULL, tmp;
00738     xmlNsPtr p = NULL,q;    
00739 
00740     if (cur == NULL)
00741     return(NULL);
00742     if (cur->type != XML_NAMESPACE_DECL)
00743     return(NULL);
00744 
00745     /*
00746      * One can add namespaces only on element nodes
00747      */
00748     if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
00749     node = NULL;
00750 
00751     while (cur != NULL) {
00752     if (cur->type != XML_NAMESPACE_DECL)
00753         break;
00754 
00755     /*
00756      * Avoid duplicating namespace declarations in the tree if
00757      * a matching declaration is in scope.
00758      */
00759     if (node != NULL) {
00760         if ((node->ns != NULL) &&
00761         (xmlStrEqual(node->ns->prefix, cur->prefix)) &&
00762             (xmlStrEqual(node->ns->href, cur->href))) {
00763         cur = cur->next;
00764         continue;
00765         }
00766         tmp = xmlSearchNs(node->doc, node, cur->prefix);
00767         if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) {
00768         cur = cur->next;
00769         continue;
00770         }
00771     }
00772 #ifdef XSLT_REFACTORED
00773     /*
00774     * Namespace exclusion and ns-aliasing is performed at
00775     * compilation-time in the refactored code.
00776     */
00777     q = xmlNewNs(node, cur->href, cur->prefix);
00778     if (p == NULL) {
00779         ret = p = q;
00780     } else {
00781         p->next = q;
00782         p = q;
00783     }
00784 #else
00785     /*
00786     * TODO: Remove this if the refactored code gets enabled.
00787     */
00788     if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
00789         const xmlChar *URI;
00790         /* TODO apply cascading */
00791         URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
00792                                           cur->href);
00793         if (URI == UNDEFINED_DEFAULT_NS)
00794             continue;
00795         if (URI != NULL) {
00796         q = xmlNewNs(node, URI, cur->prefix);
00797         } else {
00798         q = xmlNewNs(node, cur->href, cur->prefix);
00799         }
00800         if (p == NULL) {
00801         ret = p = q;
00802         } else {
00803         p->next = q;
00804         p = q;
00805         }
00806     }
00807 #endif
00808     cur = cur->next;
00809     }
00810     return(ret);
00811 }
00812 
00824 xmlNsPtr
00825 xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
00826           xmlNodePtr elem, xmlNsPtr ns)
00827 {    
00828     if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
00829     return(NULL);
00830     /*
00831      * One can add namespaces only on element nodes
00832      */
00833     if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
00834     return(xmlNewNs(NULL, ns->href, ns->prefix));
00835     else
00836     return(xmlNewNs(elem, ns->href, ns->prefix));
00837 }
00838 
00839 
00846 void
00847 xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) {
00848     if (style->nsAliases != NULL)
00849     xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL);
00850     style->nsAliases = NULL;
00851 }

Generated on Sat May 26 2012 04:18:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.