From d4956ec17b0c77a00fada90cdff7150c60e590f0 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sun, 12 Aug 2001 19:55:12 +0000 Subject: [PATCH] cleaned up the code w.r.t. handling of 'non-standard' libxml element like * libxslt/functions.c libxslt/keys.c libxslt/transform.c libxslt/xsltutils.h: cleaned up the code w.r.t. handling of 'non-standard' libxml element like namespace nodes. * tests/docs/Makefile.am tests/docs/bug-54.xml tests/general/Makefile.am tests/general/bug-54.*: added a specific example in the regression tests Daniel --- ChangeLog | 9 +++++++++ libxslt/functions.c | 3 ++- libxslt/keys.c | 40 ++++++++++++++++++++------------------- libxslt/transform.c | 24 ++++++++++++++--------- libxslt/xsltutils.h | 24 +++++++++++++++++++++++ tests/docs/Makefile.am | 1 + tests/docs/bug-54.xml | 5 +++++ tests/general/Makefile.am | 1 + tests/general/bug-54.out | 5 +++++ tests/general/bug-54.xsl | 22 +++++++++++++++++++++ 10 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 tests/docs/bug-54.xml create mode 100644 tests/general/bug-54.out create mode 100644 tests/general/bug-54.xsl diff --git a/ChangeLog b/ChangeLog index 0f444440..e961eab7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Sun Aug 12 21:53:13 CEST 2001 Daniel Veillard + + * libxslt/functions.c libxslt/keys.c libxslt/transform.c + libxslt/xsltutils.h: cleaned up the code w.r.t. handling + of 'non-standard' libxml element like namespace nodes. + * tests/docs/Makefile.am tests/docs/bug-54.xml + tests/general/Makefile.am tests/general/bug-54.*: added a + specific example in the regression tests + Wed Aug 8 22:57:05 CEST 2001 Daniel Veillard * HACKING: added John Fleck right to commit in the doc subdir diff --git a/libxslt/functions.c b/libxslt/functions.c index 87ec1560..1a00105c 100644 --- a/libxslt/functions.c +++ b/libxslt/functions.c @@ -189,7 +189,8 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){ valuePush(ctxt, xmlXPathNewNodeSet(NULL)); } else { if ((obj2 != NULL) && (obj2->nodesetval != NULL) && - (obj2->nodesetval->nodeNr > 0)) { + (obj2->nodesetval->nodeNr > 0) && + IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) { xmlNodePtr target; target = obj2->nodesetval->nodeTab[0]; diff --git a/libxslt/keys.c b/libxslt/keys.c index 0f042f37..78a91695 100644 --- a/libxslt/keys.c +++ b/libxslt/keys.c @@ -405,29 +405,31 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc, goto error; for (i = 0;i < nodelist->nodeNr;i++) { - ctxt->node = nodelist->nodeTab[i]; - str = xsltEvalXPathString(ctxt, keyd->usecomp); - if (str != NULL) { + if (IS_XSLT_REAL_NODE(nodelist->nodeTab[i])) { + ctxt->node = nodelist->nodeTab[i]; + str = xsltEvalXPathString(ctxt, keyd->usecomp); + if (str != NULL) { #ifdef WITH_XSLT_DEBUG_KEYS - xsltGenericDebug(xsltGenericDebugContext, - "xsl:key : node associated to(%s,%s)\n", - keyd->name, str); + xsltGenericDebug(xsltGenericDebugContext, + "xsl:key : node associated to(%s,%s)\n", + keyd->name, str); #endif - keylist = xmlHashLookup(table->keys, str); - if (keylist == NULL) { - keylist = xmlXPathNodeSetCreate(nodelist->nodeTab[i]); - xmlHashAddEntry(table->keys, str, keylist); + keylist = xmlHashLookup(table->keys, str); + if (keylist == NULL) { + keylist = xmlXPathNodeSetCreate(nodelist->nodeTab[i]); + xmlHashAddEntry(table->keys, str, keylist); + } else { + xmlXPathNodeSetAdd(keylist, nodelist->nodeTab[i]); + } + nodelist->nodeTab[i]->_private = keyd; + xmlFree(str); +#ifdef WITH_XSLT_DEBUG_KEYS } else { - xmlXPathNodeSetAdd(keylist, nodelist->nodeTab[i]); - } - nodelist->nodeTab[i]->_private = keyd; - xmlFree(str); -#ifdef WITH_XSLT_DEBUG_KEYS - } else { - xsltGenericDebug(xsltGenericDebugContext, - "xsl:key : use %s failed to return a string\n", - keyd->use); + xsltGenericDebug(xsltGenericDebugContext, + "xsl:key : use %s failed to return a string\n", + keyd->use); #endif + } } } diff --git a/libxslt/transform.c b/libxslt/transform.c index e9d9b08d..a0ae7ad6 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -586,6 +586,8 @@ xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node, return((xmlNodePtr) xsltCopyProp(ctxt, insert, (xmlAttrPtr) node)); case XML_NAMESPACE_DECL: + if (insert->type != XML_ELEMENT_NODE) + return(NULL); return((xmlNodePtr) xsltCopyNamespaceList(ctxt, insert, (xmlNsPtr) node)); @@ -912,7 +914,8 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node, /* * Cleanup children empty nodes if asked for */ - if ((node->children != NULL) && + if ((IS_XSLT_REAL_NODE(node)) && + (node->children != NULL) && (xsltFindElemSpaceHandling(ctxt, node))) { xmlNodePtr delete = NULL, cur = node->children; @@ -2260,7 +2263,8 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node, #endif list = res->nodesetval; if ((list != NULL) && (list->nodeTab != NULL) && - (list->nodeTab[0] != NULL)) { + (list->nodeTab[0] != NULL) && + (IS_XSLT_REAL_NODE(list->nodeTab[0]))) { xsltCopyTreeList(ctxt, list->nodeTab[0]->children, ctxt->insert); } @@ -2682,9 +2686,10 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node, ctxt->node = list->nodeTab[i]; ctxt->xpathCtxt->proximityPosition = i + 1; /* For a 'select' nodeset, need to check if document has changed */ - if ( (list->nodeTab[i]->doc!=NULL) && - (list->nodeTab[i]->doc->doc!=NULL) && - (list->nodeTab[i]->doc->doc)!=ctxt->xpathCtxt->doc) { + if ((IS_XSLT_REAL_NODE(list->nodeTab[i])) && + (list->nodeTab[i]->doc!=NULL) && + (list->nodeTab[i]->doc->doc!=NULL) && + (list->nodeTab[i]->doc->doc)!=ctxt->xpathCtxt->doc) { /* The nodeset is from another document, so must change */ ctxt->xpathCtxt->doc=list->nodeTab[i]->doc->doc; if ((ctxt->document = @@ -2696,7 +2701,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node, } ctxt->xpathCtxt->node = list->nodeTab[i]; #ifdef WITH_XSLT_DEBUG_PROCESS - xsltGenericDebug(xsltGenericDebugContext, + xsltGenericDebug(xsltGenericDebugContext, "xsltApplyTemplates: Changing document - context doc %s, xpathdoc %s\n", ctxt->document->doc->URL, ctxt->xpathCtxt->doc->URL); #endif @@ -3016,9 +3021,10 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node, ctxt->node = list->nodeTab[i]; ctxt->xpathCtxt->proximityPosition = i + 1; /* For a 'select' nodeset, need to check if document has changed */ - if ( (list->nodeTab[i]->doc!=NULL) && - (list->nodeTab[i]->doc->doc!=NULL) && - (list->nodeTab[i]->doc->doc)!=ctxt->xpathCtxt->doc) { + if ((IS_XSLT_REAL_NODE(list->nodeTab[i])) && + (list->nodeTab[i]->doc!=NULL) && + (list->nodeTab[i]->doc->doc!=NULL) && + (list->nodeTab[i]->doc->doc)!=ctxt->xpathCtxt->doc) { /* The nodeset is from another document, so must change */ ctxt->xpathCtxt->doc=list->nodeTab[i]->doc->doc; if ((ctxt->document = diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h index 5ec221f2..9d82ceaf 100644 --- a/libxslt/xsltutils.h +++ b/libxslt/xsltutils.h @@ -60,6 +60,30 @@ extern "C" { #define IS_XSLT_NAME(n, val) \ (xmlStrEqual((n)->name, (const xmlChar *) (val))) +/** + * IS_XSLT_REAL_NODE: + * + * check that a node is a 'real' one: document, element, text or attribute + */ +#ifdef LIBXML_DOCB_ENABLED +#define IS_XSLT_REAL_NODE(n) \ + (((n) != NULL) && \ + (((n)->type == XML_ELEMENT_NODE) || \ + ((n)->type == XML_TEXT_NODE) || \ + ((n)->type == XML_ATTRIBUTE_NODE) || \ + ((n)->type == XML_DOCUMENT_NODE) || \ + ((n)->type == XML_HTML_DOCUMENT_NODE) || \ + ((n)->type == XML_DOCB_DOCUMENT_NODE))) +#else +#define IS_XSLT_REAL_NODE(n) \ + (((n) != NULL) && \ + (((n)->type == XML_ELEMENT_NODE) || \ + ((n)->type == XML_TEXT_NODE) || \ + ((n)->type == XML_ATTRIBUTE_NODE) || \ + ((n)->type == XML_DOCUMENT_NODE) || \ + ((n)->type == XML_HTML_DOCUMENT_NODE))) +#endif + /* * Our own version of namespaced atributes lookup */ diff --git a/tests/docs/Makefile.am b/tests/docs/Makefile.am index 3737e5c6..29ad79c7 100644 --- a/tests/docs/Makefile.am +++ b/tests/docs/Makefile.am @@ -56,6 +56,7 @@ EXTRA_DIST = \ bug-50-.xml \ bug-52-.xml \ bug-53-.xml \ + bug-54-.xml \ character.xml \ array.xml \ items.xml diff --git a/tests/docs/bug-54.xml b/tests/docs/bug-54.xml new file mode 100644 index 00000000..bf13d1c8 --- /dev/null +++ b/tests/docs/bug-54.xml @@ -0,0 +1,5 @@ + + +1 +2 + diff --git a/tests/general/Makefile.am b/tests/general/Makefile.am index b194f01c..2c93383a 100644 --- a/tests/general/Makefile.am +++ b/tests/general/Makefile.am @@ -58,6 +58,7 @@ EXTRA_DIST = \ bug-50-.out bug-50-.xsl \ bug-52-.out bug-52-.xsl \ bug-53-.out bug-53-.xsl \ + bug-54-.out bug-54-.xsl \ character.out character.xsl \ character2.out character2.xsl \ itemschoose.out itemschoose.xsl \ diff --git a/tests/general/bug-54.out b/tests/general/bug-54.out new file mode 100644 index 00000000..cd6ab81c --- /dev/null +++ b/tests/general/bug-54.out @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/general/bug-54.xsl b/tests/general/bug-54.xsl new file mode 100644 index 00000000..0aa3840a --- /dev/null +++ b/tests/general/bug-54.xsl @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + +