ReactOS  0.4.14-dev-77-gd9e7c48
namespaces.c File Reference
#include "precomp.h"
Include dependency graph for namespaces.c:

Go to the source code of this file.

Functions

void xsltNamespaceAlias (xsltStylesheetPtr style, xmlNodePtr node)
 
xmlNsPtr xsltGetSpecialNamespace (xsltTransformContextPtr ctxt, xmlNodePtr invocNode, const xmlChar *nsName, const xmlChar *nsPrefix, xmlNodePtr target)
 
xmlNsPtr xsltGetNamespace (xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, xmlNodePtr out)
 
xmlNsPtr xsltGetPlainNamespace (xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, xmlNodePtr out)
 
xmlNsPtr xsltCopyNamespaceList (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNsPtr cur)
 
xmlNsPtr xsltCopyNamespace (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, xmlNodePtr elem, xmlNsPtr ns)
 
void xsltFreeNamespaceAliasHashes (xsltStylesheetPtr style)
 

Function Documentation

◆ xsltCopyNamespace()

xmlNsPtr xsltCopyNamespace ( xsltTransformContextPtr ctxt  ATTRIBUTE_UNUSED,
xmlNodePtr  elem,
xmlNsPtr  ns 
)

xsltCopyNamespace: @ctxt: a transformation context @elem: the target element node @ns: the namespace node

Copies a namespace node (declaration). If @elem is not NULL, then the new namespace will be declared on @elem.

Returns: a new xmlNsPtr, or NULL in case of an error.

Definition at line 789 of file namespaces.c.

791 {
792  if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
793  return(NULL);
794  /*
795  * One can add namespaces only on element nodes
796  */
797  if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
798  return(xmlNewNs(NULL, ns->href, ns->prefix));
799  else
800  return(xmlNewNs(elem, ns->href, ns->prefix));
801 }
static size_t elem
Definition: string.c:68
smooth NULL
Definition: ftsmooth.c:416
Definition: mxnamespace.c:44
BSTR prefix
Definition: mxnamespace.c:46
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)

◆ xsltCopyNamespaceList()

xmlNsPtr xsltCopyNamespaceList ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xmlNsPtr  cur 
)

xsltCopyNamespaceList: @ctxt: a transformation context @node: the target node @cur: the first namespace

Do a copy of an namespace list. If @node is non-NULL the new namespaces are added automatically. This handles namespaces aliases. This function is intended only for internal use at transformation-time for copying ns-declarations of Literal Result Elements.

Called by: xsltCopyTreeInternal() (transform.c) xsltShallowCopyElem() (transform.c)

REVISIT: This function won't be used in the refactored code.

Returns: a new xmlNsPtr, or NULL in case of error.

Definition at line 697 of file namespaces.c.

