diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2001-02-02 10:20:16 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2001-02-02 10:20:16 +0000 |
commit | 0726423c0f1d455e37671f2850845dd47c224527 (patch) | |
tree | 8dbad0b69f14686142da00fdeede6ee4dcde9f14 | |
parent | 22fc899b2da378bff95096d020154429228e3873 (diff) | |
download | libxslt-0726423c0f1d455e37671f2850845dd47c224527.tar.gz libxslt-0726423c0f1d455e37671f2850845dd47c224527.tar.bz2 libxslt-0726423c0f1d455e37671f2850845dd47c224527.zip |
And most of this is simply untested, yet...:
- FEATURES: updated
- transform.c: added xsl:element support
- namespaces.[ch]: added xsltGetSpecialNamespace()
- attributes.c: added xsl:attribute namespace support.
Daniel
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | FEATURES | 24 | ||||
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | libxslt/attributes.c | 7 | ||||
-rw-r--r-- | libxslt/namespaces.c | 45 | ||||
-rw-r--r-- | libxslt/namespaces.h | 5 | ||||
-rw-r--r-- | libxslt/transform.c | 90 |
7 files changed, 166 insertions, 19 deletions
@@ -1,3 +1,10 @@ +Fri Feb 2 11:15:24 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> + + * FEATURES: updated + * transform.c: added xsl:element support + * namespaces.[ch]: added xsltGetSpecialNamespace() + * attributes.c: added xsl:attribute namespace support. + Thu Feb 1 20:58:54 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> * libxslt/Makefile.am libxslt/imports.[ch]: new module to @@ -27,11 +27,11 @@ NO Embedding Stylesheets Top Level Elements: =================== -NO xsl:include -NO href = uri-reference +YES xsl:include +YES href = uri-reference -NO xsl:import -NO href = uri-reference +YES xsl:import +YES href = uri-reference YES xsl:strip-space YES elements = tokens @@ -49,8 +49,8 @@ YES xsl:namespace-alias YES stylesheet-prefix = prefix | "#default" YES result-prefix = prefix | "#default" -NO xsl:attribute-set -NO name = qname +YES xsl:attribute-set +YES name = qname NO use-attribute-sets = qnames YES xsl:variable @@ -92,14 +92,14 @@ NO xsl:apply-imports YES xsl:call-template YES name = qname -NO xsl:element -NO name = { qname } -NO namespace = { uri-reference } -NO use-attribute-sets = qnames +YES xsl:element +YES name = { qname } +YES namespace = { uri-reference } +YES use-attribute-sets = qnames YES xsl:attribute YES name = { qname } -NO namespace = { uri-reference } +YES namespace = { uri-reference } YES xsl:text YES disable-output-escaping = "yes" | "no" @@ -110,7 +110,7 @@ YES name = { ncname } YES xsl:comment YES xsl:copy -NO use-attribute-sets = qnames +YES use-attribute-sets = qnames YES xsl:value-of YES select = string-expression @@ -15,8 +15,7 @@ Design: be a bit ugly ... Import: - -> parse them - -> provide functions to circulate in the import tree of stylesheets + -> make sure we use the cascade wherever it's needed Extra functions: -> document() should not be a problem since Result Tree Fragments are @@ -64,6 +63,10 @@ Contextual error reporting: * * ******** +Import: + -> parse them + -> provide functions to circulate in the import tree of stylesheets + Extra functions: -> make a separate module. => done functions.[ch] diff --git a/libxslt/attributes.c b/libxslt/attributes.c index f119f423..68639920 100644 --- a/libxslt/attributes.c +++ b/libxslt/attributes.c @@ -325,16 +325,17 @@ xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node, prop = NULL; prefix = NULL; } + if ((prefix != NULL) && (xmlStrEqual(prefix, (const xmlChar *)"xmlns"))) { #ifdef DEBUG_PARSING - xsltGenericDebug(xsltGenericDebugContext, - "xslt:attribute : xmlns prefix forbidden\n"); + xsltGenericDebug(xsltGenericDebugContext, + "xslt:attribute : xmlns prefix forbidden\n"); #endif goto error; } prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"namespace"); if (prop != NULL) { - TODO /* xsl:attribute namespace */ + ns = xsltGetSpecialNamespace(ctxt, inst, prop, prefix, ctxt->insert); } else { if (prefix != NULL) { ns = xmlSearchNs(inst->doc, inst, prefix); diff --git a/libxslt/namespaces.c b/libxslt/namespaces.c index 1e699788..b70670d6 100644 --- a/libxslt/namespaces.c +++ b/libxslt/namespaces.c @@ -120,6 +120,51 @@ error: } /** + * xsltGetSpecificNamespace: + * @ctxt: a transformation context + * @cur: the input node + * @URI: the namespace URI + * @prefix: the suggested prefix + * @out: the output node (or its parent) + * + * Find the right namespace value for this URI, if needed create + * and add a new namespace decalaration on the node + * + * Returns the namespace node to use or NULL + */ +xmlNsPtr +xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, + const xmlChar *URI, const xmlChar *prefix, xmlNodePtr out) { + xmlNsPtr ret; + static int prefixno = 1; + char nprefix[10]; + + if ((ctxt == NULL) || (cur == NULL) || (out == NULL) || (URI == NULL)) + return(NULL); + + if ((out->parent != NULL) && + (out->parent->type == XML_ELEMENT_NODE) && + (out->parent->ns != NULL) && + (xmlStrEqual(out->parent->ns->href, URI))) + ret = out->parent->ns; + else + ret = xmlSearchNsByHref(out->doc, out, URI); + + if (ret == NULL) { + if (prefix == NULL) { + do { + sprintf(nprefix, "ns%d", prefixno++); + ret = xmlSearchNs(out->doc, out, (xmlChar *)nprefix); + } while (ret != NULL); + prefix = (const xmlChar *) &nprefix[0]; + } + if (out->type == XML_ELEMENT_NODE) + ret = xmlNewNs(out, URI, prefix); + } + return(ret); +} + +/** * xsltGetNamespace: * @ctxt: a transformation context * @cur: the input node diff --git a/libxslt/namespaces.h b/libxslt/namespaces.h index a4158a88..b972856c 100644 --- a/libxslt/namespaces.h +++ b/libxslt/namespaces.h @@ -21,6 +21,11 @@ xmlNsPtr xsltGetNamespace (xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, xmlNodePtr out); +xmlNsPtr xsltGetSpecialNamespace (xsltTransformContextPtr ctxt, + xmlNodePtr cur, + const xmlChar *URI, + const xmlChar *prefix, + xmlNodePtr out); xmlNsPtr xsltCopyNamespaceList (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNsPtr cur); diff --git a/libxslt/transform.c b/libxslt/transform.c index 5695ea27..9383bf3c 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -442,6 +442,94 @@ xsltCopy(xsltTransformContextPtr ctxt, xmlNodePtr node, } /** + * xsltElement: + * @ctxt: a XSLT process context + * @node: the node in the source tree. + * @inst: the xslt element node + * + * Process the xslt element node on the source node + */ +void +xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node, + xmlNodePtr inst) { + xmlChar *prop = NULL, *attributes = NULL; + xmlChar *ncname = NULL; + xmlChar *prefix = NULL; + xmlChar *value = NULL; + xmlNsPtr ns = NULL; + xmlNodePtr copy; + + + if (ctxt->insert == NULL) + return; + if (ctxt->insert->children != NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:element : node has already children\n"); + return; + } + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"name"); + if (prop == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:element : name is missing\n"); + goto error; + } + + ncname = xmlSplitQName2(prop, &prefix); + if (ncname == NULL) { + ncname = prop; + prop = NULL; + prefix = NULL; + } + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"namespace"); + if (prop != NULL) { + ns = xsltGetSpecialNamespace(ctxt, inst, prop, prefix, ctxt->insert); + } else { + if (prefix != NULL) { + if (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)) { +#ifdef DEBUG_PARSING + xsltGenericDebug(xsltGenericDebugContext, + "xslt:element : xml prefix forbidden\n"); +#endif + goto error; + } + ns = xmlSearchNs(inst->doc, inst, prefix); + if (ns == NULL) { + xsltGenericError(xsltGenericErrorContext, + "no namespace bound to prefix %s\n", prefix); + } else { + ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert); + } + } + } + + copy = xmlNewDocNode(ctxt->output, ns, ncname, NULL); + if (copy == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsl:element : creation of %s failed\n", ncname); + goto error; + } + xmlAddChild(ctxt->insert, copy); + attributes = xsltEvalAttrValueTemplate(ctxt, inst, + (const xmlChar *)"use-attribute-sets"); + if (attributes != NULL) { + xsltApplyAttributeSet(ctxt, node, inst, attributes); + xmlFree(attributes); + } + + xsltApplyOneTemplate(ctxt, ctxt->node, inst->children); + +error: + if (prop != NULL) + xmlFree(prop); + if (ncname != NULL) + xmlFree(ncname); + if (prefix != NULL) + xmlFree(prefix); + if (value != NULL) + xmlFree(value); +} + +/** * xsltComment: * @ctxt: a XSLT process context * @node: the node in the source tree. @@ -1174,12 +1262,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ctxt->insert = insert; xsltAttribute(ctxt, node, cur); ctxt->insert = oldInsert; - /******* } else if (IS_XSLT_NAME(cur, "element")) { ctxt->insert = insert; xsltElement(ctxt, node, cur); ctxt->insert = oldInsert; - *******/ } else if (IS_XSLT_NAME(cur, "comment")) { ctxt->insert = insert; xsltComment(ctxt, node, cur); |