summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@redhat.com>2012-09-08 20:45:24 +0800
committerDaniel Veillard <veillard@redhat.com>2012-09-08 20:45:24 +0800
commitdc23a2a0dd4a9b23bea81eedf907a5b9e299ca7d (patch)
treefae2edd8d32089f3af5f9726b7976104213cd52e
parent343ef27424c708619c7089aca42c67576b62d360 (diff)
downloadlibxslt-dc23a2a0dd4a9b23bea81eedf907a5b9e299ca7d.tar.gz
libxslt-dc23a2a0dd4a9b23bea81eedf907a5b9e299ca7d.tar.bz2
libxslt-dc23a2a0dd4a9b23bea81eedf907a5b9e299ca7d.zip
Add an append mode to document output
It adds the append functionality to <redirect:write> element equivalent of ESXLT:document which opens the local file in append mode and remove the XML Declaration, allowing to potentially stack multiple chunks
-rw-r--r--libxslt/transform.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 4c6b2a58..3770c3d6 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -20,6 +20,7 @@
#include "libxslt.h"
#include <string.h>
+#include <stdio.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
@@ -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",