From dc23a2a0dd4a9b23bea81eedf907a5b9e299ca7d Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sat, 8 Sep 2012 20:45:24 +0800 Subject: [PATCH] Add an append mode to document output It adds the append functionality to element equivalent of ESXLT:document which opens the local file in append mode and remove the XML Declaration, allowing to potentially stack multiple chunks --- libxslt/transform.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/libxslt/transform.c b/libxslt/transform.c index 4c6b2a5..3770c3d 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -20,6 +20,7 @@ #include "libxslt.h" #include +#include #include #include @@ -3293,6 +3294,7 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node, const xmlChar *doctypeSystem; const xmlChar *version; const xmlChar *encoding; + int redirect_write_append = 0; if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) return; @@ -3708,10 +3710,38 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node, } /* - * Save the result + * Calls to redirect:write also take an optional attribute append. + * Attribute append="true|yes" which will attempt to simply append + * to an existing file instead of always opening a new file. The + * default behavior of always overwriting the file still happens + * if we do not specify append. + * Note that append use will forbid use of remote URI target. */ - ret = xsltSaveResultToFilename((const char *) filename, - res, style, 0); + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"append", + NULL); + if (prop != NULL) { + if (xmlStrEqual(prop, (const xmlChar *) "true") || + xmlStrEqual(prop, (const xmlChar *) "yes")) { + style->omitXmlDeclaration = 1; + redirect_write_append = 1; + } else + style->omitXmlDeclaration = 0; + xmlFree(prop); + } + + if (redirect_write_append) { + FILE *f; + + f = fopen((const char *) filename, "ab"); + if (f == NULL) { + ret = -1; + } else { + ret = xsltSaveResultToFile(f, res, style); + fclose(f); + } + } else { + ret = xsltSaveResultToFilename((const char *) filename, res, style, 0); + } if (ret < 0) { xsltTransformError(ctxt, NULL, inst, "xsltDocumentElem: unable to save to %s\n", -- 2.7.4