xsltxslt-1.0exslt

Proper way to declare more than one EXSLT extension in an XSLT stylesheet


What is the proper way to declare more that one EXSLT extension in a single XSLT stylesheet?

And more importantly what is the purpose of xmlns:*="http://exslt.org/*"?

The documentation says:

You can use the extension-element-prefixes attribute to prevent the extension namespaces from being output in the result tree.

Is it just so as to not have xmlns:date="http://exslt.org/dates-and-times displayed in the root node of the output document? and if so why is it important?

With the following stylesheet I get the error:

lxml.etree.XMLSyntaxError: Attribute extension-element-prefixes redefined, line 7, column 40

I'm using XSLT 1.0 with the lxml processor.

XML Input

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl" version="1.0"?>
<item>test</item>

XSLT 1.0 Stylesheet

<xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:str="http://exslt.org/strings"
      xmlns:date="http://exslt.org/dates-and-times"
      extension-element-prefixes="str"
      extension-element-prefixes="date">

<xsl:template match="/">
  <html>
    <body>
      <xsl:value-of
        select="str:padding(2 - string-length(date:month-in-year()), 0)"/>
      <xsl:value-of select="date:month-in-year()"/>
    </body>
  </html>
</xsl:template>

</xsl:stylesheet>

HTML Output

<html xmlns:str="http://exslt.org/strings" xmlns:date="http://exslt.org/dates-and-times">
  <body>05</body>
</html>

Solution

  • You need to populate the xsl:extension-element-prefixes attribute with a whitespace-separated list of the declared namespace prefixes. In your example, that would be:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:str="http://exslt.org/strings"
    xmlns:date="http://exslt.org/dates-and-times"
    extension-element-prefixes="str date">
    

    And more importantly what is the purpose of xmlns:*="http://exslt.org/*"?

    It's a namespace declaration that binds the prefix to a namespace URI. The prefix can be anything you want - it is the namespace URI that tells the processor that the element is in a namespace that belongs to a supported extension.

    This has nothing to do with preventing the declaration from appearing in the output. That is accomplished by using either an extension-element-prefixes or exclude-result-prefixes attribute. Why is this important? It may be important if the namespace declaration is not part of the target schema.