6
votes

I have a richtext field in a schema (Tridion 2011 SP1), with a basic XSLT filter attached (the default XSLT or a custom one, it doesn't matter for this issue).

In IE9, when I create a component based on that schema, the XHTML in the Source tab is rendered fine, without any namespace, e.g.:

<p>a paragraph</p>
<p>
    <a href="http://www.sdltridion.com">a link</a>
</p>

I am able to save the component.

But in Firefox (16.0.2, unsupported), a namespace is rendered in the Source tab:

<p xmlns="http://www.w3.org/1999/XSL/Transform">a paragraph</p>
<p xmlns="http://www.w3.org/1999/XSL/Transform">
    <a href="http://www.sdltridion.com">a link</a>
</p>

which results in the following XML validation error:

The element 'Paragraph' in namespace 'http://www.yme.com/GeneralContent' has invalid child element 'p' in namespace 'http://www.w3.org/1999/XSL/Transform'. List of possible elements expected: any element in namespace 'http://www.w3.org/1999/xhtml'..

Now I know that it's an unsupported version of a Firefox, but where is this namespace coming from? The namespace defined in the Richtext XSLT is http://www.w3.org/1999/XSL/Transform...

And does anyone know of a possible workaround?

Here's the filtering XSLT, but as I already stated, it happens with the default XSLT too:

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output omit-xml-declaration="yes" method="xml" cdata-section-elements="script"></output>
    <template match="/ | node() | @*">
        <copy>
            <apply-templates select="node() | @*"></apply-templates>
        </copy>
    </template>
    <template match="*[(self::br or self::p or self::div) and normalize-space(translate(., &apos; &apos;, &apos;&apos;)) = &apos;&apos; and not(@*)     and      not(processing-instruction()) and not(comment()) and not(*[not(self::br) or @* or * or node()]) and not(following::node()[not((self::text() or self::br or self::p or self::div) and normalize-space(translate(., &apos; &apos;, &apos;&apos;)) = &apos;&apos;        and         not(@*) and not(processing-instruction()) and not(comment())        and         not(*[not(self::br) or @* or * or node()]))])]">
    </template>
    <template match="br[parent::div and not(preceding-sibling::node()) and not(following-sibling::node())]">
        <text></text>
    </template>
    <template match="table|td|tr|th|tbody|p|div|a">
        <element name="{name()}">
            <choose>
                <when test="name() =&apos;img&apos;">
                    <for-each select="@*">
                        <attribute name="{name()}">
                            <value-of select="."></value-of>
                        </attribute>
                    </for-each>
                </when>
                <otherwise>
                    <for-each select="@*">
                        <choose>
                            <when test="name() =&apos;border&apos;"></when>
                            <when test="name() =&apos;cellpadding&apos;"></when>
                            <when test="name() =&apos;cellspacing&apos;"></when>
                            <when test="name() =&apos;bgcolor&apos;"></when>
                            <when test="name() =&apos;bordercolor&apos;"></when>
                            <when test="name() =&apos;width&apos;"></when>
                            <when test="name() =&apos;height&apos;"></when>
                            <when test="name() =&apos;bordercolor&apos;"></when>
                            <when test="name() =&apos;span&apos;"></when>
                            <when test="name() =&apos;style&apos;"></when>
                            <when test="name() =&apos;class&apos;">
                                <choose>
                                    <when test=". =&apos;MsoNormal&apos;"></when>
                                    <otherwise>
                                        <attribute name="{name()}">
                                            <value-of select="."></value-of>
                                        </attribute>
                                    </otherwise>
                                </choose>
                            </when>
                            <otherwise>
                                <attribute name="{name()}">
                                    <value-of select="."></value-of>
                                </attribute>
                            </otherwise>
                        </choose>
                    </for-each>
                </otherwise>
            </choose>
            <apply-templates></apply-templates>
        </element>
    </template>
    <template match="h1">
        <element name="h2">
            <apply-templates></apply-templates>
        </element>
    </template>
    <template match="td/p">
        <apply-templates></apply-templates>
    </template>
    <template match="li/p">
        <apply-templates></apply-templates>
    </template>
    <template match="link|script|font|iframe|ilayer|layer|span|small">
        <apply-templates></apply-templates>
    </template>
</stylesheet>
2
Has your environment been recently migrated to 2011? If so can you post your Format Area XSLT in the question?Chris Summers
Yes, it has been migrated from 2009. We already had to fix another issue with richtext XSLT (Source tab would stay blank when switching). I added the filtering XSLT, but this happens with the default XSLT too. I'm wondering whether changes like these are really persistent in cache? I restarted IIS anyway after restoring the default XSLTReinder Wit
You might need to delete your browser cache to see the changes, as the Schema is cached locally on the client browserChris Summers

2 Answers

6
votes

I believe this issue is related to this post

Tridion 2011 - Filtering XSLT on Formatting Feature window

It seems like the migration process (or perhaps an odd GUI behavior) is altering the filtering XSLT, and seems to impact the behavior of the RTF fields. Basically the way the namespace and namespace prefixes are used in the XSLT seem to have changed. A typical XSLT uses the xsl namespace prefix, wheras your new XSLT seems to exclude the prefix and use a default namespace.

I think this is a bug, and should be submitted to support, but the workaround is covered in the related post.

3
votes

Well your stylesheet has <stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform"> and then does <element name="{name()}"> for <template match="table|td|tr|th|tbody|p|div|a"> meaning it takes input p (and table etc.) elements and transforms them into elements with the same name (e.g. p) but in the XSLT namespace.

So what you probably want instead is write the XSLT code with a prefix (i.e. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> and <xsl:template match="table|td|tr|th|tbody|p|div|a">) so that the XSLT namespace does not interfere with result elements you want to create.

On the other hand replacing <element name="{name()}"> with <xsl:copy> should do as well.