698  {
699  xmlNsPtr ret = NULL, tmp;
700  xmlNsPtr p = NULL,q;
701 
702  if (cur == NULL)
703  return(NULL);
704  if (cur->type != XML_NAMESPACE_DECL)
705  return(NULL);
706 
707  /*
708  * One can add namespaces only on element nodes
709  */
710  if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
711  node = NULL;
712 
713  while (cur != NULL) {
714  if (cur->type != XML_NAMESPACE_DECL)
715  break;
716 
717  /*
718  * Avoid duplicating namespace declarations in the tree if
719  * a matching declaration is in scope.
720  */
721  if (node != NULL) {
722  if ((node->ns != NULL) &&
723  (xmlStrEqual(node->ns->prefix, cur->prefix)) &&
724  (xmlStrEqual(node->ns->href, cur->href))) {
725  cur = cur->next;
726  continue;
727  }
728  tmp = xmlSearchNs(node->doc, node, cur->prefix);
729  if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) {
730  cur = cur->next;
731  continue;
732  }
733  }
734 #ifdef XSLT_REFACTORED
735  /*
736  * Namespace exclusion and ns-aliasing is performed at
737  * compilation-time in the refactored code.
738  */
739  q = xmlNewNs(node, cur->href, cur->prefix);
740  if (p == NULL) {
741  ret = p = q;
742  } else {
743  p->next = q;
744  p = q;
745  }
746 #else
747  /*
748  * TODO: Remove this if the refactored code gets enabled.
749  */
750  if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
751  const xmlChar *URI;
752  /* TODO apply cascading */
753  URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
754  cur->href);
755  if (URI == UNDEFINED_DEFAULT_NS) {
756  cur = cur->next;
757  continue;
758  }
759  if (URI != NULL) {
760  q = xmlNewNs(node, URI, cur->prefix);
761  } else {
762  q = xmlNewNs(node, cur->href, cur->prefix);
763  }
764  if (p == NULL) {
765  ret = p = q;
766  } else {
767  p->next = q;
768  p = q;
769  }
770  }
771 #endif
772  cur = cur->next;
773  }
774  return(ret);
775 }
struct _xmlNs * next
Definition: tree.h:390
Definition: tree.h:389
xmlNsType type
Definition: tree.h:391
#define XSLT_NAMESPACE
Definition: xslt.h:46
#define UNDEFINED_DEFAULT_NS
Definition: namespaces.h:30
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
smooth NULL
Definition: ftsmooth.c:416
xmlHashTablePtr nsAliases
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
int ret
unsigned char xmlChar
Definition: xmlstring.h:28
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
xsltStylesheetPtr style
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:459
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
GLfloat GLfloat p
Definition: glext.h:8902
const xmlChar * prefix
Definition: tree.h:393
const xmlChar * href
Definition: tree.h:392
Definition: dlist.c:348

Referenced by xsltCopyTree(), and xsltShallowCopyElem().

◆ xsltFreeNamespaceAliasHashes()

void xsltFreeNamespaceAliasHashes ( xsltStylesheetPtr  style)

xsltFreeNamespaceAliasHashes: @style: an XSLT stylesheet

Free up the memory used by namespaces aliases

Definition at line 811 of file namespaces.c.

811  {
812  if (style->nsAliases != NULL)
813  xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL);
814  style->nsAliases = NULL;
815 }
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:320
smooth NULL
Definition: ftsmooth.c:416
Arabic default style
Definition: afstyles.h:93

Referenced by xsltFreeStylesheet().

◆ xsltGetNamespace()

xmlNsPtr xsltGetNamespace ( xsltTransformContextPtr  ctxt,
xmlNodePtr  cur,
xmlNsPtr  ns,
xmlNodePtr  out 
)

xsltGetNamespace: @ctxt: a transformation context @cur: the input node @ns: the namespace @out: the output node (or its parent)

Find a matching (prefix and ns-name) ns-declaration for the requested @ns->prefix and @ns->href in the result tree. If none is found then a new ns-declaration will be added to @resultElem. If, in this case, the given prefix is already in use, then a ns-declaration with a modified ns-prefix be we created.

Called by:

Returns a namespace declaration or NULL in case of namespace fixup failures or API or internal errors.

Definition at line 596 of file namespaces.c.

598 {
599 
600  if (ns == NULL)
601  return(NULL);
602 
603 #ifdef XSLT_REFACTORED
604  /*
605  * Namespace exclusion and ns-aliasing is performed at
606  * compilation-time in the refactored code.
607  * Additionally, aliasing is not intended for non Literal
608  * Result Elements.
609  */
610  return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out));
611 #else
612  {
614  const xmlChar *URI = NULL; /* the replacement URI */
615 
616  if ((ctxt == NULL) || (cur == NULL) || (out == NULL))
617  return(NULL);
618 
619  style = ctxt->style;
620  while (style != NULL) {
621  if (style->nsAliases != NULL)
622  URI = (const xmlChar *)
623  xmlHashLookup(style->nsAliases, ns->href);
624  if (URI != NULL)
625  break;
626 
628  }
629 
630 
631  if (URI == UNDEFINED_DEFAULT_NS) {
632  return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out));
633 #if 0
634  /*
635  * TODO: Removed, since wrong. If there was no default
636  * namespace in the stylesheet then this must resolve to
637  * the NULL namespace.
638  */
639  xmlNsPtr dflt;
640  dflt = xmlSearchNs(cur->doc, cur, NULL);
641  if (dflt != NULL)
642  URI = dflt->href;
643  else
644  return NULL;
645 #endif
646  } else if (URI == NULL)
647  URI = ns->href;
648 
649  return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out));
650  }
651 #endif
652 }
Definition: tree.h:389
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:250
xmlNsPtr xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, const xmlChar *nsName, const xmlChar *nsPrefix, xmlNodePtr target)
Definition: namespaces.c:299
struct _xmlDoc * doc
Definition: tree.h:498
#define UNDEFINED_DEFAULT_NS
Definition: namespaces.h:30
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
Definition: mxnamespace.c:44
unsigned char xmlChar
Definition: xmlstring.h:28
BSTR prefix
Definition: mxnamespace.c:46
xsltStylesheetPtr style
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:459
Arabic default style
Definition: afstyles.h:93
const xmlChar * href
Definition: tree.h:392

