* *
************************************************************************/
-xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
- xmlNodePtr insert);
+xmlNodePtr xsltCopyTree(xsltTransformContextPtr ctxt,
+ xmlNodePtr node, xmlNodePtr insert, int literal);
/**
* xsltCopyTextString:
* @ctxt: a XSLT process context
* @list: the list of element nodes in the source tree.
* @insert: the parent in the result tree.
+ * @literal: is this a literal result element list
*
* Make a copy of the full list of tree @list
* and insert it as last children of @insert
+ * For literal result element, some of the namespaces may not be copied
+ * over according to section 7.1 .
*
* Returns a pointer to the new list, or NULL in case of error
*/
static xmlNodePtr
xsltCopyTreeList(xsltTransformContextPtr ctxt, xmlNodePtr list,
- xmlNodePtr insert) {
+ xmlNodePtr insert, int literal) {
xmlNodePtr copy, ret = NULL;
while (list != NULL) {
- copy = xsltCopyTree(ctxt, list, insert);
+ copy = xsltCopyTree(ctxt, list, insert, literal);
if (copy != NULL) {
if (ret == NULL) {
ret = copy;
}
/**
+ * xsltCopyNamespaceListInternal:
+ * @node: the target node
+ * @cur: the first namespace
+ *
+ * Do a copy of an namespace list. If @node is non-NULL the
+ * new namespaces are added automatically.
+ *
+ * Returns: a new xmlNsPtr, or NULL in case of error.
+ */
+static xmlNsPtr
+xsltCopyNamespaceListInternal(xmlNodePtr node, xmlNsPtr cur) {
+ xmlNsPtr ret = NULL;
+ xmlNsPtr p = NULL,q;
+
+ if (cur == NULL)
+ return(NULL);
+ if (cur->type != XML_NAMESPACE_DECL)
+ return(NULL);
+
+ /*
+ * One can add namespaces only on element nodes
+ */
+ if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
+ node = NULL;
+
+ while (cur != NULL) {
+ if (cur->type != XML_NAMESPACE_DECL)
+ break;
+
+ /*
+ * Avoid duplicating namespace declrations on the tree
+ */
+ if ((node != NULL) && (node->ns != NULL) &&
+ (xmlStrEqual(node->ns->href, cur->href)) &&
+ (xmlStrEqual(node->ns->prefix, cur->prefix))) {
+ cur = cur->next;
+ continue;
+ }
+
+ q = xmlNewNs(node, cur->href, cur->prefix);
+ if (p == NULL) {
+ ret = p = q;
+ } else if (q != NULL) {
+ p->next = q;
+ p = q;
+ }
+ cur = cur->next;
+ }
+ return(ret);
+}
+
+/**
* xsltCopyTree:
* @ctxt: a XSLT process context
* @node: the element node in the source tree.
* @insert: the parent in the result tree.
+ * @literal: is this a literal result element list
*
* Make a copy of the full tree under the element node @node
* and insert it as last child of @insert
+ * For literal result element, some of the namespaces may not be copied
+ * over according to section 7.1 .
*
* Returns a pointer to the new tree, or NULL in case of error
*/
xmlNodePtr
xsltCopyTree(xsltTransformContextPtr ctxt, xmlNodePtr node,
- xmlNodePtr insert) {
+ xmlNodePtr insert, int literal) {
xmlNodePtr copy;
if (node == NULL)
if ((node->name != NULL) && (node->name[0] == ' ') &&
(xmlStrEqual(node->name, (const xmlChar *) " fake node libxslt"))) {
if (node->children != NULL)
- copy = xsltCopyTreeList(ctxt, node->children, insert);
+ copy = xsltCopyTreeList(ctxt, node->children, insert, 0);
else
copy = NULL;
return(copy);
xmlNewNs(copy, BAD_CAST "", NULL);
}
}
- if (node->nsDef != NULL)
- xsltCopyNamespaceList(ctxt, copy, node->nsDef);
+ if (node->nsDef != NULL) {
+ if (literal)
+ xsltCopyNamespaceList(ctxt, copy, node->nsDef);
+ else
+ xsltCopyNamespaceListInternal(copy, node->nsDef);
+ }
if (node->properties != NULL)
copy->properties = xsltCopyPropList(ctxt, copy,
node->properties);
if (node->children != NULL)
- xsltCopyTreeList(ctxt, node->children, copy);
+ xsltCopyTreeList(ctxt, node->children, copy, literal);
} else {
xsltTransformError(ctxt, NULL, node,
"xsltCopyTree: copy %s failed\n", node->name);
if ((list->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
(list->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) {
xsltCopyTreeList(ctxt, list->nodeTab[i]->children,
- ctxt->insert);
+ ctxt->insert, 0);
} else if (list->nodeTab[i]->type == XML_ATTRIBUTE_NODE) {
xsltCopyProp(ctxt, ctxt->insert,
(xmlAttrPtr) list->nodeTab[i]);
} else {
- xsltCopyTree(ctxt, list->nodeTab[i], ctxt->insert);
+ xsltCopyTree(ctxt, list->nodeTab[i], ctxt->insert, 0);
}
}
}
(list->nodeTab[0] != NULL) &&
(IS_XSLT_REAL_NODE(list->nodeTab[0]))) {
xsltCopyTreeList(ctxt, list->nodeTab[0]->children,
- ctxt->insert);
+ ctxt->insert, 0);
}
} else {
/* convert to a string */
--- /dev/null
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:l="http://www.foobar.com/xmlns/l"
+ xmlns:s="http://www.foobar.com/xmlns/s"
+ xmlns:exsl="http://exslt.org/common"
+ exclude-result-prefixes="l"
+ extension-element-prefixes="exsl"
+>
+
+<xsl:output method="html" media-type="text/html" encoding="ISO-8859-1" />
+
+<xsl:template match="/">
+ <xsl:apply-templates select="l:doc" />
+</xsl:template>
+
+<xsl:template match="l:doc">
+ <s:doc>
+ <xsl:for-each select="@*">
+ <xsl:attribute name="{name()}"><xsl:value-of
+select="."/></xsl:attribute>
+ </xsl:for-each>
+ <s:doc-head>
+ <xsl:apply-templates select="l:doc-head"/>
+ </s:doc-head>
+ <s:doc-body>
+ <s:div class="header">
+ <s:a href="/">
+ <s:img
+src="/images/logo/mylogo.jpg" width="200" height="100" border="0"
+title="LOGO" alt="LOGO"/>
+ </s:a>
+ </s:div>
+ <s:br/>
+ <s:div class="body">
+ <xsl:apply-templates select="l:doc-content"/>
+ </s:div>
+ </s:doc-body>
+ </s:doc>
+</xsl:template>
+
+<xsl:template match="l:doc-title">
+ <s:doc-title><xsl:apply-templates/></s:doc-title>
+</xsl:template>
+
+<!-- some HTML-like elements -->
+<xsl:template
+match="l:a|l:abbr|l:acronym|l:address|l:area|l:b|l:base|l:bdo|l:big|l:blockquote|l:body|l:br|l:button|l:caption|l:cite|l:code|l:col|l:colgroup|l:dd|l:del|l:dfn|l:div|l:dl|l:dt|l:em|l:fieldset|l:form|l:frame|l:framset|l:h1|l:h2|l:h3|l:h4|l:h5|l:h6|l:head|l:hr|l:i|l:iframe|l:img|l:input|l:ins|l:kbd|l:label|l:legend|l:li|l:link|l:map|l:noframes|l:noscript|l:object|l:ol|l:optgroup|l:option|l:p|l:param|l:pre|l:q|l:samp|l:script|l:select|l:small|l:span|l:strong|l:style|l:sub|l:sup|l:table|l:tbody|l:td|l:textarea|l:tfoot|l:th|l:thead|l:tr|l:tt|l:ul|l:var">
+ <xsl:element name="s:{local-name()}">
+ <xsl:for-each select="@*">
+ <xsl:attribute name="{name()}"><xsl:value-of
+select="." /></xsl:attribute>
+ </xsl:for-each>
+ <xsl:apply-templates />
+ </xsl:element>
+</xsl:template>
+
+</xsl:stylesheet>