diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2001-02-08 11:16:41 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2001-02-08 11:16:41 +0000 |
commit | 443496a5d7ad1504ad5554f3a80d9539140fcb5c (patch) | |
tree | 1cd9a356c5592831467425f491fd15cb0ae58f8b | |
parent | 8b47e572e390ca59d2b010adb833a237bc4e9db3 (diff) | |
download | libxslt-443496a5d7ad1504ad5554f3a80d9539140fcb5c.tar.gz libxslt-443496a5d7ad1504ad5554f3a80d9539140fcb5c.tar.bz2 libxslt-443496a5d7ad1504ad5554f3a80d9539140fcb5c.zip |
Added more support for keys, nearly complete:
- FEATURES libxslt/xsltInternals.h libxslt/pattern.c libxslt/keys.c:
added support for keys in patterns
- tests/REC/test-12.2-2.*: added a specific testcase
Daniel
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | FEATURES | 4 | ||||
-rw-r--r-- | libxslt/keys.c | 23 | ||||
-rw-r--r-- | libxslt/pattern.c | 42 | ||||
-rw-r--r-- | libxslt/xsltInternals.h | 1 | ||||
-rw-r--r-- | tests/REC/test-12.2-2.out | 7 | ||||
-rw-r--r-- | tests/REC/test-12.2-2.xml | 4 | ||||
-rw-r--r-- | tests/REC/test-12.2-2.xsl | 11 |
8 files changed, 92 insertions, 6 deletions
@@ -1,3 +1,9 @@ +Thu Feb 8 12:09:58 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> + + * FEATURES libxslt/xsltInternals.h libxslt/pattern.c libxslt/keys.c: + added support for keys in patterns + * tests/REC/test-12.2-2.*: added a specific testcase + Wed Feb 7 21:16:47 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> * libxslt/functions.c FEATURES: started adding support for key() @@ -194,7 +194,7 @@ YES match="*|/" YES match="text()|@*" YES match="processing-instruction()|comment()" YES Namespace -NO Mode +YES Mode NO Extension Elements @@ -238,6 +238,6 @@ YES item[position() mod 2 = 1] YES div[@class="appendix"]//p YES @class YES @* -NO key('a','b') +YES except ns for key key('a','b') Daniel.Veillard@imag.fr diff --git a/libxslt/keys.c b/libxslt/keys.c index a25cceb3..056204fc 100644 --- a/libxslt/keys.c +++ b/libxslt/keys.c @@ -272,6 +272,7 @@ xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name, ret = (xmlNodeSetPtr)xmlHashLookup(table->keys, value); return(ret); } + table = table->next; } return(NULL); } @@ -370,6 +371,7 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) { } else { xmlXPathNodeSetAdd(keylist, nodelist->nodeTab[i]); } + nodelist->nodeTab[i]->_private = keyd; xmlFree(str); #ifdef DEBUG_KEYS } else { @@ -431,3 +433,24 @@ xsltFreeCtxtKeys(xsltTransformContextPtr ctxt) { xsltFreeKeyTableList((xsltKeyTablePtr) ctxt->keys); } +/* + * xsltIsKey: + * @ctxt: an XSLT transformation context + * @node: a node + * + * Returns 1 if the node is a Key, 0 otherwise + */ +int +xsltIsKey(xsltTransformContextPtr ctxt, xmlNodePtr node) { + if (node == NULL) + return(0); + + /* + * TODO: + * Something a bit more complex may be needed if we want + * to be able to do similar things with IDs + */ + if (node->_private != NULL) + return(1); + return(0); +} diff --git a/libxslt/pattern.c b/libxslt/pattern.c index 0bf79be9..51e4c11b 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -24,6 +24,7 @@ #include "xsltutils.h" #include "imports.h" #include "templates.h" +#include "keys.h" #include "pattern.h" /* #define DEBUG_PARSING */ @@ -58,6 +59,7 @@ struct _xsltStepOp { xsltOp op; xmlChar *value; xmlChar *value2; + xmlChar *value3; }; typedef struct _xsltCompMatch xsltCompMatch; @@ -139,6 +141,8 @@ xsltFreeCompMatch(xsltCompMatchPtr comp) { xmlFree(op->value); if (op->value2 != NULL) xmlFree(op->value2); + if (op->value3 != NULL) + xmlFree(op->value3); } memset(comp, -1, sizeof(xsltCompMatch)); xmlFree(comp); @@ -442,9 +446,21 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, return(0); break; } - case XSLT_OP_KEY: - TODO /* Handle Keys, might be done differently */ + case XSLT_OP_KEY: { + xmlNodeSetPtr list; + int i; + + list = xsltGetKey(ctxt, step->value, + step->value3, step->value2); + if (list == NULL) + return(0); + for (i = 0;i < list->nodeNr;i++) + if (list->nodeTab[i] == node) + break; + if (i >= list->nodeNr) + return(0); break; + } case XSLT_OP_NS: /* Namespace test */ if (node->ns == NULL) { @@ -761,6 +777,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, int aid) { return; } NEXT; + /* TODO: support namespace in keys */ PUSH(XSLT_OP_KEY, lit, lit2); } else if (xmlStrEqual(name, (const xmlChar *)"processing-instruction")) { NEXT; @@ -1250,9 +1267,11 @@ next_pattern: case XSLT_OP_ROOT: top = (xsltCompMatchPtr *) &(style->rootMatch); break; - case XSLT_OP_ID: case XSLT_OP_KEY: - /* TODO optimize ID/KEY !!! */ + top = (xsltCompMatchPtr *) &(style->keyMatch); + break; + case XSLT_OP_ID: + /* TODO optimize ID !!! */ case XSLT_OP_ALL: top = (xsltCompMatchPtr *) &(style->elemMatch); break; @@ -1487,6 +1506,19 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node) { } list = list->next; } + if (node->_private != NULL) { + list = style->keyMatch; + while ((list != NULL) && + ((ret == NULL) || (list->priority > ret->priority))) { + if (xsltTestCompMatch(ctxt, list, node, + ctxt->mode, ctxt->modeURI)) { + ret = list->template; + break; + } + list = list->next; + } + } + if (ret != NULL) return(ret); @@ -1512,6 +1544,8 @@ xsltFreeTemplateHashes(xsltStylesheetPtr style) { (xmlHashDeallocator) xsltFreeCompMatchList); if (style->rootMatch != NULL) xsltFreeCompMatchList(style->rootMatch); + if (style->keyMatch != NULL) + xsltFreeCompMatchList(style->keyMatch); if (style->elemMatch != NULL) xsltFreeCompMatchList(style->elemMatch); if (style->attrMatch != NULL) diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index 360d9c38..0989f4cb 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -116,6 +116,7 @@ struct _xsltStylesheet { void *templatesHash; /* hash table or wherever compiled templates informations are stored */ void *rootMatch; /* template based on / */ + void *keyMatch; /* template based on key() */ void *elemMatch; /* template based on * */ void *attrMatch; /* template based on @* */ void *parentMatch; /* template based on .. */ diff --git a/tests/REC/test-12.2-2.out b/tests/REC/test-12.2-2.out new file mode 100644 index 00000000..62ec6a48 --- /dev/null +++ b/tests/REC/test-12.2-2.out @@ -0,0 +1,7 @@ +<?xml version="1.0"?> + + +Success + + + diff --git a/tests/REC/test-12.2-2.xml b/tests/REC/test-12.2-2.xml new file mode 100644 index 00000000..b833b617 --- /dev/null +++ b/tests/REC/test-12.2-2.xml @@ -0,0 +1,4 @@ +<doc> + <div id="lookup"/> + <div id="unwanted"/> +</doc> diff --git a/tests/REC/test-12.2-2.xsl b/tests/REC/test-12.2-2.xsl new file mode 100644 index 00000000..68d1299c --- /dev/null +++ b/tests/REC/test-12.2-2.xsl @@ -0,0 +1,11 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format"> + +<xsl:key name="idkey" match="div" use="@id"/> + +<xsl:template match="key('idkey','lookup')"> +Success +</xsl:template> + +</xsl:stylesheet> |