The following XSLT transformation displays an error whenever I try to use the function node-name().
Error: E[Saxon6.5.5]The URI http://www.w3.org/2005/xpath-functions does not identify an external Java class
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<!--
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-->
<xsl:output method="text" />
<xsl:variable name="in" select="/"/>
<xsl:variable name="filter" select="document('elementsToBeLeftIn.xml')"/>
<xsl:template match="/">
<xsl:apply-templates select="*">
<xsl:with-param name="f" select="$filter/*"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*">
<xsl:param name="f"/>
<xsl:choose>
<xsl:when test="$f/*">
<xsl:copy-of select="fn:node-name()"/>
<!--
<xsl:for-each select="*[fn:node-name(.) = $f/*/fn:node-name(.)]">
<xsl:apply-templates select=".">
<xsl:with-param name="f" select="f/*[fn:node-name() = current()/fn:node-name()]"/>
</xsl:apply-templates>
</xsl:for-each>
-->
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Thanks David. This is what I really want to make work (it is recursive). Using name() I still get error *Unexpected tocken [<function>] in path expression*.
After you
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<!--
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-->
<xsl:output method="text" />
<xsl:variable name="in" select="/"/>
<xsl:variable name="filter" select="document('elementsToBeLeftIn.xml')"/>
<xsl:template match="/">
<xsl:apply-templates select="*">
<xsl:with-param name="f" select="$filter/*"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*">
<xsl:param name="f"/>
<xsl:choose>
<xsl:when test="$f/*">
<xsl:for-each select="*[name() = $f/*/name()]">
<xsl:apply-templates select=".">
<xsl:with-param name="f" select="f/*[name() = current()/name()]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Even in XSLT2 you never need to prefix standard functions like node-name(). But you are using saxon 6 which is XSLT1 so you must not prefix the functions or they will never be recognised. (XPath 1 standard functions are not in a namespace)
just use
select="name()"However I don’t think your code will work as you expect (but you didn’t say what you wanted it to do) but it will only ever apply templates to one element (the top level document element) as templates are never recursively applied.
In the case that the filter test is true
<xsl:copy-of select="name()"would put out the name of that element, with no markup (so the result will not be well formed xml).In the case that the filter test is false the entire document element including all its children is copied to the output and no further processing takes place.
is legal in XPath2 but not in XPath 1, where path expressions using
/may only use nodes not end with a function that returns a string. Not sure exactly what you want to do so can’t offer an immediate replacement.can be written as
in XPath 1.
But since you are using saxon java implementation why not simply use saxon 9 instead of saxon 6 and benefit from over a decade’s worth of further development in the xslt engine?