Referenced by xsltApplySequenceConstructor(), xsltAttrListTemplateProcess(), xsltAttrTemplateProcess(), xsltGetPlainNamespace(), and xsltShallowCopyElem().

◆ xsltGetPlainNamespace()

xmlNsPtr xsltGetPlainNamespace ( xsltTransformContextPtr  ctxt,
xmlNodePtr  cur,
xmlNsPtr  ns,
xmlNodePtr  out 
)

xsltGetPlainNamespace: @ctxt: a transformation context @cur: the input node @ns: the namespace @out: the result element

Obsolete. Not called by any Libxslt/Libexslt function. Exaclty the same as xsltGetNamespace().

Returns a namespace declaration or NULL in case of namespace fixup failures or API or internal errors.

Definition at line 669 of file namespaces.c.

671 {
672  return(xsltGetNamespace(ctxt, cur, ns, out));
673 }
xmlNsPtr xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, xmlNodePtr out)
Definition: namespaces.c:596
static FILE * out
Definition: regtests2xml.c:44
Definition: mxnamespace.c:44

◆ xsltGetSpecialNamespace()

xmlNsPtr xsltGetSpecialNamespace ( xsltTransformContextPtr  ctxt,
xmlNodePtr  invocNode,
const xmlChar nsName,
const xmlChar nsPrefix,
xmlNodePtr  target 
)

xsltGetSpecialNamespace: @ctxt: the transformation context @invocNode: the invoking node; e.g. a literal result element/attr; only used for error reports @nsName: the namespace name (or NULL) @nsPrefix: the suggested namespace prefix (or NULL) @target: the result element on which to anchor a namespace

Find a matching (prefix and ns-name) ns-declaration for the requested @nsName and @nsPrefix in the result tree. If none is found then a new ns-declaration will be added to @resultElem. If, in this case, the given prefix is already in use, then a ns-declaration with a modified ns-prefix be we created. Note that this function's priority is to preserve ns-prefixes; it will only change a prefix if there's a namespace clash. If both @nsName and @nsPrefix are NULL, then this will try to "undeclare" a default namespace by declaring an xmlns="".

Returns a namespace declaration or NULL.

Definition at line 299 of file namespaces.c.

