updated do not dump document for which there have been no generated
authorDaniel Veillard <veillard@src.gnome.org>
Thu, 5 Jul 2001 08:59:37 +0000 (08:59 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Thu, 5 Jul 2001 08:59:37 +0000 (08:59 +0000)
* FEATURES: updated
* libxslt/xsltutils.c: do not dump document for which there have
  been no generated content
* tests/multiple/result.xml tests/namespaces/extra2.out: fixed
  test output accordingly
* libxslt/transform.c libxslt/preproc.c: added xsl:fallback support
* tests/REC/Makefile.am tests/REC/test-15-1.*: xsl:fallback test
* tests/xmlspec/Makefile.am tests/docbook/Makefile.am: cleanups
Daniel

13 files changed:
ChangeLog
FEATURES
libxslt/preproc.c
libxslt/transform.c
libxslt/xsltutils.c
tests/REC/Makefile.am
tests/REC/test-15-1.out [new file with mode: 0644]
tests/REC/test-15-1.xml [new file with mode: 0644]
tests/REC/test-15-1.xsl [new file with mode: 0644]
tests/docbook/Makefile.am
tests/multiple/result.xml
tests/namespaces/extra2.out
tests/xmlspec/Makefile.am

index 79324c9..980ae81 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Thu Jul  5 10:44:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+       * FEATURES: updated
+       * libxslt/xsltutils.c: do not dump document for which there have
+         been no generated content
+       * tests/multiple/result.xml tests/namespaces/extra2.out: fixed
+         test output accordingly
+       * libxslt/transform.c libxslt/preproc.c: added xsl:fallback support
+       * tests/REC/Makefile.am tests/REC/test-15-1.*: xsl:fallback test
+       * tests/xmlspec/Makefile.am tests/docbook/Makefile.am: cleanups
+
 Wed Jul  4 15:15:50 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
        * libxslt/extension.[ch] libxslt/extra.[ch] libxslt/xsltInternals.h
index 5971446..5b13e4c 100644 (file)
--- a/FEATURES
+++ b/FEATURES
@@ -8,13 +8,13 @@ Stylesheet Constructs:
 
 YES                        xsl:stylesheet
 ?                              id = id 
-NO                             extension-element-prefixes = tokens 
+YES                            extension-element-prefixes = tokens 
 NO                             exclude-result-prefixes = tokens 
 YES                            version = number
 
 YES                        xsl:transform
 ?                              id = id 
-NO                             extension-element-prefixes = tokens 
+YES                            extension-element-prefixes = tokens 
 NO                             exclude-result-prefixes = tokens 
 YES                            version = number
 
@@ -181,7 +181,7 @@ YES                         pattern-separator = char
 YES                        xsl:message
 YES                            terminate = "yes" | "no"
 
-NO                         xsl:fallback
+YES                        xsl:fallback
 
 General:
 ========
@@ -197,9 +197,9 @@ YES                         match="processing-instruction()|comment()"
 YES                            Namespace
 YES                            Mode
 
-NO                         Extension Elements
+YES                        Extension Elements
 
-NO                         Extension Functions
+YES                        Extension Functions
 
 YES                        Attribute Value Templates
 
@@ -208,8 +208,8 @@ YES                     Result Tree Fragments
 Functions:
 ==========
 
-PARTIAL                            node-set document(object, node-set?)
-PARTIAL                            node-set key(string, object)
+YES                        node-set document(object, node-set?)
+YES                        node-set key(string, object)
 YES                        string format-number(number, string, string?)
 YES                        node-set current() 
 YES                        string unparsed-entity-uri(string)
index 9da6d95..599388a 100644 (file)
@@ -1278,6 +1278,9 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
        } else if (IS_XSLT_NAME(inst, "decimal-format")) {
            /* no computation needed */
            return;
+       } else if (IS_XSLT_NAME(inst, "fallback")) {
+           /* no computation needed */
+           return;
        } else if (IS_XSLT_NAME(inst, "document")) {
            xsltDocumentComp(style, inst);
        } else {
index c6b20b3..a51ac88 100644 (file)
@@ -865,7 +865,8 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
  */
 void
 xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
-                    xmlNodePtr list, int real) {
+                     xmlNodePtr list, int real)
+{
     xmlNodePtr cur = NULL, insert, copy = NULL;
     xmlNodePtr oldInsert;
     xmlNodePtr oldCurrent = NULL;
@@ -873,16 +874,16 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
     xmlAttrPtr attrs;
 
     if (list == NULL)
-       return;
+        return;
     CHECK_STOPPED;
 
     if (ctxt->templNr >= xsltMaxDepth) {
-       xsltGenericError(xsltGenericErrorContext,
-               "xsltApplyOneTemplate: loop found ???\n");
-       xsltGenericError(xsltGenericErrorContext,
-               "try increasing xsltMaxDepth (--maxdepth)\n");
-       xsltDebug(ctxt, node, list, NULL);
-       return;
+        xsltGenericError(xsltGenericErrorContext,
+                         "xsltApplyOneTemplate: loop found ???\n");
+        xsltGenericError(xsltGenericErrorContext,
+                         "try increasing xsltMaxDepth (--maxdepth)\n");
+        xsltDebug(ctxt, node, list, NULL);
+        return;
     }
 
     /*
@@ -891,8 +892,8 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
     oldInsert = insert = ctxt->insert;
     oldInst = ctxt->inst;
     if (real) {
-       oldCurrent = ctxt->node;
-       ctxt->node = node;
+        oldCurrent = ctxt->node;
+        ctxt->node = node;
     }
 
     /*
@@ -900,159 +901,189 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
      */
     cur = list;
     while (cur != NULL) {
-       ctxt->inst = cur;
-       /*
-        * test, we must have a valid insertion point
-        */
-       if (insert == NULL) {
+        ctxt->inst = cur;
+        /*
+         * test, we must have a valid insertion point
+         */
+        if (insert == NULL) {
 #ifdef WITH_XSLT_DEBUG_PROCESS
-           xsltGenericDebug(xsltGenericDebugContext,
-                "xsltApplyOneTemplate: insert == NULL !\n");
+            xsltGenericDebug(xsltGenericDebugContext,
+                             "xsltApplyOneTemplate: insert == NULL !\n");
 #endif
-           if (real)
-               ctxt->node = oldCurrent;
-           ctxt->inst = oldInst;
-           return;
-       }
+            if (real)
+                ctxt->node = oldCurrent;
+            ctxt->inst = oldInst;
+            return;
+        }
 
-       if (IS_XSLT_ELEM(cur)) {
-           /*
-            * This is an XSLT node
-            */
-           xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
-           if (info == NULL) {
-               if (IS_XSLT_NAME(cur, "message")) {
-                   xsltMessage(ctxt, node, cur);
-               } else {
-                   xsltGenericError(xsltGenericDebugContext,
-                    "xsltApplyOneTemplate: %s was not compiled\n",
-                                    cur->name);
-               }
-               goto skip_children;
-           }
-           
-           if (info->func != NULL) {
-               ctxt->insert = insert;
-               info->func(ctxt, node, cur, info);
-               ctxt->insert = oldInsert;
-               goto skip_children;
-           }
+        if (IS_XSLT_ELEM(cur)) {
+            /*
+             * This is an XSLT node
+             */
+            xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
+
+            if (info == NULL) {
+                if (IS_XSLT_NAME(cur, "message")) {
+                    xsltMessage(ctxt, node, cur);
+                } else {
+                    xsltGenericError(xsltGenericDebugContext,
+                                "xsltApplyOneTemplate: %s was not compiled\n",
+                                     cur->name);
+                }
+                goto skip_children;
+            }
 
-           if (IS_XSLT_NAME(cur, "variable")) {
-               xsltParseStylesheetVariable(ctxt, cur);
-           } else if (IS_XSLT_NAME(cur, "param")) {
-               xsltParseStylesheetParam(ctxt, cur);
-           } else if (IS_XSLT_NAME(cur, "message")) {
-               xsltMessage(ctxt, node, cur);
-           } else {
-               xsltGenericError(xsltGenericDebugContext,
-                    "xsltApplyOneTemplate: problem with xsl:%s\n",
-                                cur->name);
-           }
-           CHECK_STOPPED;
-           goto skip_children;
-       } else if ((cur->type == XML_TEXT_NODE) ||
-                  (cur->type == XML_CDATA_SECTION_NODE)) {
-           /*
-            * This text comes from the stylesheet
-            * For stylesheets, the set of whitespace-preserving
-            * element names consists of just xsl:text.
-            */
+            if (info->func != NULL) {
+                ctxt->insert = insert;
+                info->func(ctxt, node, cur, info);
+                ctxt->insert = oldInsert;
+                goto skip_children;
+            }
+
+            if (IS_XSLT_NAME(cur, "variable")) {
+                xsltParseStylesheetVariable(ctxt, cur);
+            } else if (IS_XSLT_NAME(cur, "param")) {
+                xsltParseStylesheetParam(ctxt, cur);
+            } else if (IS_XSLT_NAME(cur, "message")) {
+                xsltMessage(ctxt, node, cur);
+            } else {
+                xsltGenericError(xsltGenericDebugContext,
+                                 "xsltApplyOneTemplate: problem with xsl:%s\n",
+                                 cur->name);
+            }
+            CHECK_STOPPED;
+            goto skip_children;
+        } else if ((cur->type == XML_TEXT_NODE) ||
+                   (cur->type == XML_CDATA_SECTION_NODE)) {
+            /*
+             * This text comes from the stylesheet
+             * For stylesheets, the set of whitespace-preserving
+             * element names consists of just xsl:text.
+             */
 #ifdef WITH_XSLT_DEBUG_PROCESS
-           if (cur->type == XML_CDATA_SECTION_NODE)
-               xsltGenericDebug(xsltGenericDebugContext,
-                    "xsltApplyOneTemplate: copy CDATA text %s\n",
-                                cur->content);
-           else if (cur->name == xmlStringTextNoenc)
-               xsltGenericDebug(xsltGenericDebugContext,
-                    "xsltApplyOneTemplate: copy unescaped text %s\n",
-                                cur->content);
-           else
-               xsltGenericDebug(xsltGenericDebugContext,
-                    "xsltApplyOneTemplate: copy text %s\n", cur->content);
-#endif
-           copy = xmlNewText(cur->content);
-           if (copy != NULL) {
-               if ((cur->name == xmlStringTextNoenc) ||
-                   (cur->type == XML_CDATA_SECTION_NODE))
-                   copy->name = xmlStringTextNoenc;
-               xmlAddChild(insert, copy);
-           } else {
-               xsltGenericError(xsltGenericErrorContext,
-                       "xsltApplyOneTemplate: text copy failed\n");
-           }
-       } else if ((cur->type == XML_ELEMENT_NODE) && 
-                  (cur->ns != NULL) && (cur->_private != NULL)) {
-           xsltTransformFunction function;
-           /*
-            * Flagged as an extension element
-            */
-           function = (xsltTransformFunction)
-               xmlHashLookup2(ctxt->extElements, cur->name, cur->ns->href);
-           if (function == NULL) {
-               xsltGenericError(xsltGenericErrorContext,
-                       "xsltApplyOneTemplate: failed to find extension %s\n",
-                                cur->name);
-           } else {
+            if (cur->type == XML_CDATA_SECTION_NODE)
+                xsltGenericDebug(xsltGenericDebugContext,
+                                 "xsltApplyOneTemplate: copy CDATA text %s\n",
+                                 cur->content);
+            else if (cur->name == xmlStringTextNoenc)
+                xsltGenericDebug(xsltGenericDebugContext,
+                             "xsltApplyOneTemplate: copy unescaped text %s\n",
+                                 cur->content);
+            else
+                xsltGenericDebug(xsltGenericDebugContext,
+                                 "xsltApplyOneTemplate: copy text %s\n",
+                                 cur->content);
+#endif
+            copy = xmlNewText(cur->content);
+            if (copy != NULL) {
+                if ((cur->name == xmlStringTextNoenc) ||
+                    (cur->type == XML_CDATA_SECTION_NODE))
+                    copy->name = xmlStringTextNoenc;
+                xmlAddChild(insert, copy);
+            } else {
+                xsltGenericError(xsltGenericErrorContext,
+                                 "xsltApplyOneTemplate: text copy failed\n");
+            }
+        } else if ((cur->type == XML_ELEMENT_NODE) &&
+                   (cur->ns != NULL) && (cur->_private != NULL)) {
+            xsltTransformFunction function;
+
+            /*
+             * Flagged as an extension element
+             */
+            function = (xsltTransformFunction)
+                xmlHashLookup2(ctxt->extElements, cur->name,
+                               cur->ns->href);
+            if (function == NULL) {
+                xmlNodePtr child;
+                int found = 0;
+
 #ifdef WITH_XSLT_DEBUG_PROCESS
-               xsltGenericDebug(xsltGenericDebugContext,
-                "xsltApplyOneTemplate: extension construct %s\n", cur->name);
-#endif
+                xsltGenericDebug(xsltGenericDebugContext,
+                                "xsltApplyOneTemplate: unknown extension %s\n",
+                                 cur->name);
+#endif
+                /*
+                 * Search if there is fallbacks
+                 */
+                child = cur->children;
+                while (child != NULL) {
+                    if ((IS_XSLT_ELEM(child)) &&
+                        (IS_XSLT_NAME(child, "fallback"))) {
+                        found = 1;
+                        xsltApplyOneTemplate(ctxt, node, child->children,
+                                             1);
+                    }
+                    child = child->next;
+                }
 
-               ctxt->insert = insert;
-               function(ctxt, node, cur, cur->_private);
-               ctxt->insert = oldInsert;
-           }
-           goto skip_children;
-       } else if (cur->type == XML_ELEMENT_NODE) {
+                if (!found) {
+                    xsltGenericError(xsltGenericErrorContext,
+                         "xsltApplyOneTemplate: failed to find extension %s\n",
+                                     cur->name);
+                }
+            } else {
 #ifdef WITH_XSLT_DEBUG_PROCESS
-           xsltGenericDebug(xsltGenericDebugContext,
-                "xsltApplyOneTemplate: copy node %s\n", cur->name);
+                xsltGenericDebug(xsltGenericDebugContext,
+                              "xsltApplyOneTemplate: extension construct %s\n",
+                                 cur->name);
 #endif
-           copy = xsltCopyNode(ctxt, cur, insert);
-           /*
-            * all the attributes are directly inherited
-            */
-           if (cur->properties != NULL) {
-               attrs = xsltAttrListTemplateProcess(ctxt, copy,
-                                                   cur->properties);
-           }
-       }
 
-       /*
-        * Skip to next node, in document order.
-        */
-       if (cur->children != NULL) {
-           if (cur->children->type != XML_ENTITY_DECL) {
-               cur = cur->children;
-               if (copy != NULL)
-                   insert = copy;
-               continue;
-           }
-       }
-skip_children:
-       if (cur->next != NULL) {
-           cur = cur->next;
-           continue;
-       }
-       
-       do {
-           cur = cur->parent;
-           insert = insert->parent;
-           if (cur == NULL)
-               break;
-           if (cur == list->parent) {
-               cur = NULL;
-               break;
-           }
-           if (cur->next != NULL) {
-               cur = cur->next;
-               break;
-           }
-       } while (cur != NULL);
+                ctxt->insert = insert;
+                function(ctxt, node, cur, cur->_private);
+                ctxt->insert = oldInsert;
+            }
+            goto skip_children;
+        } else if (cur->type == XML_ELEMENT_NODE) {
+#ifdef WITH_XSLT_DEBUG_PROCESS
+            xsltGenericDebug(xsltGenericDebugContext,
+                             "xsltApplyOneTemplate: copy node %s\n",
+                             cur->name);
+#endif
+            copy = xsltCopyNode(ctxt, cur, insert);
+            /*
+             * all the attributes are directly inherited
+             */
+            if (cur->properties != NULL) {
+                attrs = xsltAttrListTemplateProcess(ctxt, copy,
+                                                    cur->properties);
+            }
+        }
+
+        /*
+         * Skip to next node, in document order.
+         */
+        if (cur->children != NULL) {
+            if (cur->children->type != XML_ENTITY_DECL) {
+                cur = cur->children;
+                if (copy != NULL)
+                    insert = copy;
+                continue;
+            }
+        }
+      skip_children:
+        if (cur->next != NULL) {
+            cur = cur->next;
+            continue;
+        }
+
+        do {
+            cur = cur->parent;
+            insert = insert->parent;
+            if (cur == NULL)
+                break;
+            if (cur == list->parent) {
+                cur = NULL;
+                break;
+            }
+            if (cur->next != NULL) {
+                cur = cur->next;
+                break;
+            }
+        } while (cur != NULL);
     }
     if (real)
-       ctxt->node = oldCurrent;
+        ctxt->node = oldCurrent;
     ctxt->inst = oldInst;
 }
 
