VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libxslt/documents.c@ 24345

Last change on this file since 24345 was 7296, checked in by vboxsync, 17 years ago

Added libxslt-1.1.22 sources.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 10.4 KB
Line 
1/*
2 * documents.c: Implementation of the documents handling
3 *
4 * See Copyright for the status of this software.
5 *
6 * [email protected]
7 */
8
9#define IN_LIBXSLT
10#include "libxslt.h"
11
12#include <string.h>
13
14#include <libxml/xmlmemory.h>
15#include <libxml/tree.h>
16#include <libxml/hash.h>
17#include <libxml/parser.h>
18#include <libxml/parserInternals.h>
19#include "xslt.h"
20#include "xsltInternals.h"
21#include "xsltutils.h"
22#include "documents.h"
23#include "transform.h"
24#include "imports.h"
25#include "keys.h"
26#include "security.h"
27
28#ifdef LIBXML_XINCLUDE_ENABLED
29#include <libxml/xinclude.h>
30#endif
31
32#define WITH_XSLT_DEBUG_DOCUMENTS
33
34#ifdef WITH_XSLT_DEBUG
35#define WITH_XSLT_DEBUG_DOCUMENTS
36#endif
37
38/************************************************************************
39 * *
40 * Hooks for the document loader *
41 * *
42 ************************************************************************/
43
44/**
45 * xsltDocDefaultLoaderFunc:
46 * @URI: the URI of the document to load
47 * @dict: the dictionary to use when parsing that document
48 * @options: parsing options, a set of xmlParserOption
49 * @ctxt: the context, either a stylesheet or a transformation context
50 * @type: the xsltLoadType indicating the kind of loading required
51 *
52 * Default function to load document not provided by the compilation or
53 * transformation API themselve, for example when an xsl:import,
54 * xsl:include is found at compilation time or when a document()
55 * call is made at runtime.
56 *
57 * Returns the pointer to the document (which will be modified and
58 * freed by the engine later), or NULL in case of error.
59 */
60static xmlDocPtr
61xsltDocDefaultLoaderFunc(const xmlChar * URI, xmlDictPtr dict, int options,
62 void *ctxt ATTRIBUTE_UNUSED,
63 xsltLoadType type ATTRIBUTE_UNUSED)
64{
65 xmlParserCtxtPtr pctxt;
66 xmlParserInputPtr inputStream;
67 xmlDocPtr doc;
68
69 pctxt = xmlNewParserCtxt();
70 if (pctxt == NULL)
71 return(NULL);
72 if ((dict != NULL) && (pctxt->dict != NULL)) {
73 xmlDictFree(pctxt->dict);
74 pctxt->dict = NULL;
75 }
76 if (dict != NULL) {
77 pctxt->dict = dict;
78 xmlDictReference(pctxt->dict);
79#ifdef WITH_XSLT_DEBUG
80 xsltGenericDebug(xsltGenericDebugContext,
81 "Reusing dictionary for document\n");
82#endif
83 }
84 xmlCtxtUseOptions(pctxt, options);
85 inputStream = xmlLoadExternalEntity((const char *) URI, NULL, pctxt);
86 if (inputStream == NULL) {
87 xmlFreeParserCtxt(pctxt);
88 return(NULL);
89 }
90 inputPush(pctxt, inputStream);
91 if (pctxt->directory == NULL)
92 pctxt->directory = xmlParserGetDirectory((const char *) URI);
93
94 xmlParseDocument(pctxt);
95
96 if (pctxt->wellFormed) {
97 doc = pctxt->myDoc;
98 }
99 else {
100 doc = NULL;
101 xmlFreeDoc(pctxt->myDoc);
102 pctxt->myDoc = NULL;
103 }
104 xmlFreeParserCtxt(pctxt);
105
106 return(doc);
107}
108
109
110xsltDocLoaderFunc xsltDocDefaultLoader = xsltDocDefaultLoaderFunc;
111
112/**
113 * xsltSetLoaderFunc:
114 * @f: the new function to handle document loading.
115 *
116 * Set the new function to load document, if NULL it resets it to the
117 * default function.
118 */
119
120void
121xsltSetLoaderFunc(xsltDocLoaderFunc f) {
122 if (f == NULL)
123 xsltDocDefaultLoader = xsltDocDefaultLoaderFunc;
124 else
125 xsltDocDefaultLoader = f;
126}
127
128/************************************************************************
129 * *
130 * Module interfaces *
131 * *
132 ************************************************************************/
133
134/**
135 * xsltNewDocument:
136 * @ctxt: an XSLT transformation context (or NULL)
137 * @doc: a parsed XML document
138 *
139 * Register a new document, apply key computations
140 *
141 * Returns a handler to the document
142 */
143xsltDocumentPtr
144xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
145 xsltDocumentPtr cur;
146
147 cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
148 if (cur == NULL) {
149 xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
150 "xsltNewDocument : malloc failed\n");
151 return(NULL);
152 }
153 memset(cur, 0, sizeof(xsltDocument));
154 cur->doc = doc;
155 if (ctxt != NULL) {
156 if (! XSLT_IS_RES_TREE_FRAG(doc)) {
157 cur->next = ctxt->docList;
158 ctxt->docList = cur;
159 }
160#ifdef XSLT_REFACTORED_KEYCOMP
161 /*
162 * A key with a specific name for a specific document
163 * will only be computed if there's a call to the key()
164 * function using that specific name for that specific
165 * document. I.e. computation of keys will be done in
166 * xsltGetKey() (keys.c) on an on-demand basis.
167 */
168#else
169 /*
170 * Old behaviour.
171 */
172 xsltInitCtxtKeys(ctxt, cur);
173#endif
174 }
175 return(cur);
176}
177
178/**
179 * xsltNewStyleDocument:
180 * @style: an XSLT style sheet
181 * @doc: a parsed XML document
182 *
183 * Register a new document, apply key computations
184 *
185 * Returns a handler to the document
186 */
187xsltDocumentPtr
188xsltNewStyleDocument(xsltStylesheetPtr style, xmlDocPtr doc) {
189 xsltDocumentPtr cur;
190
191 cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
192 if (cur == NULL) {
193 xsltTransformError(NULL, style, (xmlNodePtr) doc,
194 "xsltNewStyleDocument : malloc failed\n");
195 return(NULL);
196 }
197 memset(cur, 0, sizeof(xsltDocument));
198 cur->doc = doc;
199 if (style != NULL) {
200 cur->next = style->docList;
201 style->docList = cur;
202 }
203 return(cur);
204}
205
206/**
207 * xsltFreeStyleDocuments:
208 * @style: an XSLT stylesheet (representing a stylesheet-level)
209 *
210 * Frees the node-trees (and xsltDocument structures) of all
211 * stylesheet-modules of the stylesheet-level represented by
212 * the given @style.
213 */
214void
215xsltFreeStyleDocuments(xsltStylesheetPtr style) {
216 xsltDocumentPtr doc, cur;
217#ifdef XSLT_REFACTORED_XSLT_NSCOMP
218 xsltNsMapPtr nsMap;
219#endif
220
221 if (style == NULL)
222 return;
223
224#ifdef XSLT_REFACTORED_XSLT_NSCOMP
225 if (XSLT_HAS_INTERNAL_NSMAP(style))
226 nsMap = XSLT_GET_INTERNAL_NSMAP(style);
227 else
228 nsMap = NULL;
229#endif
230
231 cur = style->docList;
232 while (cur != NULL) {
233 doc = cur;
234 cur = cur->next;
235#ifdef XSLT_REFACTORED_XSLT_NSCOMP
236 /*
237 * Restore all changed namespace URIs of ns-decls.
238 */
239 if (nsMap)
240 xsltRestoreDocumentNamespaces(nsMap, doc->doc);
241#endif
242 xsltFreeDocumentKeys(doc);
243 if (!doc->main)
244 xmlFreeDoc(doc->doc);
245 xmlFree(doc);
246 }
247}
248
249/**
250 * xsltFreeDocuments:
251 * @ctxt: an XSLT transformation context
252 *
253 * Free up all the space used by the loaded documents
254 */
255void
256xsltFreeDocuments(xsltTransformContextPtr ctxt) {
257 xsltDocumentPtr doc, cur;
258
259 cur = ctxt->docList;
260 while (cur != NULL) {
261 doc = cur;
262 cur = cur->next;
263 xsltFreeDocumentKeys(doc);
264 if (!doc->main)
265 xmlFreeDoc(doc->doc);
266 xmlFree(doc);
267 }
268 cur = ctxt->styleList;
269 while (cur != NULL) {
270 doc = cur;
271 cur = cur->next;
272 xsltFreeDocumentKeys(doc);
273 if (!doc->main)
274 xmlFreeDoc(doc->doc);
275 xmlFree(doc);
276 }
277}
278
279/**
280 * xsltLoadDocument:
281 * @ctxt: an XSLT transformation context
282 * @URI: the computed URI of the document
283 *
284 * Try to load a document (not a stylesheet)
285 * within the XSLT transformation context
286 *
287 * Returns the new xsltDocumentPtr or NULL in case of error
288 */
289xsltDocumentPtr
290xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
291 xsltDocumentPtr ret;
292 xmlDocPtr doc;
293
294 if ((ctxt == NULL) || (URI == NULL))
295 return(NULL);
296
297 /*
298 * Security framework check
299 */
300 if (ctxt->sec != NULL) {
301 int res;
302
303 res = xsltCheckRead(ctxt->sec, ctxt, URI);
304 if (res == 0) {
305 xsltTransformError(ctxt, NULL, NULL,
306 "xsltLoadDocument: read rights for %s denied\n",
307 URI);
308 return(NULL);
309 }
310 }
311
312 /*
313 * Walk the context list to find the document if preparsed
314 */
315 ret = ctxt->docList;
316 while (ret != NULL) {
317 if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
318 (xmlStrEqual(ret->doc->URL, URI)))
319 return(ret);
320 ret = ret->next;
321 }
322
323 doc = xsltDocDefaultLoader(URI, ctxt->dict, ctxt->parserOptions,
324 (void *) ctxt, XSLT_LOAD_DOCUMENT);
325
326 if (doc == NULL)
327 return(NULL);
328
329 if (ctxt->xinclude != 0) {
330#ifdef LIBXML_XINCLUDE_ENABLED
331#if LIBXML_VERSION >= 20603
332 xmlXIncludeProcessFlags(doc, ctxt->parserOptions);
333#else
334 xmlXIncludeProcess(doc);
335#endif
336#else
337 xsltTransformError(ctxt, NULL, NULL,
338 "xsltLoadDocument(%s) : XInclude processing not compiled in\n",
339 URI);
340#endif
341 }
342 /*
343 * Apply white-space stripping if asked for
344 */
345 if (xsltNeedElemSpaceHandling(ctxt))
346 xsltApplyStripSpaces(ctxt, xmlDocGetRootElement(doc));
347 if (ctxt->debugStatus == XSLT_DEBUG_NONE)
348 xmlXPathOrderDocElems(doc);
349
350 ret = xsltNewDocument(ctxt, doc);
351 return(ret);
352}
353
354/**
355 * xsltLoadStyleDocument:
356 * @style: an XSLT style sheet
357 * @URI: the computed URI of the document
358 *
359 * Try to load a stylesheet document within the XSLT transformation context
360 *
361 * Returns the new xsltDocumentPtr or NULL in case of error
362 */
363xsltDocumentPtr
364xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
365 xsltDocumentPtr ret;
366 xmlDocPtr doc;
367 xsltSecurityPrefsPtr sec;
368
369 if ((style == NULL) || (URI == NULL))
370 return(NULL);
371
372 /*
373 * Security framework check
374 */
375 sec = xsltGetDefaultSecurityPrefs();
376 if (sec != NULL) {
377 int res;
378
379 res = xsltCheckRead(sec, NULL, URI);
380 if (res == 0) {
381 xsltTransformError(NULL, NULL, NULL,
382 "xsltLoadStyleDocument: read rights for %s denied\n",
383 URI);
384 return(NULL);
385 }
386 }
387
388 /*
389 * Walk the context list to find the document if preparsed
390 */
391 ret = style->docList;
392 while (ret != NULL) {
393 if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
394 (xmlStrEqual(ret->doc->URL, URI)))
395 return(ret);
396 ret = ret->next;
397 }
398
399 doc = xsltDocDefaultLoader(URI, style->dict, XSLT_PARSE_OPTIONS,
400 (void *) style, XSLT_LOAD_STYLESHEET);
401 if (doc == NULL)
402 return(NULL);
403
404 ret = xsltNewStyleDocument(style, doc);
405 return(ret);
406}
407
408/**
409 * xsltFindDocument:
410 * @ctxt: an XSLT transformation context
411 * @doc: a parsed XML document
412 *
413 * Try to find a document within the XSLT transformation context.
414 * This will not find document infos for temporary
415 * Result Tree Fragments.
416 *
417 * Returns the desired xsltDocumentPtr or NULL in case of error
418 */
419xsltDocumentPtr
420xsltFindDocument (xsltTransformContextPtr ctxt, xmlDocPtr doc) {
421 xsltDocumentPtr ret;
422
423 if ((ctxt == NULL) || (doc == NULL))
424 return(NULL);
425
426 /*
427 * Walk the context list to find the document
428 */
429 ret = ctxt->docList;
430 while (ret != NULL) {
431 if (ret->doc == doc)
432 return(ret);
433 ret = ret->next;
434 }
435 if (doc == ctxt->style->doc)
436 return(ctxt->document);
437 return(NULL);
438}
439
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette