0

I put a javascript function in my xsl file. This function must be called whenever onclick event is fired.

<script type= "text/javascript">
    <xsl:text>
        function embeddedPreview(source) {
            if($("#embed").length > 0) {
            //set the source to the location asked for
                $("#embed").attr("src", source);
            } else {
                //Create the embed iframe
                $("#preview-embed").append("<iframe id='embed' src='"+source+"' width='100%' height='342px' style='border:none;'/>");         //requires jQuery
            }
        }
    </xsl:text>
</script>

When I run this, an error below occurs pointing to Line 9.

javax.xml.transform.TransformerException: iframe is not allowed in this position in the stylesheet!

Below is a part of my xsl file where iframe must be appended, particularly in div with an id of "preview-embed".

What does it mean? Does div is not allowed to be appended with an iframe? Please help me.

Tomalak
  • 332,285
  • 67
  • 532
  • 628

3 Answers3

1

In DSpace XMLUI, I believe that this is the official way to include jQuery. In your theme's sitemap.xmap file, add the loadJQuery line shown below. This approach has the benefit of only including jQuery when it will be used.

        <map:match pattern="**">

            <!-- Step 1: Generate the DRI page -->
            <map:generate type="file" src="cocoon://DRI/{1}"/>

            <!-- Step 2 Add page metadata -->
            <map:select type="browser">
                <!-- Internet explorer 6 -->
                <map:when test="explorer6">
                    <map:transform type="IncludePageMeta">
                        <map:parameter name="stylesheet.screen#1" value="lib/style.css"/>
                        <map:parameter name="stylesheet.screen#2" value="lib/style-ie6.css"/>

                        <map:parameter name="theme.path" value="{global:theme-path}"/>
                        <map:parameter name="theme.name" value="{global:theme-name}"/>
                    </map:transform>
                </map:when>
                <!-- The theme has been tested with firefox 2.0 & i.e. 7.0 -->
                <map:otherwise>
                    <map:transform type="IncludePageMeta">
                        <map:parameter name="stylesheet.screen" value="lib/style.css"/>

                        <map:parameter name="javascript#1" value="../../loadJQuery.js"/>
                        <map:parameter name="javascript#2" value="lib/gu-custom.js"/>
                        <map:parameter name="javascript#3" value="../mobile/lib/cookies.js"/>
                        <map:parameter name="javascript#4" value="../mobile/lib/detectmobile.js"/>

                        <map:parameter name="theme.path" value="{global:theme-path}"/>
                        <map:parameter name="theme.name" value="{global:theme-name}"/>
                    </map:transform>
                </map:otherwise>
            </map:select>

I found that in some instances, jQuery was not loaded when I needed it to be loaded. Rather than including jQuery using mechanism above, I overrode the XMLUI template that builds the html head block and put an explicit call to jQuery there.

<xsl:template name="buildHead">
    <head>
        ...
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">&#160;</script>
        ...
    </head>
</xsl:template>

The template that I overrode exists here: https://github.com/DSpace/DSpace/blob/master/dspace-xmlui/src/main/webapp/themes/dri2xhtml/structural.xsl#L152

terrywb
  • 3,740
  • 3
  • 25
  • 50
0

In fact your XSL considers <iframe to be the beginning of a tag, which is not well-formed. You should use the following:

 <xsl:text disable-output-escaping="yes">
     function embeddedPreview(source) {
         if($("#embed").length > 0) {
         //set the source to the location asked for
             $("#embed").attr("src", source);
         } else {
             //Create the embed iframe
            $("#preview-embed").append("&lt;iframe id='embed' src='"+source+"' width='100%' height='342px' style='border:none;'/>");         //requires jQuery
        }
    }
</xsl:text>

However the error message is a bit weird... Which XSL-T processor do your use? Where is you template located?

potame
  • 7,597
  • 4
  • 26
  • 33
0

Your XSL stylesheet has to be a well-formed XML document and a valid XSLT document.

The <xsl:text> element cannot contain other elements(*) - and from the perspective of the XSL processor, <iframe /> is an element, it doesn't care that it sits in a JavaScript string, because the XSL processor simply doesn't know anything about JS.

(*)The spec: http://www.w3.org/TR/xslt#element-text states that <xsl:text> may only contain #PCDATA.


So your document might be well-formed XML, but it isn't valid XSLT. What you probably wanted to use is a CDATA section:

<xsl:template match="foo">
  <script type="text/javascript"><![CDATA[
    function embeddedPreview(source) {
        if($("#embed").length > 0) {
            //set the source to the location asked for
            $("#embed").attr("src", source);
        } else {
            //Create the embed iframe
            $("#preview-embed").append("<iframe id='embed' src='"+source+"' width='100%' height='342px' style='border:none;'/>");
        }
   }
]]></script>
</xsl:template>

But what you actually should to do is move all JavaScript code to an external JS file.

<xsl:template match="foo">
  <script type="text/javascript" src="preview.js"></script>
</xsl:template>
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • I followed what you've said about the CDATA stuff, the errors gone but tells that the function "embeddedPreview" is not defined. What shall I do? –  Jan 20 '15 at 02:06
  • Well, that sounds like your XSLT problem is solved. Javascript problems were not really part of your question, but the logical thing to do would be to look into the produced HTML source code. Is it there? – Tomalak Jan 20 '15 at 06:05
  • When I inspect element the "preview" link, I saw that the function embeddedPreview was called when an onclick event fires. It was looking for a javascript function when in fact I already embedded it in the xsl file. –  Jan 20 '15 at 06:11
  • Your answer is somewhat related to this article http://support.microsoft.com/kb/273793 . Im trying this out, hoping it will work out soon. –  Jan 20 '15 at 06:13