302 {
303  xmlNsPtr ns;
304  int prefixOccupied = 0;
305 
306  if ((ctxt == NULL) || (target == NULL) ||
307  (target->type != XML_ELEMENT_NODE))
308  return(NULL);
309 
310  /*
311  * NOTE: Namespace exclusion and ns-aliasing is performed at
312  * compilation-time in the refactored code; so this need not be done
313  * here (it was in the old code).
314  * NOTE: @invocNode was named @cur in the old code and was documented to
315  * be an input node; since it was only used to anchor an error report
316  * somewhere, we can safely change this to @invocNode, which now
317  * will be the XSLT instruction (also a literal result element/attribute),
318  * which was responsible for this call.
319  */
320  /*
321  * OPTIMIZE TODO: This all could be optimized by keeping track of
322  * the ns-decls currently in-scope via a specialized context.
323  */
324  if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) {
325  /*
326  * NOTE: the "undeclaration" of the default namespace was
327  * part of the logic of the old xsltGetSpecialNamespace() code,
328  * so we'll keep that mechanism.
329  * Related to the old code: bug #302020:
330  */
331  /*
332  * OPTIMIZE TODO: This all could be optimized by keeping track of
333  * the ns-decls currently in-scope via a specialized context.
334  */
335  /*
336  * Search on the result element itself.
337  */
338  if (target->nsDef != NULL) {
339  ns = target->nsDef;
340  do {
341  if (ns->prefix == NULL) {
342  if ((ns->href != NULL) && (ns->href[0] != 0)) {
343  /*
344  * Raise a namespace normalization error.
345  */
346  xsltTransformError(ctxt, NULL, invocNode,
347  "Namespace normalization error: Cannot undeclare "
348  "the default namespace, since the default namespace "
349  "'%s' is already declared on the result element "
350  "'%s'.\n", ns->href, target->name);
351  return(NULL);
352  } else {
353  /*
354  * The default namespace was undeclared on the
355  * result element.
356  */
357  return(NULL);
358  }
359  break;
360  }
361  ns = ns->next;
362  } while (ns != NULL);
363  }
364  if ((target->parent != NULL) &&
365  (target->parent->type == XML_ELEMENT_NODE))
366  {
367  /*
368  * The parent element is in no namespace, so assume
369  * that there is no default namespace in scope.
370  */
371  if (target->parent->ns == NULL)
372  return(NULL);
373 
374  ns = xmlSearchNs(target->doc, target->parent,
375  NULL);
376  /*
377  * Fine if there's no default ns is scope, or if the
378  * default ns was undeclared.
379  */
380  if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0))
381  return(NULL);
382 
383  /*
384  * Undeclare the default namespace.
385  */
387  /* TODO: Check result */
388  return(NULL);
389  }
390  return(NULL);
391  }
392  /*
393  * Handle the XML namespace.
394  * QUESTION: Is this faster than using xmlStrEqual() anyway?
395  */
396  if ((nsPrefix != NULL) &&
397  (nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') &&
398  (nsPrefix[2] == 'l') && (nsPrefix[3] == 0))
399  {
400  return(xmlSearchNs(target->doc, target, nsPrefix));
401  }
402  /*
403  * First: search on the result element itself.
404  */
405  if (target->nsDef != NULL) {
406  ns = target->nsDef;
407  do {
408  if ((ns->prefix == NULL) == (nsPrefix == NULL)) {
409  if (ns->prefix == nsPrefix) {
410  if (xmlStrEqual(ns->href, nsName))
411  return(ns);
412  prefixOccupied = 1;
413  break;
414  } else if (xmlStrEqual(ns->prefix, nsPrefix)) {
415  if (xmlStrEqual(ns->href, nsName))
416  return(ns);
417  prefixOccupied = 1;
418  break;
419  }
420  }
421  ns = ns->next;
422  } while (ns != NULL);
423  }
424  if (prefixOccupied) {
425  /*
426  * If the ns-prefix is occupied by an other ns-decl on the
427  * result element, then this means:
428  * 1) The desired prefix is shadowed
429  * 2) There's no way around changing the prefix
430  *
431  * Try a desperate search for an in-scope ns-decl
432  * with a matching ns-name before we use the last option,
433  * which is to recreate the ns-decl with a modified prefix.
434  */
435  ns = xmlSearchNsByHref(target->doc, target, nsName);
436  if (ns != NULL)
437  return(ns);
438 
439  /*
440  * Fallback to changing the prefix.
441  */
442  } else if ((target->parent != NULL) &&
443  (target->parent->type == XML_ELEMENT_NODE))
444  {
445  /*
446  * Try to find a matching ns-decl in the ancestor-axis.
447  *
448  * Check the common case: The parent element of the current
449  * result element is in the same namespace (with an equal ns-prefix).
450  */
451  if ((target->parent->ns != NULL) &&
452  ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL)))
453  {
454  ns = target->parent->ns;
455 
456  if (nsPrefix == NULL) {
457  if (xmlStrEqual(ns->href, nsName))
458  return(ns);
459  } else if (xmlStrEqual(ns->prefix, nsPrefix) &&
460  xmlStrEqual(ns->href, nsName))
461  {
462  return(ns);
463  }
464  }
465  /*
466  * Lookup the remaining in-scope namespaces.
467  */
468  ns = xmlSearchNs(target->doc, target->parent, nsPrefix);
469  if (ns != NULL) {
470  if (xmlStrEqual(ns->href, nsName))
471  return(ns);
472  /*
473  * Now check for a nasty case: We need to ensure that the new
474  * ns-decl won't shadow a prefix in-use by an existing attribute.
475  * <foo xmlns:a="urn:test:a">
476  * <bar a:a="val-a">
477  * <xsl:attribute xmlns:a="urn:test:b" name="a:b">
478  * val-b</xsl:attribute>
479  * </bar>
480  * </foo>
481  */
482  if (target->properties) {
483  xmlAttrPtr attr = target->properties;
484  do {
485  if ((attr->ns) &&
486  xmlStrEqual(attr->ns->prefix, nsPrefix))
487  {
488  /*
489  * Bad, this prefix is already in use.
490  * Since we'll change the prefix anyway, try
491  * a search for a matching ns-decl based on the
492  * namespace name.
493  */
494  ns = xmlSearchNsByHref(target->doc, target, nsName);
495  if (ns != NULL)
496  return(ns);
497  goto declare_new_prefix;
498  }
499  attr = attr->next;
500  } while (attr != NULL);
501  }
502  } else {
503  /*
504  * Either no matching ns-prefix was found or the namespace is
505  * shadowed.
506  * Create a new ns-decl on the current result element.
507  *
508  * Hmm, we could also try to reuse an in-scope
509  * namespace with a matching ns-name but a different
510  * ns-prefix.
511  * What has higher priority?
512  * 1) If keeping the prefix: create a new ns-decl.
513  * 2) If reusal: first lookup ns-names; then fallback
514  * to creation of a new ns-decl.
515  * REVISIT: this currently uses case 1) although
516  * the old way was use xmlSearchNsByHref() and to let change
517  * the prefix.
518  */
519 #if 0
520  ns = xmlSearchNsByHref(target->doc, target, nsName);
521  if (ns != NULL)
522  return(ns);
523 #endif
524  }
525  /*
526  * Create the ns-decl on the current result element.
527  */
528  ns = xmlNewNs(target, nsName, nsPrefix);
529  /* TODO: check errors */
530  return(ns);
531  } else {
532  /*
533  * This is either the root of the tree or something weird is going on.
534  */
535  ns = xmlNewNs(target, nsName, nsPrefix);
536  /* TODO: Check result */
537  return(ns);
538  }
539 
540 declare_new_prefix:
541  /*
542  * Fallback: we need to generate a new prefix and declare the namespace
543  * on the result element.
544  */
545  {
546  xmlChar pref[30];
547  int counter = 1;
548 
549  if (nsPrefix == NULL) {
550  nsPrefix = BAD_CAST "ns";
551  }
552 
553  do {
554  snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++);
555  ns = xmlSearchNs(target->doc, target, BAD_CAST pref);
556  if (counter > 1000) {
557  xsltTransformError(ctxt, NULL, invocNode,
558  "Internal error in xsltAcquireResultInScopeNs(): "
559  "Failed to compute a unique ns-prefix for the "
560  "generated element");
561  return(NULL);
562  }
563  } while (ns != NULL);
564  ns = xmlNewNs(target, nsName, BAD_CAST pref);
565  /* TODO: Check result */
566  return(ns);
567  }
568  return(NULL);
569 }
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href)
Definition: tree.h:389
#define snprintf
Definition: wintirpc.h:48
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
smooth NULL
Definition: ftsmooth.c:416
#define BAD_CAST
Definition: xmlstring.h:35
Definition: cookie.c:170
Definition: mxnamespace.c:44
unsigned char xmlChar
Definition: xmlstring.h:28
BSTR prefix
Definition: mxnamespace.c:46
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
Definition: tree.h:434
GLenum target
Definition: glext.h:7315
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678

