How can I prevent these redundant namespaces from an XSLT stylesheet?

11,162

Solution 1

Instead of xsl:copy-of use an identity transformation templates and remove the namespace prefix from XHTML elements.

<xsl:stylesheet version="1.0"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:fbb="urn:foo:bar:baz"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="fbb html">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/fbb:foo">
    <html>
      <head>
        <title>Example</title>
      </head>
      <body>
        <p>
          <xsl:apply-templates select="fbb:bar/fbb:baz/node()"/>
        </p>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="html:*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Solution 2

Update your exclude-result-prefixes to include the default namespace:

exclude-result-prefixes="#default"

Or you could suppress all inline namespacing by doing:

exclude-result-prefixes="#all"

There is a bit of wonkiness though, as some processors expect a space-separated list while others expect a comma-separated list. xsltproc seems to like comma-separated so if you still want to be explicit you can do:

exclude-result-prefixes="#default,fbb"
Share:
11,162
Ben Blank
Author by

Ben Blank

Updated on June 12, 2022

Comments

  • Ben Blank
    Ben Blank almost 2 years

    When using an XSLT stylesheet to transform an XML file which contains embedded XHTML (using namespaces) into pure XHTML, I'm left with redundant namespace definitions on the elements which were originally XHTML. Simple test case:

    XML:

    <?xml version="1.0" encoding="utf-8" ?>
    <?xml-stylesheet type="text/xml" href="fbb.xsl"?>
    <foo xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml">
        <bar>
            <baz>Some <html:i>example</html:i> text.</baz>
        </bar>
    </foo>
    

    XSL:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:fbb="urn:foo:bar:baz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="fbb">
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:template match="/fbb:foo">
            <html>
                <head>
                    <title>Example</title>
                </head>
    
                <body>
                    <p>
                        <xsl:copy-of select="fbb:bar/fbb:baz/node()"/>
                    </p>
                </body>
            </html>
        </xsl:template>
    </xsl:stylesheet>
    

    Output:

    <?xml version="1.0"?>
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>Example</title>
      </head>
      <body>
        <p>Some <html:i xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml">example</html:i> text.</p>
      </body>
    </html>
    

    Is it possible to prevent the redundant namespaces (and prefix) from being added to the <i> element? (For reference, I'm using xsltproc with libxml2-2.7.3 and libxslt-1.1.24 on Cygwin.)