summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2001-02-02 10:20:16 +0000
committerDaniel Veillard <veillard@src.gnome.org>2001-02-02 10:20:16 +0000
commit0726423c0f1d455e37671f2850845dd47c224527 (patch)
tree8dbad0b69f14686142da00fdeede6ee4dcde9f14
parent22fc899b2da378bff95096d020154429228e3873 (diff)
downloadlibxslt-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--ChangeLog7
-rw-r--r--FEATURES24
-rw-r--r--TODO7
-rw-r--r--libxslt/attributes.c7
-rw-r--r--libxslt/namespaces.c45
-rw-r--r--libxslt/namespaces.h5
-rw-r--r--libxslt/transform.c90
7 files changed, 166 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ffa204d..57a01753 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/FEATURES b/FEATURES
index 22959b07..eeeda7cc 100644
--- a/FEATURES
+++ b/FEATURES
@@ -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
diff --git a/TODO b/TODO
index 2caefd19..acc15a60 100644
--- a/TODO
+++ b/TODO
@@ -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);