diff options
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | libxslt/namespaces.c | 95 | ||||
| -rw-r--r-- | libxslt/namespaces.h | 6 | ||||
| -rw-r--r-- | libxslt/transform.c | 9 | ||||
| -rw-r--r-- | libxslt/xslt.c | 5 | ||||
| -rw-r--r-- | libxslt/xsltInternals.h | 4 | ||||
| -rw-r--r-- | tests/namespaces/Makefile.am | 4 | ||||
| -rw-r--r-- | tests/namespaces/tst7.out | 13 | ||||
| -rw-r--r-- | tests/namespaces/tst7.xml | 2 | ||||
| -rw-r--r-- | tests/namespaces/tst7.xsl | 21 | ||||
| -rw-r--r-- | tests/namespaces/tst8.out | 7 | ||||
| -rw-r--r-- | tests/namespaces/tst8.xml | 2 | ||||
| -rw-r--r-- | tests/namespaces/tst8.xsl | 18 |
13 files changed, 171 insertions, 22 deletions
@@ -1,3 +1,10 @@ +Sat Aug 14 21:49:48 PDT 2004 William Brack <wbrack@mmm.comlhk> + + * libxslt/namespaces.[ch], transform.c, xslt.c, xsltInternals.h: + fixed handling of #default in namespace-alias for default + namespace (bug 149659) + * tests/namespaces/tst7.* tst8.*: added regression tests for above + Fri Aug 6 11:05:31 PDT 2004 William Brack <wbrack@mmm.com.hk> * libexslt/date.c: added date:sum routine supplied by Joel diff --git a/libxslt/namespaces.c b/libxslt/namespaces.c index f8a62cc0..d54edf79 100644 --- a/libxslt/namespaces.c +++ b/libxslt/namespaces.c @@ -64,8 +64,10 @@ void xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) { xmlChar *sprefix; xmlNsPtr sNs; + const xmlChar *shref; xmlChar *rprefix; xmlNsPtr rNs; + const xmlChar *rhref; sprefix = xsltGetNsProp(node, (const xmlChar *)"stylesheet-prefix", XSLT_NAMESPACE); @@ -81,37 +83,68 @@ xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node) { "namespace-alias: result-prefix attribute missing\n"); goto error; } + if (xmlStrEqual(sprefix, (const xmlChar *)"#default")) { + /* + * Do we have a default namespace previously declared? + */ sNs = xmlSearchNs(node->doc, node, NULL); + if (sNs == NULL) + shref = NULL; /* No - set NULL */ + else + shref = sNs->href; /* Yes - set for nsAlias table */ } else { sNs = xmlSearchNs(node->doc, node, sprefix); + + if ((sNs == NULL) || (sNs->href == NULL)) { + xsltTransformError(NULL, style, node, + "namespace-alias: prefix %s not bound to any namespace\n", + sprefix); + goto error; + } else + shref = sNs->href; } - if ((sNs == NULL) || (sNs->href == NULL)) { - xsltTransformError(NULL, style, node, - "namespace-alias: prefix %s not bound to any namespace\n", - sprefix); - goto error; - } + + /* + * When "#default" is used for result, if a default namespace has not + * been explicitly declared the special value UNDEFINED_DEFAULT_NS is + * put into the nsAliases table + */ if (xmlStrEqual(rprefix, (const xmlChar *)"#default")) { rNs = xmlSearchNs(node->doc, node, NULL); + if (rNs == NULL) + rhref = UNDEFINED_DEFAULT_NS; + else + rhref = rNs->href; } else { rNs = xmlSearchNs(node->doc, node, rprefix); + + if ((rNs == NULL) || (rNs->href == NULL)) { + xsltTransformError(NULL, style, node, + "namespace-alias: prefix %s not bound to any namespace\n", + rprefix); + goto error; + } else + rhref = rNs->href; } - if ((rNs == NULL) || (rNs->href == NULL)) { - xsltTransformError(NULL, style, node, - "namespace-alias: prefix %s not bound to any namespace\n", - rprefix); - goto error; - } - if (style->nsAliases == NULL) - style->nsAliases = xmlHashCreate(10); - if (style->nsAliases == NULL) { - xsltTransformError(NULL, style, node, - "namespace-alias: cannot create hash table\n"); - goto error; + /* + * Special case if #default is used for stylesheet and no default has + * been explicitly declared. We use style->defaultAlias for this + */ + if (shref == NULL) { + if (rNs != NULL) + style->defaultAlias = rNs->href; + } else { + if (style->nsAliases == NULL) + style->nsAliases = xmlHashCreate(10); + if (style->nsAliases == NULL) { + xsltTransformError(NULL, style, node, + "namespace-alias: cannot create hash table\n"); + goto error; + } + xmlHashAddEntry((xmlHashTablePtr) style->nsAliases, + shref, (void *) rhref); } - xmlHashAddEntry((xmlHashTablePtr) style->nsAliases, - sNs->href, (void *) rNs->href); error: if (sprefix != NULL) @@ -247,6 +280,15 @@ xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, style = xsltNextImport(style); } + if (URI == UNDEFINED_DEFAULT_NS) { + xmlNsPtr dflt; + dflt = xmlSearchNs(cur->doc, cur, NULL); + if (dflt == NULL) + return NULL; + else + URI = dflt->href; + } + if (URI == NULL) URI = ns->href; @@ -368,7 +410,14 @@ xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns, style = xsltNextImport(style); } - if (URI == NULL) + if (URI == UNDEFINED_DEFAULT_NS) { + xmlNsPtr dflt; + dflt = xmlSearchNs(cur->doc, cur, NULL); + if (dflt != NULL) + URI = dflt->href; + else + return NULL; + } else if (URI == NULL) URI = ns->href; /* @@ -456,6 +505,8 @@ xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node, /* TODO apply cascading */ URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases, cur->href); + if (URI == UNDEFINED_DEFAULT_NS) + continue; if (URI != NULL) { q = xmlNewNs(node, URI, cur->prefix); } else { @@ -505,6 +556,8 @@ xsltCopyNamespace(xsltTransformContextPtr ctxt, xmlNodePtr node, if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) { URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases, cur->href); + if (URI == UNDEFINED_DEFAULT_NS) + return(NULL); if (URI != NULL) { ret = xmlNewNs(node, URI, cur->prefix); } else { diff --git a/libxslt/namespaces.h b/libxslt/namespaces.h index c92eb1a7..acc3aa0f 100644 --- a/libxslt/namespaces.h +++ b/libxslt/namespaces.h @@ -18,6 +18,12 @@ extern "C" { #endif +/* + * Used within nsAliases hashtable when the default namespace is required + * but it's not been explicitly defined + */ +#define UNDEFINED_DEFAULT_NS (const xmlChar *) -1L + XSLTPUBFUN void XSLTCALL xsltNamespaceAlias (xsltStylesheetPtr style, xmlNodePtr node); diff --git a/libxslt/transform.c b/libxslt/transform.c index 35b6e2b1..043f009e 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -1715,6 +1715,15 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, style = xsltNextImport(style); } + if (URI == UNDEFINED_DEFAULT_NS) { + xmlNsPtr dflt; + dflt = xmlSearchNs(cur->doc, cur, NULL); + if (dflt == NULL) + continue; + else + URI = dflt->href; + } + if (URI == NULL) { ret = xmlSearchNs(copy->doc, copy, ns->prefix); if ((ret == NULL) || diff --git a/libxslt/xslt.c b/libxslt/xslt.c index 2445c768..72b88694 100644 --- a/libxslt/xslt.c +++ b/libxslt/xslt.c @@ -1496,6 +1496,11 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) { * This is an element which will be output as part of the * template exectution, precompile AVT if found. */ + if ((cur->ns == NULL) && (style->defaultAlias != NULL) && + (cur->type == XML_ELEMENT_NODE)) { + cur->ns = xmlSearchNsByHref(cur->doc, cur, + style->defaultAlias); + } if (cur->properties != NULL) { xmlAttrPtr attr = cur->properties; diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index b5d5238c..386405c2 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -431,6 +431,10 @@ struct _xsltStylesheet { * precompiled attribute value templates. */ void *attVTs; + /* + * if namespace-alias has an alias for the default stylesheet prefix + */ + const xmlChar *defaultAlias; }; /* diff --git a/tests/namespaces/Makefile.am b/tests/namespaces/Makefile.am index ebb95810..4c58bd72 100644 --- a/tests/namespaces/Makefile.am +++ b/tests/namespaces/Makefile.am @@ -11,7 +11,9 @@ EXTRA_DIST = \ tst3.xml tst3.xsl tst3.out \ tst4.xml tst4.xsl tst4.out \ tst5.xml tst5.xsl tst5.out \ - tst6.xml tst6.xsl tst6.out + tst6.xml tst6.xsl tst6.out \ + tst7.xml tst7.xsl tst7.out \ + tst8.xml tst8.xsl tst8.out all: diff --git a/tests/namespaces/tst7.out b/tests/namespaces/tst7.out new file mode 100644 index 00000000..b86f605e --- /dev/null +++ b/tests/namespaces/tst7.out @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title> + A title + </title> + </head> + <body> + Some text + </body> +</html> diff --git a/tests/namespaces/tst7.xml b/tests/namespaces/tst7.xml new file mode 100644 index 00000000..ac9ac8fd --- /dev/null +++ b/tests/namespaces/tst7.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" ?> +<adoc /> diff --git a/tests/namespaces/tst7.xsl b/tests/namespaces/tst7.xsl new file mode 100644 index 00000000..1ce238bd --- /dev/null +++ b/tests/namespaces/tst7.xsl @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" ?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:html="http://http://www.w3.org/1999/xhtml"> + <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" +doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" +doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" /> + <xsl:namespace-alias stylesheet-prefix="html" result-prefix="#default" /> + <xsl:strip-space elements="*" /> + <xsl:template match="/adoc"> + <html:html> + <html:head> + <html:title> + A title + </html:title> + </html:head> + <html:body> + Some text + </html:body> + </html:html> + </xsl:template> +</xsl:stylesheet> diff --git a/tests/namespaces/tst8.out b/tests/namespaces/tst8.out new file mode 100644 index 00000000..5eabde58 --- /dev/null +++ b/tests/namespaces/tst8.out @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<bb:root xmlns:bb="http://bbrack.org"> + <element1 xmlns="http://delightful.com.hk"> + <element2>Content 2</element2> + </element1> + <bb:element3>Content 3</bb:element3> +</bb:root> diff --git a/tests/namespaces/tst8.xml b/tests/namespaces/tst8.xml new file mode 100644 index 00000000..ac9ac8fd --- /dev/null +++ b/tests/namespaces/tst8.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" ?> +<adoc /> diff --git a/tests/namespaces/tst8.xsl b/tests/namespaces/tst8.xsl new file mode 100644 index 00000000..52f2caa1 --- /dev/null +++ b/tests/namespaces/tst8.xsl @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:bb="http://bbrack.org"> + <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> + <xsl:namespace-alias + stylesheet-prefix="#default" + result-prefix="bb" /> + <xsl:strip-space elements="*" /> + <xsl:template match="/adoc"> + <root> + <element1 xmlns="http://delightful.com.hk"> + <element2>Content 2</element2> + </element1> + <element3>Content 3</element3> + </root> + </xsl:template> +</xsl:stylesheet> |
