15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespaces.c: Implementation of the XSLT namespaces handling 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reference: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/1999/REC-xslt-19991116 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXSLT 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxslt.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TYPES_H 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_MATH_H 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_FLOAT_H 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <float.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_IEEEFP_H 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ieeefp.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_NAN_H 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <nan.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CTYPE_H 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef XSLT_NEED_TRIO 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <trio.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/hash.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xslt.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltInternals.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltutils.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "namespaces.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "imports.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Module interfaces * 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XSLT_REFACTORED 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltNsAliasPtr 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNewNsAlias(xsltCompilerCtxtPtr cctxt) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltNsAliasPtr ret; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cctxt == NULL) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias)); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, cctxt->style, NULL, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltNewNsAlias(): Memory allocation failed.\n"); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cctxt->style->errors++; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xsltNsAlias)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Store the item at current stylesheet-level. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->next = cctxt->nsAliases; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cctxt->nsAliases = ret; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* XSLT_REFACTORED */ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNamespaceAlias: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: the XSLT stylesheet 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the xsl:namespace-alias node 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read the stylesheet-prefix and result-prefix attributes, register 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them as well as the corresponding namespace. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *resultPrefix = NULL; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *stylePrefix = NULL; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr literalNs = NULL; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr targetNs = NULL; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XSLT_REFACTORED 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltNsAliasPtr alias; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((style == NULL) || (node == NULL)) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPEC XSLT 1.0: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "If a namespace URI is declared to be an alias for multiple 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * different namespace URIs, then the declaration with the highest 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * import precedence is used. It is an error if there is more than 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * one such declaration. An XSLT processor may signal the error; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if it does not signal the error, it must recover by choosing, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from amongst the declarations with the highest import precedence, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the one that occurs last in the stylesheet." 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPEC TODO: Check for the errors mentioned above. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE that the XSLT 2.0 also *does* use the NULL namespace if 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "#default" is used and there's no default namespace is scope. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * I.e., this is *not* an error. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Most XSLT 1.0 implementations work this way. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The XSLT 1.0 spec has nothing to say on the subject. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Attribute "stylesheet-prefix". 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stylePrefix == NULL) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The attribute 'stylesheet-prefix' is missing.\n"); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNs = xmlSearchNs(node->doc, node, NULL); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNs = xmlSearchNs(node->doc, node, stylePrefix); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (literalNs == NULL) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attribute 'stylesheet-prefix': There's no namespace " 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "declaration in scope for the prefix '%s'.\n", 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stylePrefix); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Attribute "result-prefix". 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resultPrefix == NULL) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The attribute 'result-prefix' is missing.\n"); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNs = xmlSearchNs(node->doc, node, NULL); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNs = xmlSearchNs(node->doc, node, resultPrefix); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (targetNs == NULL) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attribute 'result-prefix': There's no namespace " 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "declaration in scope for the prefix '%s'.\n", 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stylePrefix); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Same alias for multiple different target namespace URIs: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: The one with the highest import precedence is used. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Example: 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="foo" 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="bar"/> 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="foo" 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="zar"/> 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Same target namespace URI for multiple different aliases: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All alias-definitions will be used. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Example: 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="bar" 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="foo"/> 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="zar" 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="foo"/> 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cases using #default: 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="#default" 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="#default"/> 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Has this an effect at all? 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="foo" 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="#default"/> 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * From namespace to no namespace. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias stylesheet-prefix="#default" 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result-prefix="foo"/> 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * From no namespace to namespace. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Store the ns-node in the alias-object. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alias = xsltNewNsAlias(XSLT_CCTXT(style)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alias == NULL) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alias->literalNs = literalNs; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alias->targetNs = targetNs; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_CCTXT(style)->hasNsAliases = 1; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* XSLT_REFACTORED */ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *literalNsName; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *targetNsName; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((style == NULL) || (node == NULL)) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stylePrefix == NULL) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "namespace-alias: stylesheet-prefix attribute missing\n"); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resultPrefix == NULL) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "namespace-alias: result-prefix attribute missing\n"); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNs = xmlSearchNs(node->doc, node, NULL); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (literalNs == NULL) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNsName = NULL; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNsName = literalNs->href; /* Yes - set for nsAlias table */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNs = xmlSearchNs(node->doc, node, stylePrefix); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((literalNs == NULL) || (literalNs->href == NULL)) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "namespace-alias: prefix %s not bound to any namespace\n", 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stylePrefix); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNsName = literalNs->href; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * When "#default" is used for result, if a default namespace has not 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * been explicitly declared the special value UNDEFINED_DEFAULT_NS is 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * put into the nsAliases table 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNs = xmlSearchNs(node->doc, node, NULL); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (targetNs == NULL) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNsName = UNDEFINED_DEFAULT_NS; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNsName = targetNs->href; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNs = xmlSearchNs(node->doc, node, resultPrefix); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((targetNs == NULL) || (targetNs->href == NULL)) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "namespace-alias: prefix %s not bound to any namespace\n", 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resultPrefix); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetNsName = targetNs->href; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Special case: if #default is used for 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the stylesheet-prefix (literal namespace) and there's no default 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace in scope, we'll use style->defaultAlias for this. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (literalNsName == NULL) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (targetNs != NULL) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUG TODO: Is it not sufficient to have only 1 field for 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this, since subsequently alias declarations will 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * overwrite this. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Example: 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias result-prefix="foo" 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stylesheet-prefix="#default"/> 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:namespace-alias result-prefix="bar" 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stylesheet-prefix="#default"/> 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The mapping for "foo" won't be visible anymore. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style->defaultAlias = targetNs->href; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->nsAliases == NULL) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style->nsAliases = xmlHashCreate(10); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->nsAliases == NULL) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "namespace-alias: cannot create hash table\n"); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashAddEntry((xmlHashTablePtr) style->nsAliases, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) literalNsName, (void *) targetNsName); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* else of XSLT_REFACTORED */ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stylePrefix != NULL) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stylePrefix); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resultPrefix != NULL) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(resultPrefix); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetSpecialNamespace: 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the transformation context 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @invocNode: the invoking node; e.g. a literal result element/attr; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * only used for error reports 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsName: the namespace name (or NULL) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsPrefix: the suggested namespace prefix (or NULL) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @target: the result element on which to anchor a namespace 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find a matching (prefix and ns-name) ns-declaration 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the requested @nsName and @nsPrefix in the result tree. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If none is found then a new ns-declaration will be 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * added to @resultElem. If, in this case, the given prefix is 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * already in use, then a ns-declaration with a modified ns-prefix 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be we created. Note that this function's priority is to 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * preserve ns-prefixes; it will only change a prefix if there's 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a namespace clash. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If both @nsName and @nsPrefix are NULL, then this will try to 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "undeclare" a default namespace by declaring an xmlns="". 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a namespace declaration or NULL. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNsPtr 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *nsName, const xmlChar *nsPrefix, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr target) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int prefixOccupied = 0; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (target == NULL) || 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (target->type != XML_ELEMENT_NODE)) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE: Namespace exclusion and ns-aliasing is performed at 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compilation-time in the refactored code; so this need not be done 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * here (it was in the old code). 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE: @invocNode was named @cur in the old code and was documented to 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be an input node; since it was only used to anchor an error report 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * somewhere, we can safely change this to @invocNode, which now 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be the XSLT instruction (also a literal result element/attribute), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which was responsible for this call. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OPTIMIZE TODO: This all could be optimized by keeping track of 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ns-decls currently in-scope via a specialized context. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE: the "undeclaration" of the default namespace was 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * part of the logic of the old xsltGetSpecialNamespace() code, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so we'll keep that mechanism. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Related to the old code: bug #302020: 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OPTIMIZE TODO: This all could be optimized by keeping track of 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ns-decls currently in-scope via a specialized context. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Search on the result element itself. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->nsDef != NULL) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = target->nsDef; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns->prefix == NULL) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ns->href != NULL) && (ns->href[0] != 0)) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Raise a namespace normalization error. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(ctxt, NULL, invocNode, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Namespace normalization error: Cannot undeclare " 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "the default namespace, since the default namespace " 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "'%s' is already declared on the result element " 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "'%s'.\n", ns->href, target->name); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The default namespace was undeclared on the 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result element. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = ns->next; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ns != NULL); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target->parent != NULL) && 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (target->parent->type == XML_ELEMENT_NODE)) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The parent element is in no namespace, so assume 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that there is no default namespace in scope. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->parent->ns == NULL) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNs(target->doc, target->parent, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Fine if there's no default ns is scope, or if the 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * default ns was undeclared. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0)) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Undeclare the default namespace. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNewNs(target, BAD_CAST "", NULL); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: Check result */ 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle the XML namespace. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * QUESTION: Is this faster than using xmlStrEqual() anyway? 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nsPrefix != NULL) && 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') && 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (nsPrefix[2] == 'l') && (nsPrefix[3] == 0)) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlSearchNs(target->doc, target, nsPrefix)); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * First: search on the result element itself. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->nsDef != NULL) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = target->nsDef; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ns->prefix == NULL) == (nsPrefix == NULL)) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns->prefix == nsPrefix) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(ns->href, nsName)) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefixOccupied = 1; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(ns->prefix, nsPrefix)) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(ns->href, nsName)) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefixOccupied = 1; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = ns->next; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ns != NULL); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefixOccupied) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the ns-prefix is occupied by an other ns-decl on the 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result element, then this means: 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1) The desired prefix is shadowed 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2) There's no way around changing the prefix 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try a desperate search for an in-scope ns-decl 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with a matching ns-name before we use the last option, 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which is to recreate the ns-decl with a modified prefix. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNsByHref(target->doc, target, nsName); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns != NULL) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Fallback to changing the prefix. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((target->parent != NULL) && 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (target->parent->type == XML_ELEMENT_NODE)) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to find a matching ns-decl in the ancestor-axis. 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check the common case: The parent element of the current 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result element is in the same namespace (with an equal ns-prefix). 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target->parent->ns != NULL) && 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL))) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = target->parent->ns; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsPrefix == NULL) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(ns->href, nsName)) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(ns->prefix, nsPrefix) && 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStrEqual(ns->href, nsName)) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lookup the remaining in-scope namespaces. 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNs(target->doc, target->parent, nsPrefix); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns != NULL) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(ns->href, nsName)) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Now check for a nasty case: We need to ensure that the new 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ns-decl won't shadow a prefix in-use by an existing attribute. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <foo xmlns:a="urn:test:a"> 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <bar a:a="val-a"> 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <xsl:attribute xmlns:a="urn:test:b" name="a:b"> 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * val-b</xsl:attribute> 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </bar> 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </foo> 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->properties) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAttrPtr attr = target->properties; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((attr->ns) && 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStrEqual(attr->ns->prefix, nsPrefix)) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Bad, this prefix is already in use. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since we'll change the prefix anyway, try 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a search for a matching ns-decl based on the 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace name. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNsByHref(target->doc, target, nsName); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns != NULL) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto declare_new_prefix; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attr = attr->next; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (attr != NULL); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Either no matching ns-prefix was found or the namespace is 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shadowed. 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new ns-decl on the current result element. 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Hmm, we could also try to reuse an in-scope 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace with a matching ns-name but a different 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ns-prefix. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * What has higher priority? 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1) If keeping the prefix: create a new ns-decl. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2) If reusal: first lookup ns-names; then fallback 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to creation of a new ns-decl. 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * REVISIT: this currently uses case 1) although 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the old way was use xmlSearchNsByHref() and to let change 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the prefix. 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNsByHref(target->doc, target, nsName); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns != NULL) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create the ns-decl on the current result element. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlNewNs(target, nsName, nsPrefix); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: check errors */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is either the root of the tree or something weird is going on. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlNewNs(target, nsName, nsPrefix); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: Check result */ 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)declare_new_prefix: 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Fallback: we need to generate a new prefix and declare the namespace 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the result element. 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar pref[30]; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter = 1; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsPrefix == NULL) { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nsPrefix = "ns"; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNs(target->doc, target, BAD_CAST pref); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (counter > 1000) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(ctxt, NULL, invocNode, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltAcquireResultInScopeNs(): " 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to compute a unique ns-prefix for the " 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "generated element"); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ns != NULL); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlNewNs(target, nsName, BAD_CAST pref); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: Check result */ 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ns); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetNamespace: 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a transformation context 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the input node 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ns: the namespace 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out: the output node (or its parent) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find a matching (prefix and ns-name) ns-declaration 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the requested @ns->prefix and @ns->href in the result tree. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If none is found then a new ns-declaration will be 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * added to @resultElem. If, in this case, the given prefix is 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * already in use, then a ns-declaration with a modified ns-prefix 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be we created. 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called by: 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - xsltCopyPropList() (*not* anymore) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - xsltShallowCopyElement() 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - xsltCopyTreeInternal() (*not* anymore) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - xsltApplySequenceConstructor() (*not* in the refactored code), 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - xsltElement() (*not* anymore) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a namespace declaration or NULL in case of 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace fixup failures or API or internal errors. 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNsPtr 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr out) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns == NULL) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XSLT_REFACTORED 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Namespace exclusion and ns-aliasing is performed at 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compilation-time in the refactored code. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Additionally, aliasing is not intended for non Literal 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Result Elements. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr style; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *URI = NULL; /* the replacement URI */ 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (cur == NULL) || (out == NULL)) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style = ctxt->style; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (style != NULL) { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->nsAliases != NULL) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = (const xmlChar *) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashLookup(style->nsAliases, ns->href); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI != NULL) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style = xsltNextImport(style); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI == UNDEFINED_DEFAULT_NS) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out)); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Removed, since wrong. If there was no default 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace in the stylesheet then this must resolve to 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the NULL namespace. 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr dflt; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dflt = xmlSearchNs(cur->doc, cur, NULL); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dflt != NULL) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = dflt->href; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (URI == NULL) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = ns->href; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out)); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetPlainNamespace: 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a transformation context 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the input node 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ns: the namespace 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out: the result element 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Obsolete. 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * *Not* called by any Libxslt/Libexslt function. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Exaclty the same as xsltGetNamespace(). 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a namespace declaration or NULL in case of 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * namespace fixup failures or API or internal errors. 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNsPtr 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns, xmlNodePtr out) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xsltGetNamespace(ctxt, cur, ns, out)); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCopyNamespaceList: 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a transformation context 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the target node 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the first namespace 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do a copy of an namespace list. If @node is non-NULL the 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * new namespaces are added automatically. This handles namespaces 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * aliases. 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is intended only for *internal* use at 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transformation-time for copying ns-declarations of Literal 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Result Elements. 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called by: 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCopyTreeInternal() (transform.c) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltShallowCopyElem() (transform.c) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * REVISIT: This function won't be used in the refactored code. 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: a new xmlNsPtr, or NULL in case of error. 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNsPtr 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr cur) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ret = NULL, tmp; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr p = NULL,q; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == NULL) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->type != XML_NAMESPACE_DECL) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * One can add namespaces only on element nodes 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = NULL; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->type != XML_NAMESPACE_DECL) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Avoid duplicating namespace declarations in the tree if 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a matching declaration is in scope. 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node != NULL) { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->ns != NULL) && 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->ns->prefix, cur->prefix)) && 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->ns->href, cur->href))) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlSearchNs(node->doc, node, cur->prefix); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XSLT_REFACTORED 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Namespace exclusion and ns-aliasing is performed at 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compilation-time in the refactored code. 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q = xmlNewNs(node, cur->href, cur->prefix); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p == NULL) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = p = q; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->next = q; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = q; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Remove this if the refactored code gets enabled. 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *URI; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO apply cascading */ 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->href); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI == UNDEFINED_DEFAULT_NS) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI != NULL) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q = xmlNewNs(node, URI, cur->prefix); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q = xmlNewNs(node, cur->href, cur->prefix); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p == NULL) { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = p = q; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->next = q; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = q; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCopyNamespace: 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a transformation context 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @elem: the target element node 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ns: the namespace node 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copies a namespace node (declaration). If @elem is not NULL, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then the new namespace will be declared on @elem. 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: a new xmlNsPtr, or NULL in case of an error. 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNsPtr 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr elem, xmlNsPtr ns) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * One can add namespaces only on element nodes 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE)) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlNewNs(NULL, ns->href, ns->prefix)); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlNewNs(elem, ns->href, ns->prefix)); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeNamespaceAliasHashes: 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory used by namespaces aliases 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->nsAliases != NULL) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style->nsAliases = NULL; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 852