I have an xsl that copies a xml file and renames the root tag.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:abc="http://example.com">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<test>
<xsl:apply-templates select="node()|@*"/>
</test>
</xsl:template>
<!--xsl:template match="abc:set">
-<xsl:apply-templates select="node()|@*"/>-
</xsl:template-->
</xsl:stylesheet>
That works fine but when I uncomment the last block to handle some namespaced tags I got an error that the says that something is wrong with the copy statement. How can I match and transform namespaced tags?
I don't know what exactly you are trying to achieve. Your question is a little abstract. However your match attribute is correct. But there is not difference right now as to what :
does and as to what this :
does. If you just want to copy everything then the first template would suffice including tags with namespaces. Otherwise I guess you would need to do something differently when matching your namespaced tag. If so then you don't need to call the identity match template again. e.g. :
Rest assured that this will match all abc:set tags and apply the transformation to them.
You are likely getting an error because the
abc:set
element has attributes, and your template matching onabc:set
is producing "naked" attributes that are not attached to an element.Since you are not copying the
abc:set
element (or creating an element) in the template match forabc:set
, when theapply-templates
inside of that template applies the templates to the selectedabc:set/@*
andabc:set/node()
, then the attributes match the identity template and will be copied forward.You can verify whether that is the issue by taking the
@*
out of the select statement for theapply-templates
, like this:The template above will only process the child nodes of
abc:set
.If your intent was to simply copy the
abc:set
, then you don't need a specific template matching on that element. The identity template will match on it and handle that for you.If you really want to remove the
abc:set
element but keep the sub-tree of which it is the root of, then replace:with:
Your original code would cause errors if the matched element has attributes, because then the identity rule will copy them, likely not in addition to creating an element, so this would be an attempt at producing attributes belonging to no element. Any XSLT processor is obliged to signal an error in this case.
The replacement code doesn't process any of the attributes of the matched
abc:set
element.