17d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/*
27d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * namespaces.c: Implementation of the XSLT namespaces handling
37d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
47d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Reference:
57d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *   http://www.w3.org/TR/1999/REC-xslt-19991116
67d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
77d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * See Copyright for the status of this software.
87d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
97d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * daniel@veillard.com
107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#define IN_LIBXSLT
137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "libxslt.h"
147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <string.h>
167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_SYS_TYPES_H
187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <sys/types.h>
197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_MATH_H
217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <math.h>
227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_FLOAT_H
247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <float.h>
257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_IEEEFP_H
277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <ieeefp.h>
287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_NAN_H
307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <nan.h>
317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_CTYPE_H
337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <ctype.h>
347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifndef	XSLT_NEED_TRIO
367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <stdio.h>
377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#else
387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <trio.h>
397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlmemory.h>
427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/tree.h>
437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/hash.h>
447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlerror.h>
457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/uri.h>
467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xslt.h"
477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltInternals.h"
487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltutils.h"
497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "namespaces.h"
507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "imports.h"
517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/************************************************************************
537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *									*
547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *			Module interfaces				*
557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *									*
567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ************************************************************************/
577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef XSLT_REFACTORED
597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangstatic xsltNsAliasPtr
607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltNewNsAlias(xsltCompilerCtxtPtr cctxt)
617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltNsAliasPtr ret;
637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cctxt == NULL)
657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias));
687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (ret == NULL) {
697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, cctxt->style, NULL,
707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "Internal error in xsltNewNsAlias(): Memory allocation failed.\n");
717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	cctxt->style->errors++;
727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    memset(ret, 0, sizeof(xsltNsAlias));
757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * TODO: Store the item at current stylesheet-level.
777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    ret->next = cctxt->nsAliases;
797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    cctxt->nsAliases = ret;
807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(ret);
827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif /* XSLT_REFACTORED */
847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltNamespaceAlias:
867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @style:  the XSLT stylesheet
877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @node:  the xsl:namespace-alias node
887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Read the stylesheet-prefix and result-prefix attributes, register
907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * them as well as the corresponding namespace.
917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid
937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node)
947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *resultPrefix = NULL;
967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *stylePrefix = NULL;
977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlNsPtr literalNs = NULL;
987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlNsPtr targetNs = NULL;
997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef XSLT_REFACTORED
1017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltNsAliasPtr alias;
1027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((style == NULL) || (node == NULL))
1047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return;
1057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * SPEC XSLT 1.0:
1087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  "If a namespace URI is declared to be an alias for multiple
1097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  different namespace URIs, then the declaration with the highest
1107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  import precedence is used. It is an error if there is more than
1117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  one such declaration. An XSLT processor may signal the error;
1127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  if it does not signal the error, it must recover by choosing,
1137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  from amongst the declarations with the highest import precedence,
1147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  the one that occurs last in the stylesheet."
1157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *
1167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * SPEC TODO: Check for the errors mentioned above.
1177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
1187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * NOTE that the XSLT 2.0 also *does* use the NULL namespace if
1207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  "#default" is used and there's no default namespace is scope.
1217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  I.e., this is *not* an error.
1227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  Most XSLT 1.0 implementations work this way.
1237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  The XSLT 1.0 spec has nothing to say on the subject.
1247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
1257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Attribute "stylesheet-prefix".
1277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
1287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
1297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (stylePrefix == NULL) {
1307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, node,
1317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "The attribute 'stylesheet-prefix' is missing.\n");
1327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return;
1337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default"))
1357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	literalNs = xmlSearchNs(node->doc, node, NULL);
1367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    else {
1377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	literalNs = xmlSearchNs(node->doc, node, stylePrefix);
1387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (literalNs == NULL) {
1397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, node,
1407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "Attribute 'stylesheet-prefix': There's no namespace "
1417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		"declaration in scope for the prefix '%s'.\n",
1427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    stylePrefix);
1437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
1447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Attribute "result-prefix".
1487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
1497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
1507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (resultPrefix == NULL) {
1517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, node,
1527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "The attribute 'result-prefix' is missing.\n");
1537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
1547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default"))
1567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	targetNs = xmlSearchNs(node->doc, node, NULL);
1577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    else {
1587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	targetNs = xmlSearchNs(node->doc, node, resultPrefix);
1597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (targetNs == NULL) {
1617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	   xsltTransformError(NULL, style, node,
1627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "Attribute 'result-prefix': There's no namespace "
1637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		"declaration in scope for the prefix '%s'.\n",
1647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    stylePrefix);
1657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
1667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Same alias for multiple different target namespace URIs:
1717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  TODO: The one with the highest import precedence is used.
1727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  Example:
1737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="foo"
1747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="bar"/>
1757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="foo"
1777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="zar"/>
1787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Same target namespace URI for multiple different aliases:
1807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  All alias-definitions will be used.
1817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  Example:
1827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="bar"
1837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="foo"/>
1847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="zar"
1867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="foo"/>
1877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Cases using #default:
1887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="#default"
1897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="#default"/>
1907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  TODO: Has this an effect at all?
1917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="foo"
1937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="#default"/>
1947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  From namespace to no namespace.
1957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *
1967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  <xsl:namespace-alias stylesheet-prefix="#default"
1977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *                       result-prefix="foo"/>
1987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  From no namespace to namespace.
1997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
2007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     /*
2037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Store the ns-node in the alias-object.
2047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
2057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    alias = xsltNewNsAlias(XSLT_CCTXT(style));
2067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (alias == NULL)
2077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return;
2087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    alias->literalNs = literalNs;
2097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    alias->targetNs = targetNs;
2107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    XSLT_CCTXT(style)->hasNsAliases = 1;
2117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#else /* XSLT_REFACTORED */
2147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    const xmlChar *literalNsName;
2157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    const xmlChar *targetNsName;
2167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((style == NULL) || (node == NULL))
2197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return;
2207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
2227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (stylePrefix == NULL) {
2237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, node,
2247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "namespace-alias: stylesheet-prefix attribute missing\n");
2257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return;
2267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
2287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (resultPrefix == NULL) {
2297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, node,
2307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "namespace-alias: result-prefix attribute missing\n");
2317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
2327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) {
2357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	literalNs = xmlSearchNs(node->doc, node, NULL);
2367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (literalNs == NULL) {
2377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    literalNsName = NULL;
2387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else
2397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    literalNsName = literalNs->href; /* Yes - set for nsAlias table */
2407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
2417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	literalNs = xmlSearchNs(node->doc, node, stylePrefix);
2427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if ((literalNs == NULL) || (literalNs->href == NULL)) {
2447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, node,
2457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "namespace-alias: prefix %s not bound to any namespace\n",
2467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang					stylePrefix);
2477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
2487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else
2497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    literalNsName = literalNs->href;
2507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
2537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * When "#default" is used for result, if a default namespace has not
2547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * been explicitly declared the special value UNDEFINED_DEFAULT_NS is
2557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * put into the nsAliases table
2567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
2577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) {
2587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	targetNs = xmlSearchNs(node->doc, node, NULL);
2597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (targetNs == NULL) {
2607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    targetNsName = UNDEFINED_DEFAULT_NS;
2617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else
2627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    targetNsName = targetNs->href;
2637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
2647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	targetNs = xmlSearchNs(node->doc, node, resultPrefix);
2657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if ((targetNs == NULL) || (targetNs->href == NULL)) {
2677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, node,
2687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "namespace-alias: prefix %s not bound to any namespace\n",
2697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang					resultPrefix);
2707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
2717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else
2727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    targetNsName = targetNs->href;
2737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
2757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Special case: if #default is used for
2767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  the stylesheet-prefix (literal namespace) and there's no default
2777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     *  namespace in scope, we'll use style->defaultAlias for this.
2787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
2797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (literalNsName == NULL) {
2807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (targetNs != NULL) {
2817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
2827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * BUG TODO: Is it not sufficient to have only 1 field for
2837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  this, since subsequently alias declarations will
2847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  overwrite this.
2857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  Example:
2867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *   <xsl:namespace-alias result-prefix="foo"
2877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *                        stylesheet-prefix="#default"/>
2887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *   <xsl:namespace-alias result-prefix="bar"
2897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *                        stylesheet-prefix="#default"/>
2907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  The mapping for "foo" won't be visible anymore.
2917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
2927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang            style->defaultAlias = targetNs->href;
2937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
2947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
2957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (style->nsAliases == NULL)
2967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    style->nsAliases = xmlHashCreate(10);
2977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (style->nsAliases == NULL) {
2987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, node,
2997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "namespace-alias: cannot create hash table\n");
3007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
3017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        }
3027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
3037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    literalNsName, (void *) targetNsName);
3047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
3057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif /* else of XSLT_REFACTORED */
3067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangerror:
3087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (stylePrefix != NULL)
3097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(stylePrefix);
3107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (resultPrefix != NULL)
3117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(resultPrefix);
3127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
3137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
3157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltGetSpecialNamespace:
3167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  the transformation context
3177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @invocNode: the invoking node; e.g. a literal result element/attr;
3187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *             only used for error reports
3197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nsName:  the namespace name (or NULL)
3207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nsPrefix:  the suggested namespace prefix (or NULL)
3217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @target:  the result element on which to anchor a namespace
3227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Find a matching (prefix and ns-name) ns-declaration
3247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * for the requested @nsName and @nsPrefix in the result tree.
3257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * If none is found then a new ns-declaration will be
3267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * added to @resultElem. If, in this case, the given prefix is
3277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * already in use, then a ns-declaration with a modified ns-prefix
3287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * be we created. Note that this function's priority is to
3297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * preserve ns-prefixes; it will only change a prefix if there's
3307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * a namespace clash.
3317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * If both @nsName and @nsPrefix are NULL, then this will try to
3327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * "undeclare" a default namespace by declaring an xmlns="".
3337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns a namespace declaration or NULL.
3357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
3367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlNsPtr
3377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode,
3387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		const xmlChar *nsName, const xmlChar *nsPrefix,
3397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		xmlNodePtr target)
3407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
3417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlNsPtr ns;
3427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    int prefixOccupied = 0;
3437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((ctxt == NULL) || (target == NULL) ||
3457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	(target->type != XML_ELEMENT_NODE))
3467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
3477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
3497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * NOTE: Namespace exclusion and ns-aliasing is performed at
3507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  compilation-time in the refactored code; so this need not be done
3517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  here (it was in the old code).
3527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * NOTE: @invocNode was named @cur in the old code and was documented to
3537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  be an input node; since it was only used to anchor an error report
3547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  somewhere, we can safely change this to @invocNode, which now
3557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  will be the XSLT instruction (also a literal result element/attribute),
3567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  which was responsible for this call.
3577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
3587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
3597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * OPTIMIZE TODO: This all could be optimized by keeping track of
3607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  the ns-decls currently in-scope via a specialized context.
3617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
3627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) {
3637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
3647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* NOTE: the "undeclaration" of the default namespace was
3657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* part of the logic of the old xsltGetSpecialNamespace() code,
3667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* so we'll keep that mechanism.
3677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Related to the old code: bug #302020:
3687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
3697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
3707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* OPTIMIZE TODO: This all could be optimized by keeping track of
3717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*  the ns-decls currently in-scope via a specialized context.
3727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
3737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
3747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Search on the result element itself.
3757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
3767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (target->nsDef != NULL) {
3777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = target->nsDef;
3787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    do {
3797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		if (ns->prefix == NULL) {
3807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    if ((ns->href != NULL) && (ns->href[0] != 0)) {
3817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			/*
3827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* Raise a namespace normalization error.
3837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			*/
3847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			xsltTransformError(ctxt, NULL, invocNode,
3857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			    "Namespace normalization error: Cannot undeclare "
3867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			    "the default namespace, since the default namespace "
3877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			    "'%s' is already declared on the result element "
3887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			    "'%s'.\n", ns->href, target->name);
3897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			return(NULL);
3907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    } else {
3917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			/*
3927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* The default namespace was undeclared on the
3937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* result element.
3947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			*/
3957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			return(NULL);
3967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    }
3977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    break;
3987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		}
3997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		ns = ns->next;
4007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    } while (ns != NULL);
4017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
4027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if ((target->parent != NULL) &&
4037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    (target->parent->type == XML_ELEMENT_NODE))
4047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	{
4057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
4067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * The parent element is in no namespace, so assume
4077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * that there is no default namespace in scope.
4087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
4097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (target->parent->ns == NULL)
4107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(NULL);
4117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
4127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = xmlSearchNs(target->doc, target->parent,
4137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		NULL);
4147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
4157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Fine if there's no default ns is scope, or if the
4167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * default ns was undeclared.
4177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
4187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0))
4197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(NULL);
4207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
4217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
4227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Undeclare the default namespace.
4237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
4247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xmlNewNs(target, BAD_CAST "", NULL);
4257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /* TODO: Check result */
4267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(NULL);
4277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
4287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
4297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
4307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
4317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Handle the XML namespace.
4327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * QUESTION: Is this faster than using xmlStrEqual() anyway?
4337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
4347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((nsPrefix != NULL) &&
4357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	(nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') &&
4367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	(nsPrefix[2] == 'l') && (nsPrefix[3] == 0))
4377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    {
4387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(xmlSearchNs(target->doc, target, nsPrefix));
4397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
4407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
4417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * First: search on the result element itself.
4427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
4437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (target->nsDef != NULL) {
4447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = target->nsDef;
4457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	do {
4467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if ((ns->prefix == NULL) == (nsPrefix == NULL)) {
4477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		if (ns->prefix == nsPrefix) {
4487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    if (xmlStrEqual(ns->href, nsName))
4497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			return(ns);
4507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    prefixOccupied = 1;
4517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    break;
4527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		} else if (xmlStrEqual(ns->prefix, nsPrefix)) {
4537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    if (xmlStrEqual(ns->href, nsName))
4547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			return(ns);
4557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    prefixOccupied = 1;
4567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    break;
4577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		}
4587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
4597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = ns->next;
4607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} while (ns != NULL);
4617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
4627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (prefixOccupied) {
4637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
4647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* If the ns-prefix is occupied by an other ns-decl on the
4657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* result element, then this means:
4667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* 1) The desired prefix is shadowed
4677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* 2) There's no way around changing the prefix
4687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*
4697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Try a desperate search for an in-scope ns-decl
4707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* with a matching ns-name before we use the last option,
4717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* which is to recreate the ns-decl with a modified prefix.
4727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
4737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = xmlSearchNsByHref(target->doc, target, nsName);
4747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (ns != NULL)
4757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(ns);
4767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
4777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
4787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Fallback to changing the prefix.
4797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
4807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else if ((target->parent != NULL) &&
4817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	(target->parent->type == XML_ELEMENT_NODE))
4827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    {
4837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
4847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Try to find a matching ns-decl in the ancestor-axis.
4857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*
4867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Check the common case: The parent element of the current
4877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* result element is in the same namespace (with an equal ns-prefix).
4887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
4897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if ((target->parent->ns != NULL) &&
4907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL)))
4917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	{
4927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = target->parent->ns;
4937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
4947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (nsPrefix == NULL) {
4957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		if (xmlStrEqual(ns->href, nsName))
4967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    return(ns);
4977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    } else if (xmlStrEqual(ns->prefix, nsPrefix) &&
4987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		xmlStrEqual(ns->href, nsName))
4997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    {
5007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(ns);
5017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
5027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
5037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
5047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Lookup the remaining in-scope namespaces.
5057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
5067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = xmlSearchNs(target->doc, target->parent, nsPrefix);
5077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (ns != NULL) {
5087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (xmlStrEqual(ns->href, nsName))
5097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(ns);
5107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
5117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Now check for a nasty case: We need to ensure that the new
5127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * ns-decl won't shadow a prefix in-use by an existing attribute.
5137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * <foo xmlns:a="urn:test:a">
5147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *   <bar a:a="val-a">
5157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *     <xsl:attribute xmlns:a="urn:test:b" name="a:b">
5167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *        val-b</xsl:attribute>
5177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *   </bar>
5187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * </foo>
5197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
5207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (target->properties) {
5217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		xmlAttrPtr attr = target->properties;
5227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		do {
5237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    if ((attr->ns) &&
5247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			xmlStrEqual(attr->ns->prefix, nsPrefix))
5257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    {
5267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			/*
5277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* Bad, this prefix is already in use.
5287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* Since we'll change the prefix anyway, try
5297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* a search for a matching ns-decl based on the
5307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			* namespace name.
5317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			*/
5327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			ns = xmlSearchNsByHref(target->doc, target, nsName);
5337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			if (ns != NULL)
5347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			    return(ns);
5357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			goto declare_new_prefix;
5367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    }
5377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    attr = attr->next;
5387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		} while (attr != NULL);
5397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
5407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else {
5417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
5427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Either no matching ns-prefix was found or the namespace is
5437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * shadowed.
5447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Create a new ns-decl on the current result element.
5457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *
5467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * Hmm, we could also try to reuse an in-scope
5477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * namespace with a matching ns-name but a different
5487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * ns-prefix.
5497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * What has higher priority?
5507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  1) If keeping the prefix: create a new ns-decl.
5517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  2) If reusal: first lookup ns-names; then fallback
5527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *     to creation of a new ns-decl.
5537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * REVISIT: this currently uses case 1) although
5547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  the old way was use xmlSearchNsByHref() and to let change
5557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    *  the prefix.
5567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
5577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#if 0
5587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = xmlSearchNsByHref(target->doc, target, nsName);
5597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (ns != NULL)
5607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(ns);
5617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
5627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
5637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
5647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Create the ns-decl on the current result element.
5657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
5667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = xmlNewNs(target, nsName, nsPrefix);
5677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/* TODO: check errors */
5687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(ns);
5697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
5707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
5717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* This is either the root of the tree or something weird is going on.
5727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
5737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = xmlNewNs(target, nsName, nsPrefix);
5747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/* TODO: Check result */
5757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(ns);
5767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
5777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
5787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangdeclare_new_prefix:
5797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
5807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Fallback: we need to generate a new prefix and declare the namespace
5817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * on the result element.
5827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
5837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    {
5847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlChar pref[30];
5857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	int counter = 1;
5867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
5877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (nsPrefix == NULL) {
5887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    nsPrefix = "ns";
5897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
5907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
5917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	do {
5927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++);
5937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ns = xmlSearchNs(target->doc, target, BAD_CAST pref);
5947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (counter > 1000) {
5957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		xsltTransformError(ctxt, NULL, invocNode,
5967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    "Internal error in xsltAcquireResultInScopeNs(): "
5977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    "Failed to compute a unique ns-prefix for the "
5987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    "generated element");
5997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(NULL);
6007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
6017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} while (ns != NULL);
6027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ns = xmlNewNs(target, nsName, BAD_CAST pref);
6037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/* TODO: Check result */
6047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(ns);
6057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
6067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(NULL);
6077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
6087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
6107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltGetNamespace:
6117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  a transformation context
6127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the input node
6137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ns:  the namespace
6147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @out:  the output node (or its parent)
6157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
6167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Find a matching (prefix and ns-name) ns-declaration
6177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * for the requested @ns->prefix and @ns->href in the result tree.
6187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * If none is found then a new ns-declaration will be
6197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * added to @resultElem. If, in this case, the given prefix is
6207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * already in use, then a ns-declaration with a modified ns-prefix
6217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * be we created.
6227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
6237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Called by:
6247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  - xsltCopyPropList() (*not*  anymore)
6257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  - xsltShallowCopyElement()
6267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  - xsltCopyTreeInternal() (*not*  anymore)
6277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  - xsltApplySequenceConstructor() (*not* in the refactored code),
6287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  - xsltElement() (*not* anymore)
6297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
6307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns a namespace declaration or NULL in case of
6317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *         namespace fixup failures or API or internal errors.
6327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
6337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlNsPtr
6347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns,
6357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	         xmlNodePtr out)
6367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
6377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (ns == NULL)
6397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
6407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef XSLT_REFACTORED
6427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
6437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Namespace exclusion and ns-aliasing is performed at
6447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * compilation-time in the refactored code.
6457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Additionally, aliasing is not intended for non Literal
6467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * Result Elements.
6477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
6487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out));
6497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#else
6507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    {
6517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltStylesheetPtr style;
6527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	const xmlChar *URI = NULL; /* the replacement URI */
6537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if ((ctxt == NULL) || (cur == NULL) || (out == NULL))
6557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(NULL);
6567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style = ctxt->style;
6587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	while (style != NULL) {
6597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (style->nsAliases != NULL)
6607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		URI = (const xmlChar *)
6617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		xmlHashLookup(style->nsAliases, ns->href);
6627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (URI != NULL)
6637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		break;
6647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    style = xsltNextImport(style);
6667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
6677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (URI == UNDEFINED_DEFAULT_NS) {
6707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out));
6717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#if 0
6727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /*
6737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * TODO: Removed, since wrong. If there was no default
6747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * namespace in the stylesheet then this must resolve to
6757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    * the NULL namespace.
6767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    */
6777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xmlNsPtr dflt;
6787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    dflt = xmlSearchNs(cur->doc, cur, NULL);
6797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (dflt != NULL)
6807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		URI = dflt->href;
6817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    else
6827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return NULL;
6837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
6847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else if (URI == NULL)
6857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    URI = ns->href;
6867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out));
6887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
6897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
6907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
6917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
6927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
6937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltGetPlainNamespace:
6947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  a transformation context
6957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the input node
6967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ns:  the namespace
6977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @out:  the result element
6987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
6997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Obsolete.
7007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * *Not* called by any Libxslt/Libexslt function.
7017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Exaclty the same as xsltGetNamespace().
7027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
7037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns a namespace declaration or NULL in case of
7047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *         namespace fixup failures or API or internal errors.
7057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
7067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlNsPtr
7077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur,
7087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang                      xmlNsPtr ns, xmlNodePtr out)
7097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
7107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(xsltGetNamespace(ctxt, cur, ns, out));
7117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
7127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
7137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
7147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltCopyNamespaceList:
7157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  a transformation context
7167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @node:  the target node
7177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the first namespace
7187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
7197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Do a copy of an namespace list. If @node is non-NULL the
7207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * new namespaces are added automatically. This handles namespaces
7217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * aliases.
7227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * This function is intended only for *internal* use at
7237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * transformation-time for copying ns-declarations of Literal
7247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Result Elements.
7257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
7267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Called by:
7277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *   xsltCopyTreeInternal() (transform.c)
7287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *   xsltShallowCopyElem() (transform.c)
7297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
7307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * REVISIT: This function won't be used in the refactored code.
7317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
7327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns: a new xmlNsPtr, or NULL in case of error.
7337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
7347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlNsPtr
7357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node,
7367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	              xmlNsPtr cur) {
7377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlNsPtr ret = NULL, tmp;
7387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlNsPtr p = NULL,q;
7397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
7407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cur == NULL)
7417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
7427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cur->type != XML_NAMESPACE_DECL)
7437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
7447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
7457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
7467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * One can add namespaces only on element nodes
7477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
7487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
7497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	node = NULL;
7507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
7517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (cur != NULL) {
7527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (cur->type != XML_NAMESPACE_DECL)
7537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    break;
7547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
7557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
7567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	 * Avoid duplicating namespace declarations in the tree if
7577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	 * a matching declaration is in scope.
7587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	 */
7597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (node != NULL) {
7607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if ((node->ns != NULL) &&
7617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		(xmlStrEqual(node->ns->prefix, cur->prefix)) &&
7627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        	(xmlStrEqual(node->ns->href, cur->href))) {
7637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		cur = cur->next;
7647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		continue;
7657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
7667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    tmp = xmlSearchNs(node->doc, node, cur->prefix);
7677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) {
7687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		cur = cur->next;
7697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		continue;
7707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
7717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
7727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef XSLT_REFACTORED
7737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
7747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* Namespace exclusion and ns-aliasing is performed at
7757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* compilation-time in the refactored code.
7767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
7777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	q = xmlNewNs(node, cur->href, cur->prefix);
7787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (p == NULL) {
7797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    ret = p = q;
7807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else {
7817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    p->next = q;
7827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    p = q;
7837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
7847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#else
7857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	/*
7867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	* TODO: Remove this if the refactored code gets enabled.
7877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	*/
7887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
7897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    const xmlChar *URI;
7907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    /* TODO apply cascading */
7917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
7927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		                                  cur->href);
7937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (URI == UNDEFINED_DEFAULT_NS)
7947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        continue;
7957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (URI != NULL) {
7967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		q = xmlNewNs(node, URI, cur->prefix);
7977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    } else {
7987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		q = xmlNewNs(node, cur->href, cur->prefix);
7997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
8007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (p == NULL) {
8017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		ret = p = q;
8027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    } else {
8037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		p->next = q;
8047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		p = q;
8057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
8067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
8077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
8087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	cur = cur->next;
8097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
8107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(ret);
8117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
8127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
8137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
8147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltCopyNamespace:
8157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  a transformation context
8167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @elem:  the target element node
8177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ns:  the namespace node
8187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
8197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Copies a namespace node (declaration). If @elem is not NULL,
8207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * then the new namespace will be declared on @elem.
8217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
8227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns: a new xmlNsPtr, or NULL in case of an error.
8237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
8247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlNsPtr
8257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
8267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		  xmlNodePtr elem, xmlNsPtr ns)
8277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{
8287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
8297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
8307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
8317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * One can add namespaces only on element nodes
8327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
8337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
8347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(xmlNewNs(NULL, ns->href, ns->prefix));
8357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    else
8367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(xmlNewNs(elem, ns->href, ns->prefix));
8377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
8387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
8397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
8407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
8417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFreeNamespaceAliasHashes:
8427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @style: an XSLT stylesheet
8437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
8447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Free up the memory used by namespaces aliases
8457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
8467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid
8477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) {
8487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (style->nsAliases != NULL)
8497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL);
8507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->nsAliases = NULL;
8517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
852