17d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/*
27d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * imports.c: Implementation of the XSLT imports
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
367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlmemory.h>
377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/tree.h>
387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/hash.h>
397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlerror.h>
407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/uri.h>
417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xslt.h"
427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltInternals.h"
437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltutils.h"
447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "preproc.h"
457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "imports.h"
467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "documents.h"
477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "security.h"
487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "pattern.h"
497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/************************************************************************
527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *									*
537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *			Module interfaces				*
547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *									*
557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ************************************************************************/
567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFixImportedCompSteps:
587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @master: the "master" stylesheet
597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @style: the stylesheet being imported by the master
607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * normalize the comp steps for the stylesheet being imported
627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * by the master, together with any imports within that.
637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangstatic void xsltFixImportedCompSteps(xsltStylesheetPtr master,
667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			xsltStylesheetPtr style) {
677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr res;
687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlHashScan(style->templatesHash,
697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	            (xmlHashScanner) xsltNormalizeCompSteps, master);
707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    master->extrasNr += style->extrasNr;
717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    for (res = style->imports; res != NULL; res = res->next) {
727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        xsltFixImportedCompSteps(master, res);
737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltParseStylesheetImport:
787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @style:  the XSLT stylesheet
797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the import element
807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * parse an XSLT stylesheet import element
827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns 0 in case of success -1 in case of failure.
847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangint
877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    int ret = -1;
897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlDocPtr import = NULL;
907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *base = NULL;
917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *uriRef = NULL;
927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *URI = NULL;
937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr res;
947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltSecurityPrefsPtr sec;
957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((cur == NULL) || (style == NULL))
977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return (ret);
987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
1007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (uriRef == NULL) {
1017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
1027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:import : missing href attribute\n");
1037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
1047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    base = xmlNodeGetBase(style->doc, cur);
1077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    URI = xmlBuildURI(uriRef, base);
1087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (URI == NULL) {
1097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
1107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:import : invalid URI reference %s\n", uriRef);
1117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
1127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    res = style;
1157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (res != NULL) {
1167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (res->doc == NULL)
1177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    break;
1187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (xmlStrEqual(res->doc->URL, URI)) {
1197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, cur,
1207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	       "xsl:import : recursion detected on imported URL %s\n", URI);
1217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
1227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	res = res->parent;
1247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
1277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * Security framework check
1287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
1297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    sec = xsltGetDefaultSecurityPrefs();
1307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (sec != NULL) {
1317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	int secres;
1327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	secres = xsltCheckRead(sec, NULL, URI);
1347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (secres == 0) {
1357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, NULL, NULL,
1367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		 "xsl:import: read rights for %s denied\n",
1377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang			     URI);
1387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
1397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    import = xsltDocDefaultLoader(URI, style->dict, XSLT_PARSE_OPTIONS,
1437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang                                  (void *) style, XSLT_LOAD_STYLESHEET);
1447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (import == NULL) {
1457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
1467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:import : unable to load %s\n", URI);
1477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
1487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
1497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    res = xsltParseStylesheetImportedDoc(import, style);
1517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (res != NULL) {
1527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	res->next = style->imports;
1537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style->imports = res;
1547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (style->parent == NULL) {
1557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltFixImportedCompSteps(style, res);
1567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ret = 0;
1587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
1597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFreeDoc(import);
1607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
1617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangerror:
1637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (uriRef != NULL)
1647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(uriRef);
1657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (base != NULL)
1667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(base);
1677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (URI != NULL)
1687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(URI);
1697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return (ret);
1717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
1727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
1747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltParseStylesheetInclude:
1757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @style:  the XSLT stylesheet
1767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the include node
1777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
1787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * parse an XSLT stylesheet include element
1797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
1807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns 0 in case of success -1 in case of failure
1817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
1827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangint
1847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
1857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    int ret = -1;
1867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlDocPtr oldDoc;
1877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *base = NULL;
1887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *uriRef = NULL;
1897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xmlChar *URI = NULL;
1907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr result;
1917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltDocumentPtr include;
1927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltDocumentPtr docptr;
1937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    int oldNopreproc;
1947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((cur == NULL) || (style == NULL))
1967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return (ret);
1977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
1987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
1997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (uriRef == NULL) {
2007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
2017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:include : missing href attribute\n");
2027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
2037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    base = xmlNodeGetBase(style->doc, cur);
2067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    URI = xmlBuildURI(uriRef, base);
2077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (URI == NULL) {
2087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
2097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:include : invalid URI reference %s\n", uriRef);
2107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
2117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
2147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * in order to detect recursion, we check all previously included
2157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     * stylesheets.
2167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang     */
2177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    docptr = style->includes;
2187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (docptr != NULL) {
2197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang        if (xmlStrEqual(docptr->doc->URL, URI)) {
2207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    xsltTransformError(NULL, style, cur,
2217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	        "xsl:include : recursion detected on included URL %s\n", URI);
2227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    goto error;
2237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
2247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	docptr = docptr->includes;
2257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    include = xsltLoadStyleDocument(style, URI);
2287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (include == NULL) {
2297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
2307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "xsl:include : unable to load %s\n", URI);
2317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
2327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef XSLT_REFACTORED
2347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (IS_XSLT_ELEM_FAST(cur) && (cur->psvi != NULL)) {
2357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	((xsltStyleItemIncludePtr) cur->psvi)->include = include;
2367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } else {
2377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xsltTransformError(NULL, style, cur,
2387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "Internal error: (xsltParseStylesheetInclude) "
2397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    "The xsl:include element was not compiled.\n", URI);
2407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style->errors++;
2417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif
2437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    oldDoc = style->doc;
2447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->doc = include->doc;
2457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /* chain to stylesheet for recursion checking */
2467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    include->includes = style->includes;
2477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->includes = include;
2487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    oldNopreproc = style->nopreproc;
2497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->nopreproc = include->preproc;
2507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    /*
2517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    * TODO: This will change some values of the
2527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  including stylesheet with every included module
2537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  (e.g. excluded-result-prefixes)
2547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    *  We need to strictly seperate such stylesheet-owned values.
2557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    */
2567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    result = xsltParseStylesheetProcess(style, include->doc);
2577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->nopreproc = oldNopreproc;
2587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    include->preproc = 1;
2597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->includes = include->includes;
2607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style->doc = oldDoc;
2617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (result == NULL) {
2627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	ret = -1;
2637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	goto error;
2647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
2657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    ret = 0;
2667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangerror:
2687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (uriRef != NULL)
2697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(uriRef);
2707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (base != NULL)
2717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(base);
2727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (URI != NULL)
2737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	xmlFree(URI);
2747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return (ret);
2767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
2777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
2797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltNextImport:
2807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @cur:  the current XSLT stylesheet
2817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
2827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Find the next stylesheet in import precedence.
2837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
2847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns the next stylesheet or NULL if it was the last one
2857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
2867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
2877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltStylesheetPtr
2887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltNextImport(xsltStylesheetPtr cur) {
2897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cur == NULL)
2907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
2917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cur->imports != NULL)
2927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(cur->imports);
2937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (cur->next != NULL)
2947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(cur->next) ;
2957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    do {
2967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	cur = cur->parent;
2977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (cur == NULL) break;
2987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (cur->next != NULL) return(cur->next);
2997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    } while (cur != NULL);
3007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(cur);
3017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
3027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
3047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltNeedElemSpaceHandling:
3057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  an XSLT transformation context
3067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Checks whether that stylesheet requires white-space stripping
3087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns 1 if space should be stripped, 0 if not
3107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
3117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangint
3137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) {
3147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr style;
3157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if (ctxt == NULL)
3177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(0);
3187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style = ctxt->style;
3197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (style != NULL) {
3207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (style->stripSpaces != NULL)
3217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(1);
3227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style = xsltNextImport(style);
3237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
3247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(0);
3257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
3267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
3287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFindElemSpaceHandling:
3297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  an XSLT transformation context
3307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @node:  an XML node
3317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Find strip-space or preserve-space informations for an element
3337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * respect the import precedence or the wildcards
3347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns 1 if space should be stripped, 0 if not, and 2 if everything
3367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *         should be CDTATA wrapped.
3377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
3387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangint
3407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
3417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr style;
3427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    const xmlChar *val;
3437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((ctxt == NULL) || (node == NULL))
3457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(0);
3467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style = ctxt->style;
3477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (style != NULL) {
3487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (node->ns != NULL) {
3497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    val = (const xmlChar *)
3507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	      xmlHashLookup2(style->stripSpaces, node->name, node->ns->href);
3517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang            if (val == NULL) {
3527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang                val = (const xmlChar *)
3537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang                    xmlHashLookup2(style->stripSpaces, BAD_CAST "*",
3547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang                                   node->ns->href);
3557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang            }
3567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	} else {
3577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    val = (const xmlChar *)
3587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		  xmlHashLookup2(style->stripSpaces, node->name, NULL);
3597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
3607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (val != NULL) {
3617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (xmlStrEqual(val, (xmlChar *) "strip"))
3627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(1);
3637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (xmlStrEqual(val, (xmlChar *) "preserve"))
3647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		return(0);
3657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
3667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (style->stripAll == 1)
3677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(1);
3687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	if (style->stripAll == -1)
3697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    return(0);
3707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style = xsltNextImport(style);
3727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
3737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(0);
3747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
3757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/**
3777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFindTemplate:
3787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt:  an XSLT transformation context
3797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @name: the template name
3807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nameURI: the template name URI
3817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Finds the named template, apply import precedence rule.
3837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * REVISIT TODO: We'll change the nameURI fields of
3847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  templates to be in the string dict, so if the
3857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  specified @nameURI is in the same dict, then use pointer
3867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  comparison. Check if this can be done in a sane way.
3877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  Maybe this function is not needed internally at
3887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  transformation-time if we hard-wire the called templates
3897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *  to the caller.
3907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang *
3917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns the xsltTemplatePtr or NULL if not found
3927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */
3937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltTemplatePtr
3947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
3957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	         const xmlChar *nameURI) {
3967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltTemplatePtr cur;
3977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    xsltStylesheetPtr style;
3987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
3997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    if ((ctxt == NULL) || (name == NULL))
4007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	return(NULL);
4017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    style = ctxt->style;
4027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    while (style != NULL) {
4037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	cur = style->templates;
4047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	while (cur != NULL) {
4057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    if (xmlStrEqual(name, cur->name)) {
4067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
4077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    ((nameURI != NULL) && (cur->nameURI != NULL) &&
4087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		     (xmlStrEqual(nameURI, cur->nameURI)))) {
4097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		    return(cur);
4107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang		}
4117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    }
4127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	    cur = cur->next;
4137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	}
4147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
4157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang	style = xsltNextImport(style);
4167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    }
4177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang    return(NULL);
4187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang}
4197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang
420