3

I'm replacing links in a RTF with an iframe wrapped with a div. I'm using <element name="div"> to create new tags. This works fine.

However, the XML rendered when i switch to the source tab contains an unwanted xmlns-attribute, that prevents me from saving the component!

What I am expecting is:

<div class="video-container">

And what I am getting is:

<div xmlns="http://www.w3.org/1999/XSL/Transform" class="video-container">

So with this xmlns attribute (since div is not part of the XSL Transform schema), the error I am getting says:

(80040356) XML validation error. Reason: The element 'body' in namespace 'uuid:e3dc07b9-c583-461e-80ee-69a9cd39e596' has invalid child element 'div' in namespace 'http://www.w3.org/1999/XSL/Transform'. List of possible elements expected: any element in namespace 'http://www.w3.org/1999/xhtml'.. Unable to save new item

And if I try to explicitly set the namespace on the div with this:

<attribute name="xmlns">http://www.w3.org/1999/xhtml</attribute>

, then I get the following error:

Error: Attribute xmlns redefined

*UPDATED (before I only included the filtering XSLT part, now here's the whole schema) *

Here is my complete schema:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="uuid:e3dc07b9-c583-461e-80ee-69a9cd39e596" xmlns:tcmi="http://www.tridion.com/ContentManager/5.0/Instance" elementFormDefault="qualified" targetNamespace="uuid:e3dc07b9-c583-461e-80ee-69a9cd39e596">   <xsd:import namespace="http://www.tridion.com/ContentManager/5.0/Instance" schemaLocation="cm_xml_inst.xsd"></xsd:import>   <xsd:annotation>
    <xsd:appinfo>
      <tcm:Labels xmlns:tcm="http://www.tridion.com/ContentManager/5.0">
        <tcm:Label ElementName="body" Metadata="false">body</tcm:Label>
      </tcm:Labels>
    </xsd:appinfo>   </xsd:annotation>   <xsd:element name="Content">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="body" minOccurs="1" maxOccurs="unbounded" type="tcmi:XHTML">
          <xsd:annotation>
            <xsd:appinfo>
              <tcm:ExtensionXml xmlns:tcm="http://www.tridion.com/ContentManager/5.0"></tcm:ExtensionXml>
              <tcm:Size xmlns:tcm="http://www.tridion.com/ContentManager/5.0">10</tcm:Size>
              <tcm:FilterXSLT xmlns:tcm="http://www.tridion.com/ContentManager/5.0">
                <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml" version="1.0">
                  <output omit-xml-declaration="yes" method="xml" cdata-section-elements="script"></output>
                  <template match="/ | node() | @*">
                    <copy>
                      <apply-templates select="node() | @*"></apply-templates>
                    </copy>
                  </template>
                  <!-- Convert Youtube and Xstream links into embedded iframes -->
                  <template match="a">
                    <element name="html:div">
                      <attribute name="class">video-container</attribute>
                      <element name="iframe">
                        <attribute name="width">695</attribute>
                        <attribute name="height">391</attribute>
                        <attribute name="src">
                          <text>http://www.youtube.com/embed/ero44g6ocCc</text>
                        </attribute>
                        <attribute name="frameborder">0</attribute>
                        <attribute name="allowfullscreen">true</attribute>
                      </element>
                    </element>
                  </template>
                  <!-- End of Youtube and Xstream block -->
                  <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()])       )])     ]">
                    <!-- ignore all paragraphs and line-breaks at the end that have nothing but (non-breaking) spaces and line breaks -->
                  </template>
                  <template match="br[parent::div and not(preceding-sibling::node()) and not(following-sibling::node())]">
                    <!-- Chrome generates <div><br/></div>. Renders differently in different browsers. Replace it with a non-breaking space -->
                    <text> </text>
                  </template>
                  <template name="FormattingFeatures">
                    <FormattingFeatures xmlns="http://www.tridion.com/ContentManager/5.2/FormatArea">
                      <Doctype>Transitional</Doctype>
                      <AccessibilityLevel>0</AccessibilityLevel>
                      <DisallowedActions></DisallowedActions>
                      <DisallowedStyles></DisallowedStyles>
                    </FormattingFeatures>
                  </template>
                </stylesheet>
              </tcm:FilterXSLT>
            </xsd:appinfo>
          </xsd:annotation>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>   </xsd:element> </xsd:schema>

I'm running Tridion 2013.

2
  • Is this a migrated schema? Your XSLT seems to be missing the XSL prefixes. Commented May 6, 2013 at 12:29
  • Nope, newly created.
    – Xyslarda
    Commented May 6, 2013 at 12:56

3 Answers 3

3

As Chris points out, your XSL elements are missing the prefix. I think he's right to think this is a migration problem. What this means is that when you're creating the div, the namespace is that of XSL.

To fix this, I'd suggest returning to the more normal situation, where XSL elements use a prefix to reference their namespace, and set the default namespace to the XHTML namespace.

Alternatively (but I think this is messier) you could leave the general structure as is, and use the html prefix on the div...

<element name="html:div">...

Note: in your example, you have the html namespace declared at the top.

3
  • Ah, sorry. That xmlns:html-atribute on the stylesheet-tag was added by me manually. I was trying what you just proposed :-) But that didn't work either, it didn't output anything at all.
    – Xyslarda
    Commented May 6, 2013 at 13:07
  • You need to put your "match" expressions in the right namespace too. Commented May 6, 2013 at 14:04
  • Thanks Dominic. It worked when I prefixed the xsl tags and then set the standard namespace to xhtml. Then I also didn't have to use <element name="iframe"> but could only use <iframe>.
    – Xyslarda
    Commented May 7, 2013 at 7:41
2

Try writing <xhtml:div class="video-container">.... instead of creating the element. Not sure it will make a difference

2
  • How do you mean writing? If you mean writing out the tag explicitly, it doesn't work (at least not for me). See tridion.stackexchange.com/questions/1068/…
    – Xyslarda
    Commented May 6, 2013 at 12:55
  • sorry, formatting got messed up and hid my tag. Make sure to add the XHTML namespace at the to of your XSLT also. Commented May 6, 2013 at 18:08
1

Your filtering XSLT looks like

You got the schema Item XML and then copied tcm:FilterXSLT part and pasted on the question.

with this, we may see some more extra content. Best way is to open schema, go to Filtering XSLT tab and then copy the XSLT and paste on the question.

Apart from this, your Filter XSLT should be

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output omit-xml-declaration="yes" method="xml" cdata-section-elements="script"/>
    <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()])       )])     ]">
        <!-- ignore all paragraphs and line-breaks at the end that have nothing but (non-breaking) spaces and line breaks -->
    </template>
    <template match="br[parent::div and not(preceding-sibling::node()) and not(following-sibling::node())]">
        <!-- Chrome generates <div><br/></div>. Renders differently in different browsers. Replace it with a non-breaking space -->
        <text> </text>
    </template>
    <!-- Custom block that should convert a link into an iframe wrapped with a div -->
    <template match="a">
        <element name="div">
            <attribute name="class">
                <value-of select="'video-container'"></value-of>
            </attribute>
            <element name="iframe">
                <attribute name="width">
                    <value-of select="'695'"></value-of>
                </attribute>
                <attribute name="height">
                    <value-of select="'391'"></value-of>
                </attribute>
                <attribute name="src">
                    <value-of select="'http://www.youtube.com/embed/ero44g6ocCc'"></value-of>
                </attribute>
            </element>
        </element>
    </template>
    <!-- End of custom block -->
</stylesheet>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.