diff --git a/libxslt/functions.c b/libxslt/functions.c
index 6448bde..6cd90d1 100644
--- a/libxslt/functions.c
+++ b/libxslt/functions.c
@@ -665,6 +665,9 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
     xmlXPathObjectPtr obj = NULL;
     long val;
     xmlChar str[30];
+    xsltTransformContextPtr tctxt;
+
+    tctxt = xsltXPathGetTransformContext(ctxt);
 
     if (nargs == 0) {
 	cur = ctxt->context->node;
@@ -707,6 +710,26 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
     } else {
       sprintf((char *)str, "idm%ld", -val);
     }
+    if (tctxt->deterministicGenerateId) {
+      unsigned long* id;
+      if (tctxt->deterministicIds == NULL) {
+	tctxt->deterministicIds = xmlHashCreate(1024);
+	if (tctxt->deterministicIds == NULL) {
+	  xsltTransformError(tctxt, NULL, NULL, "generate-id() : malloc failed");
+	}
+      }
+
+      id = (unsigned long*) xmlHashLookup(tctxt->deterministicIds, str);
+      if (id == NULL) {
+	id = (unsigned long*) xmlMalloc(sizeof(unsigned long));
+	if (id == NULL) {
+	  xsltTransformError(tctxt, NULL, NULL, "generate-id() : malloc failed");
+	}
+	*id = tctxt->nextDeterministicId++;
+	xmlHashAddEntry(tctxt->deterministicIds, str, id);
+      }
+      sprintf((char *)str, "idd%lu", *id);
+    }
     valuePush(ctxt, xmlXPathNewString(str));
 }
 
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 24f9eb2..3773a6a 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -701,6 +701,10 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
     cur->xinclude = xsltGetXIncludeDefault();
     cur->keyInitLevel = 0;
 
+    cur->deterministicGenerateId = 0;
+    cur->nextDeterministicId = 0;
+    cur->deterministicIds = NULL;
+
     return(cur);
 
 internal_err:
@@ -756,6 +760,8 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
     xsltGenericDebug(xsltGenericDebugContext,
                      "freeing transformation dictionary\n");
 #endif
+    if (ctxt->deterministicIds != NULL)
+	xmlHashFree(ctxt->deterministicIds, (xmlHashDeallocator)xmlFree);
     memset(ctxt, -1, sizeof(xsltTransformContext));
     xmlFree(ctxt);
 }
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 95e8fe6..c2d61be 100644
--- a/libxslt/xsltInternals.h
+++ b/libxslt/xsltInternals.h
@@ -1786,6 +1786,10 @@ struct _xsltTransformContext {
     int funcLevel;      /* Needed to catch recursive functions issues */
     int maxTemplateDepth;
     int maxTemplateVars;
+
+    int deterministicGenerateId; /* Whether to use deterministic generate-id() */
+    unsigned long nextDeterministicId;
+    xmlHashTablePtr deterministicIds;
 };
 
 /**
diff --git a/xsltproc/xsltproc.c b/xsltproc/xsltproc.c
index 66d8cbb..df41d30 100644
--- a/xsltproc/xsltproc.c
+++ b/xsltproc/xsltproc.c
@@ -88,6 +88,7 @@ static int load_trace = 0;
 static int xinclude = 0;
 static int xincludestyle = 0;
 #endif
+static int deterministic = 0;
 static int profile = 0;
 
 #define MAX_PARAMETERS 64
@@ -404,6 +405,8 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
 	if (xinclude)
 	    ctxt->xinclude = 1;
 #endif
+	if (deterministic)
+	    ctxt->deterministicGenerateId = 1;
 	if (profile) {
 	    res = xsltApplyStylesheetUser(cur, doc, params, NULL,
 		                          stderr, ctxt);
@@ -475,6 +478,8 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
 #endif
 	ctxt->maxTemplateDepth = xsltMaxDepth;
 	ctxt->maxTemplateVars = xsltMaxVars;
+	if (deterministic)
+	    ctxt->deterministicGenerateId = 1;
 
 	if (profile) {
 	    ret = xsltRunStylesheetUser(cur, doc, params, output,
@@ -539,6 +544,7 @@ static void usage(const char *name) {
     printf("\t--xincludestyle : do XInclude processing on stylesheets\n");
 #endif
     printf("\t--load-trace : print trace of all external entites loaded\n");
+    printf("\t--deterministic : make the output of generate-id() deterministic\n");
     printf("\t--profile or --norman : dump profiling informations \n");
     printf("\nProject libxslt home page: http://xmlsoft.org/XSLT/\n");
     printf("To report bugs and get help: http://xmlsoft.org/XSLT/bugs.html\n");
@@ -629,6 +635,9 @@ main(int argc, char **argv)
         } else if ((!strcmp(argv[i], "-timing")) ||
                    (!strcmp(argv[i], "--timing"))) {
             timing++;
+        } else if ((!strcmp(argv[i], "-deterministic")) ||
+                   (!strcmp(argv[i], "--deterministic"))) {
+            deterministic++;
         } else if ((!strcmp(argv[i], "-profile")) ||
                    (!strcmp(argv[i], "--profile"))) {
             profile++;
