86771af68fc86cb256e053f07d2fca7ecccfe996
[platform/upstream/libxslt.git] / libxslt / documents.c
1 /*
2  * documents.c: Implementation of the documents handling
3  *
4  * See Copyright for the status of this software.
5  *
6  * daniel@veillard.com
7  */
8
9 #include "libxslt.h"
10
11 #include <string.h>
12
13 #include <libxml/xmlmemory.h>
14 #include <libxml/tree.h>
15 #include <libxml/hash.h>
16 #include "xslt.h"
17 #include "xsltInternals.h"
18 #include "xsltutils.h"
19 #include "documents.h"
20 #include "transform.h"
21 #include "imports.h"
22 #include "keys.h"
23
24 #ifdef LIBXML_XINCLUDE_ENABLED
25 #include <libxml/xinclude.h>
26 #endif
27
28 #ifdef WITH_XSLT_DEBUG
29 #define WITH_XSLT_DEBUG_DOCUMENTS
30 #endif
31
32 /************************************************************************
33  *                                                                      *
34  *                      Module interfaces                               *
35  *                                                                      *
36  ************************************************************************/
37
38 /**
39  * xsltNewDocument:
40  * @ctxt: an XSLT transformation context (or NULL)
41  * @doc:  a parsed XML document
42  *
43  * Register a new document, apply key computations
44  */
45 xsltDocumentPtr 
46 xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
47     xsltDocumentPtr cur;
48
49     cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
50     if (cur == NULL) {
51         xsltPrintErrorContext(ctxt, NULL, (xmlNodePtr) doc);
52         xsltGenericError(xsltGenericErrorContext,
53                 "xsltNewDocument : malloc failed\n");
54         return(NULL);
55     }
56     memset(cur, 0, sizeof(xsltDocument));
57     cur->doc = doc;
58     if (ctxt != NULL) {
59         cur->next = ctxt->docList;
60         ctxt->docList = cur;
61         xsltInitCtxtKeys(ctxt, cur);
62     }
63     return(cur);
64 }
65
66 /**
67  * xsltNewStyleDocument:
68  * @style: an XSLT style sheet
69  * @doc:  a parsed XML document
70  *
71  * Register a new document, apply key computations
72  */
73 xsltDocumentPtr 
74 xsltNewStyleDocument(xsltStylesheetPtr style, xmlDocPtr doc) {
75     xsltDocumentPtr cur;
76
77     cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
78     if (cur == NULL) {
79         xsltPrintErrorContext(NULL, style, (xmlNodePtr) doc);
80         xsltGenericError(xsltGenericErrorContext,
81                 "xsltNewStyleDocument : malloc failed\n");
82         return(NULL);
83     }
84     memset(cur, 0, sizeof(xsltDocument));
85     cur->doc = doc;
86     if (style != NULL) {
87         cur->next = style->docList;
88         style->docList = cur;
89     }
90     return(cur);
91 }
92
93 /**
94  * xsltFreeStyleDocuments:
95  * @style: an XSLT style sheet
96  *
97  * Free up all the space used by the loaded documents
98  */
99 void    
100 xsltFreeStyleDocuments(xsltStylesheetPtr style) {
101     xsltDocumentPtr doc, cur;
102
103     cur = style->docList;
104     while (cur != NULL) {
105         doc = cur;
106         cur = cur->next;
107         xsltFreeDocumentKeys(doc);
108         if (!doc->main)
109             xmlFreeDoc(doc->doc);
110         xmlFree(doc);
111     }
112 }
113
114 /**
115  * xsltFreeDocuments:
116  * @ctxt: an XSLT transformation context
117  *
118  * Free up all the space used by the loaded documents
119  */
120 void    
121 xsltFreeDocuments(xsltTransformContextPtr ctxt) {
122     xsltDocumentPtr doc, cur;
123
124     cur = ctxt->docList;
125     while (cur != NULL) {
126         doc = cur;
127         cur = cur->next;
128         xsltFreeDocumentKeys(doc);
129         if (!doc->main)
130             xmlFreeDoc(doc->doc);
131         xmlFree(doc);
132     }
133 }
134
135
136 /**
137  * xsltLoadDocument:
138  * @ctxt: an XSLT transformation context
139  * @URI:  the computed URI of the document
140  *
141  * Try to load a document within the XSLT transformation context
142  *
143  * Returns the new xsltDocumentPtr or NULL in case of error
144  */
145 xsltDocumentPtr 
146 xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
147     xsltDocumentPtr ret;
148     xmlDocPtr doc;
149
150     if ((ctxt == NULL) || (URI == NULL))
151         return(NULL);
152
153     /*
154      * Walk the context list to find the document if preparsed
155      */
156     ret = ctxt->docList;
157     while (ret != NULL) {
158         if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
159             (xmlStrEqual(ret->doc->URL, URI)))
160             return(ret);
161         ret = ret->next;
162     }
163
164     doc = xmlParseFile((const char *) URI);
165     if (doc == NULL)
166         return(NULL);
167
168     if (ctxt->xinclude != 0) {
169 #ifdef LIBXML_XINCLUDE_ENABLED
170         xmlXIncludeProcess(doc);
171 #else
172         xsltPrintErrorContext(ctxt, NULL, NULL);
173         xsltGenericError(xsltGenericErrorContext,
174             "xsltLoadDocument(%s) : XInclude processing not compiled in\n",
175                          URI);
176 #endif
177     }
178     /*
179      * Apply white-space stripping if asked for
180      */
181     if (xsltNeedElemSpaceHandling(ctxt))
182         xsltApplyStripSpaces(ctxt, xmlDocGetRootElement(doc));
183
184     ret = xsltNewDocument(ctxt, doc);
185     return(ret);
186 }
187
188 /**
189  * xsltLoadStyleDocument:
190  * @style: an XSLT style sheet
191  * @URI:  the computed URI of the document
192  *
193  * Try to load a document within the XSLT transformation context
194  *
195  * Returns the new xsltDocumentPtr or NULL in case of error
196  */
197 xsltDocumentPtr 
198 xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
199     xsltDocumentPtr ret;
200     xmlDocPtr doc;
201
202     if ((style == NULL) || (URI == NULL))
203         return(NULL);
204
205     /*
206      * Walk the context list to find the document if preparsed
207      */
208     ret = style->docList;
209     while (ret != NULL) {
210         if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
211             (xmlStrEqual(ret->doc->URL, URI)))
212             return(ret);
213         ret = ret->next;
214     }
215
216     doc = xmlParseFile((const char *) URI);
217     if (doc == NULL)
218         return(NULL);
219
220     ret = xsltNewStyleDocument(style, doc);
221     return(ret);
222 }
223
224 /**
225  * xsltFindDocument:
226  * @ctxt: an XSLT transformation context
227  * @@doc: a parsed XML document
228  *
229  * Try to find a document within the XSLT transformation context
230  *
231  * Returns the desired xsltDocumentPtr or NULL in case of error
232  */
233 xsltDocumentPtr
234 xsltFindDocument (xsltTransformContextPtr ctxt, xmlDocPtr doc) {
235     xsltDocumentPtr ret;
236
237     if ((ctxt == NULL) || (doc == NULL))
238         return(NULL);
239
240     /*
241      * Walk the context list to find the document
242      */
243     ret = ctxt->docList;
244     while (ret != NULL) {
245         if (ret->doc == doc)
246             return(ret);
247         ret = ret->next;
248     }
249     if (doc == ctxt->style->doc)
250         return(ctxt->document);
251     return(NULL);
252 }
253