index df69fac..c39685d 100644 (file)
@@ -671,6 +671,8 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
 
     if ((buf == NULL) || (result == NULL) || (style == NULL))
        return(-1);
+    if (result->children == NULL)
+       return(0);
 
     if ((style->methodURI != NULL) &&
        ((style->method == NULL) ||
@@ -828,6 +830,8 @@ xsltSaveResultToFilename(const char *URL, xmlDocPtr result,
 
     if ((URL == NULL) || (result == NULL) || (style == NULL))
        return(-1);
+    if (result->children == NULL)
+       return(0);
 
     XSLT_GET_IMPORT_PTR(encoding, style, encoding)
     if (encoding != NULL) {
@@ -869,6 +873,8 @@ xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style) {
 
     if ((file == NULL) || (result == NULL) || (style == NULL))
        return(-1);
+    if (result->children == NULL)
+       return(0);
 
     XSLT_GET_IMPORT_PTR(encoding, style, encoding)
     if (encoding != NULL) {
@@ -911,6 +917,8 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {
 
     if ((fd < 0) || (result == NULL) || (style == NULL))
        return(-1);
+    if (result->children == NULL)
+       return(0);
 
     XSLT_GET_IMPORT_PTR(encoding, style, encoding)
     if (encoding != NULL) {
index 0953493..04eeedf 100644 (file)
@@ -14,6 +14,7 @@ EXTRA_DIST =                                          \
     test-11.2-6.out test-11.2-6.xml test-11.2-6.xsl    \
     test-12.2-1.out test-12.2-1.xml test-12.2-1.xsl    \
     test-12.2-2.out test-12.2-2.xml test-12.2-2.xsl    \
+    test-15-1.out test-15-1.xml test-15-1.xsl          \
     test-2.3-1.out test-2.3-1.xml test-2.3-1.xsl       \
     test-2.3-2.out test-2.3-2.xml test-2.3-2.xsl       \
     test-2.5-1.out test-2.5-1.xml test-2.5-1.xsl       \
diff --git a/tests/REC/test-15-1.out b/tests/REC/test-15-1.out
new file mode 100644 (file)
index 0000000..965f7cd
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<doc>SUCCESS</doc>
diff --git a/tests/REC/test-15-1.xml b/tests/REC/test-15-1.xml
new file mode 100644 (file)
index 0000000..69d62f2
--- /dev/null
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/REC/test-15-1.xsl b/tests/REC/test-15-1.xsl
new file mode 100644 (file)
index 0000000..524f1e6
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+               xmlns:test="http://example.org/"
+               xsl:extension-element-prefixes="test"
+                version='1.0'>
+<xsl:template match="/">
+<test:test>
+<xsl:fallback><doc>SUCCESS</doc></xsl:fallback>
+</test:test>
+</xsl:template>
+</xsl:stylesheet>
index 2eef7e4..a519dbf 100644 (file)
@@ -58,7 +58,7 @@ single:
 xtchunk:
        @(echo > .memdump)
        @(for i in $(srcdir)/test/gdp-handbook.xml ; do \
-         echo "Texting HTML chunking on $$i :" ; \
+         echo "Testing HTML chunking on $$i :" ; \
          html=$(srcdir)/result/html/`basename $$i .xml`.html; \
          $(top_builddir)/libxslt/xsltproc -o $(srcdir)/result/xtchunk/html/gdp-handbook $(srcdir)/html/xtchunk.xsl $$i ; \
          for html in $(srcdir)/result/xtchunk/html/*.html ; do \
index a8c0be8..e69de29 100644 (file)
@@ -1,2 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
-
index 2ac8158..a1c21e5 100644 (file)
@@ -1,4 +1,3 @@
 Templates:
 #0 name / 
 Variables:
-<?xml version="1.0"?>
index 5ae6665..48ead92 100644 (file)
@@ -12,13 +12,13 @@ all: test
 test tests: $(top_builddir)/libxslt/xsltproc
        @(echo > .memdump)
        @($(top_builddir)/libxslt/xsltproc -timing $(srcdir)/REC-xml-2e.xsl $(srcdir)/REC-xml-20001006.xml > REC-xml-20001006.out 2> debug ; \
-       diff $(srcdir)/REC-xml-20001006.html REC-xml-20001006.out | grep -v 'id[0-9]' | grep -v -- '---' | grep -v 158 | grep -v 4031 ; \
+       diff $(srcdir)/REC-xml-20001006.html REC-xml-20001006.out | grep -v 'id[0-9]' | grep -v -- '---' | grep -v 100 | grep -v 3866 ; \
        grep implemented debug | sort | uniq -c || true; \
        grep " ms$$" debug || true; \
        grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0" || true;\
        rm -f REC-xml-20001006.out)
        @($(top_builddir)/libxslt/xsltproc  -timing --param show.diff.markup 1 $(srcdir)/REC-xml-2e.xsl $(srcdir)/REC-xml-20001006.xml > REC-xml-20001006-review.out 2> debug ; \
-       diff $(srcdir)/REC-xml-20001006-review.html REC-xml-20001006-review.out | grep -v 'id[0-9]' | grep -v -- '---' | grep -v 158 | grep -v 4031 ; \
+       diff $(srcdir)/REC-xml-20001006-review.html REC-xml-20001006-review.out | grep -v 'id[0-9]' | grep -v -- '---' | grep -v 117 | grep -v 4066 ; \
        grep implemented debug | sort | uniq -c || true; \
        grep " ms$$" debug || true; \
        grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0" || true;\