Referenced by xsltApplySequenceConstructor(), xsltAttribute(), xsltAttrListTemplateProcess(), xsltCopyAttrListNoOverwrite(), xsltCopyTree(), xsltElement(), xsltGetNamespace(), xsltShallowCopyAttr(), and xsltShallowCopyElem().

◆ xsltNamespaceAlias()

void xsltNamespaceAlias ( xsltStylesheetPtr  style,
xmlNodePtr  node 
)

xsltNamespaceAlias: @style: the XSLT stylesheet @node: the xsl:namespace-alias node

Read the stylesheet-prefix and result-prefix attributes, register them as well as the corresponding namespace.

Definition at line 55 of file namespaces.c.

56 {
57  xmlChar *resultPrefix = NULL;
58  xmlChar *stylePrefix = NULL;
59  xmlNsPtr literalNs = NULL;
60  xmlNsPtr targetNs = NULL;
61 
62 #ifdef XSLT_REFACTORED
63  xsltNsAliasPtr alias;
64 
65  if ((style == NULL) || (node == NULL))
66  return;
67 
68  /*
69  * SPEC XSLT 1.0:
70  * "If a namespace URI is declared to be an alias for multiple
71  * different namespace URIs, then the declaration with the highest
72  * import precedence is used. It is an error if there is more than
73  * one such declaration. An XSLT processor may signal the error;
74  * if it does not signal the error, it must recover by choosing,
75  * from amongst the declarations with the highest import precedence,
76  * the one that occurs last in the stylesheet."
77  *
78  * SPEC TODO: Check for the errors mentioned above.
79  */
80  /*
81  * NOTE that the XSLT 2.0 also *does* use the NULL namespace if
82  * "#default" is used and there's no default namespace is scope.
83  * I.e., this is *not* an error.
84  * Most XSLT 1.0 implementations work this way.
85  * The XSLT 1.0 spec has nothing to say on the subject.
86  */
87  /*
88  * Attribute "stylesheet-prefix".
89  */
90  stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
91  if (stylePrefix == NULL) {
93  "The attribute 'stylesheet-prefix' is missing.\n");
94  return;
95  }
96  if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default"))
97  literalNs = xmlSearchNs(node->doc, node, NULL);
98  else {
99  literalNs = xmlSearchNs(node->doc, node, stylePrefix);
100  if (literalNs == NULL) {
102  "Attribute 'stylesheet-prefix': There's no namespace "
103  "declaration in scope for the prefix '%s'.\n",
104  stylePrefix);
105  goto error;
106  }
107  }
108  /*
109  * Attribute "result-prefix".
110  */
111  resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
112  if (resultPrefix == NULL) {
114  "The attribute 'result-prefix' is missing.\n");
115  goto error;
116  }
117  if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default"))
118  targetNs = xmlSearchNs(node->doc, node, NULL);
119  else {
120  targetNs = xmlSearchNs(node->doc, node, resultPrefix);
121 
122  if (targetNs == NULL) {
124  "Attribute 'result-prefix': There's no namespace "
125  "declaration in scope for the prefix '%s'.\n",
126  stylePrefix);
127  goto error;
128  }
129  }
130  /*
131  *
132  * Same alias for multiple different target namespace URIs:
133  * TODO: The one with the highest import precedence is used.
134  * Example:
135  * <xsl:namespace-alias stylesheet-prefix="foo"
136  * result-prefix="bar"/>
137  *
138  * <xsl:namespace-alias stylesheet-prefix="foo"
139  * result-prefix="zar"/>
140  *
141  * Same target namespace URI for multiple different aliases:
142  * All alias-definitions will be used.
143  * Example:
144  * <xsl:namespace-alias stylesheet-prefix="bar"
145  * result-prefix="foo"/>
146  *
147  * <xsl:namespace-alias stylesheet-prefix="zar"
148  * result-prefix="foo"/>
149  * Cases using #default:
150  * <xsl:namespace-alias stylesheet-prefix="#default"
151  * result-prefix="#default"/>
152  * TODO: Has this an effect at all?
153  *
154  * <xsl:namespace-alias stylesheet-prefix="foo"
155  * result-prefix="#default"/>
156  * From namespace to no namespace.
157  *
158  * <xsl:namespace-alias stylesheet-prefix="#default"
159  * result-prefix="foo"/>
160  * From no namespace to namespace.
161  */
162 
163 
164  /*
165  * Store the ns-node in the alias-object.
166  */
167  alias = xsltNewNsAlias(XSLT_CCTXT(style));
168  if (alias == NULL)
169  return;
170  alias->literalNs = literalNs;
171  alias->targetNs = targetNs;
172  XSLT_CCTXT(style)->hasNsAliases = 1;
173 
174 
175 #else /* XSLT_REFACTORED */
176  const xmlChar *literalNsName;
177  const xmlChar *targetNsName;
178 
179 
180  if ((style == NULL) || (node == NULL))
181  return;
182 
183  stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
184  if (stylePrefix == NULL) {
186  "namespace-alias: stylesheet-prefix attribute missing\n");
187  return;
188  }
189  resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
190  if (resultPrefix == NULL) {
192  "namespace-alias: result-prefix attribute missing\n");
193  goto error;
194  }
195 
196  if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) {
197  literalNs = xmlSearchNs(node->doc, node, NULL);
198  if (literalNs == NULL) {
199  literalNsName = NULL;
200  } else
201  literalNsName = literalNs->href; /* Yes - set for nsAlias table */
202  } else {
203  literalNs = xmlSearchNs(node->doc, node, stylePrefix);
204 
205  if ((literalNs == NULL) || (literalNs->href == NULL)) {
207  "namespace-alias: prefix %s not bound to any namespace\n",
208  stylePrefix);
209  goto error;
210  } else
211  literalNsName = literalNs->href;
212  }
213 
214  /*
215  * When "#default" is used for result, if a default namespace has not
216  * been explicitly declared the special value UNDEFINED_DEFAULT_NS is
217  * put into the nsAliases table
218  */
219  if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) {
220  targetNs = xmlSearchNs(node->doc, node, NULL);
221  if (targetNs == NULL) {
222  targetNsName = UNDEFINED_DEFAULT_NS;
223  } else
224  targetNsName = targetNs->href;
225  } else {
226  targetNs = xmlSearchNs(node->doc, node, resultPrefix);
227 
228  if ((targetNs == NULL) || (targetNs->href == NULL)) {
230  "namespace-alias: prefix %s not bound to any namespace\n",
231  resultPrefix);
232  goto error;
233  } else
234  targetNsName = targetNs->href;
235  }
236  /*
237  * Special case: if #default is used for
238  * the stylesheet-prefix (literal namespace) and there's no default
239  * namespace in scope, we'll use style->defaultAlias for this.
240  */
241  if (literalNsName == NULL) {
242  if (targetNs != NULL) {
243  /*
244  * BUG TODO: Is it not sufficient to have only 1 field for
245  * this, since subsequently alias declarations will
246  * overwrite this.
247  * Example:
248  * <xsl:namespace-alias result-prefix="foo"
249  * stylesheet-prefix="#default"/>
250  * <xsl:namespace-alias result-prefix="bar"
251  * stylesheet-prefix="#default"/>
252  * The mapping for "foo" won't be visible anymore.
253  */
254  style->defaultAlias = targetNs->href;
255  }
256  } else {
257  if (style->nsAliases == NULL)
258  style->nsAliases = xmlHashCreate(10);
259  if (style->nsAliases == NULL) {
261  "namespace-alias: cannot create hash table\n");
262  goto error;
263  }
265  literalNsName, (void *) targetNsName);
266  }
267 #endif /* else of XSLT_REFACTORED */
268 
269 error:
270  if (stylePrefix != NULL)
271  xmlFree(stylePrefix);
272  if (resultPrefix != NULL)
273  xmlFree(resultPrefix);
274 }
#define error(str)
Definition: mkdosfs.c:1605
Definition: tree.h:389
XMLPUBFUN int XMLCALL xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata)
Definition: hash.c:387
#define UNDEFINED_DEFAULT_NS
Definition: namespaces.h:30
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
smooth NULL
Definition: ftsmooth.c:416
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
XMLPUBFUN xmlChar *XMLCALL xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:174
unsigned char xmlChar
Definition: xmlstring.h:28
const WCHAR * alias
Definition: main.c:67
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
Arabic default style
Definition: afstyles.h:93
const xmlChar * href
Definition: tree.h:392
Definition: dlist.c:348

Referenced by xsltParseStylesheetTop().