I have a problem where Microsoft Excel wants a specific format for inline formatted text such that the Data element has a xmlns of "http://www.w3.org/TR/REC-html40" but the child elements (Font and B) have no defined namespace:
<Cell>
<ss:Data xmlns="http://www.w3.org/TR/REC-html40" ss:Type="String" xml:space="preserve">
<Font>normal text</Font>
<B>bold text</B>
<Font Color="#FF0000">red text</Font>
</ss:Data>
</Cell>
If any xmlns attribute is added to Font or B, they are not rendered correctly in Microsoft Excel.
I have the following source XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<text>normal text</text>
<b>bold text</b>
<red>red text</red>
</document>
My XSLT file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:svg="http://www.w3.org/2000/svg" version="2.0" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" version="1.0"/>
<xsl:template match="/">
<xsl:value-of disable-output-escaping="yes" select="'<?xml version="1.0" encoding="utf-8"?>'"/>
<xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Worksheet">
<Table>
<Row>
<Cell>
<ss:Data xmlns="http://www.w3.org/TR/REC-html40" ss:Type="String" xml:space="preserve"><xsl:apply-templates select="node()" /></ss:Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template match="text">
<Font><xsl:value-of select="." /></Font>
</xsl:template>
<xsl:template match="b">
<B><xsl:value-of select="." /></B>
</xsl:template>
<xsl:template match="red">
<Font Color="#FF0000"><xsl:value-of select="." /></Font>
</xsl:template>
</xsl:stylesheet>
I want to achieve the following output (note that the Font and B) elements have no xmlns attribute:
<?xml version="1.0" encoding="utf-8"?><?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:svg="http://www.w3.org/2000/svg">
<Worksheet ss:Name="Worksheet">
<Table>
<Row>
<Cell>
<ss:Data xmlns="http://www.w3.org/TR/REC-html40" ss:Type="String" xml:space="preserve"><Font>normal text</Font><B>bold text</B><Font Color="#FF0000">red text</Font> </ss:Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
Instead, my XSLT transform gives me (note that xmlns has been added to Font and B elements):
<?xml version="1.0" encoding="utf-8"?><?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:kc="http://www.kelvinconnect.com/"
xmlns:svg="http://www.w3.org/2000/svg">
<Worksheet ss:Name="Worksheet">
<Table>
<Row>
<Cell>
<ss:Data xmlns="http://www.w3.org/TR/REC-html40" ss:Type="String" xml:space="preserve"><Font xmlns="urn:schemas-microsoft-com:office:spreadsheet">normal text</Font><B xmlns="urn:schemas-microsoft-com:office:spreadsheet">bold text</B><Font Color="#FF0000" xmlns="urn:schemas-microsoft-com:office:spreadsheet">red text</Font></ss:Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
I understand that the defined default namespace (urn:schemas-microsoft-com:office:spreadsheet) is being added to the Font and B elements to clarify the namespace, given that the parent item (ss:Data) is defined to be in the "http://www.w3.org/TR/REC-html40" namespace, but my problem is that Microsoft Excel simply does not work unless the ss:Data element is defined to use xmlns of "http://www.w3.org/TR/REC-html40" AND the B and Font elements do NOT specify an xmlns attribute.
Can anyone suggest a way to alter my XSLT transform such that xmlns elements are not added to B and Font elements?
I tried adding exclude-result-prefixes="#default", but that had no effect.
I have also tried changing my templates to:
<xsl:template match="b">
<xsl:element name="B" namespace="">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
But this merely changed the xmlns attribute to blank (xmlns="") rather than removing the attribute completely.