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.)
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>
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With