Is document() support in Chrome and Firefox on the roadmap? My stylesheets need it.

I have a set of existing stylesheets used within the Xopus editing process which display the target text of hyperlinks via XSLT functions which use document() functions and match to <xsl:key> definitions. The stylesheets are complex and extensive, and they work.

At least, they work in Xopus under IE. Not in Chrome or Firefox.

The Xopus 5.4 documentation has a simple XInclude example which suggests that I could re-implement these stylesheets using Xincludes and xpointers, but I'm not having much luck.

I'm either after a commitment from Xopus to support document() in these other browsers, or a demonstrable example of how to implement my requirement without using document() and xsl:key.

  • I've been experimenting with a simpler example than my actual requirement but it still isn't working.

    I've created an XML document "globvars.xml" which contains a simple structure like so:

    <?xml version="1.0"?>
    <globals>
      <date id="globaldate">Wed Sep 12 22:00:30 NZST 2018</date>
      <server id="globalserver">fergus</server>
      <version id="globalversion">testing 10659M</version>
    </globals>

    The document I wish to edit in Xopus can reference these like so:

    <para>This application was built on <global name="server"/> on <global name="date"/> using source version <global name="version"/>.</para>

    Under IE I can edit this file with a simple single-transform pipeline, where the rendering XSL ("docs_edit.xsl") contains the equivalent of:

    <xsl:template match="global">
      <span class="meta-global">
        <xsl:choose>
          <xsl:when test="@name = 'date'">
            <xsl:value-of select="document('globvars.xml')/globals/date"/>
          </xsl:when>
        <!-- etc. -->
        </xsl:choose>
      </span>
    </xsl:template>

    If I attempt to edit this file in Xopus through Chrome or Firefox I get the error "Failed to compile stylesheet: The document() function in XSLT is only supported in Internet Explorer."

    After carefully reading the online documentation I made a few modifications. I changed the Xopus pipeline to this:

    <x:pipeline xsd="docs_edit.xsd">
      <x:view name="WYSIWYG">
        <x:transform xsl="preparexi.xsl"/>
        <x:resolveXIncludes/>
        <x:transform xsl="docs_edit.xsl"/>
      </x:view>
    </x:pipeline>

    where "prepare.xi" is trivial, the guts of it are:

    <xsl:template match="global">
      <xi:include href="globvars.xml">
        <xsl:attribute name="xpointer">
          <xsl:text>id(&quot;global</xsl:text>
          <xsl:value-of select="@name"/>
          <xsl:text>&quot;)</xsl:text>
        </xsl:attribute>
      </xi:include>
    </xsl:template>

    This inserts nothing. None of the normal xpointer options: id(), element() etc. work.

  • I managed to have xi:include work with Xopus in my case.

    Two gotchas :

    - don't forget <xi:fallback> in your "preparexi.xsl" to see what's gone wrong

     eg : <xi:include href="{$path}">

        <xi:fallback>Not found : <xsl:value-of select="$path"/></xi:fallback>

    - don't forget a presentation for the imported data, in your "docs_edit.xsl"

     eg : in my case to see imported tables , I had to add

     <xsl:template match="table|colgroup|col|tbody|tr|td|th">

       <xsl:element name="{local-name()}">

         <xsl:copy-of select="@*"/>

         <xsl:apply-templates select="node()"/>

       </xsl:element>

     </xsl:template>

    Should your <xi:include> spit <span class="meta-global"> or just <global>...</global> ?

    All I can figure is your XSL "preparexi.xsl" giving part of "globvars.xml" which may not be displayed by your "docs_edit.xsl".

    Rémi

  • My bad in transcribing my test example. Because I have several possible substitutions they're encoded in a named template and I just moved one of the alternatives inline. The actual templates are:

    <xsl:template match="global">
      <global>
        <xsl:call-template name="global_sub">
          <xsl:with-param name="varname" select="@name"/>
        </xsl:call-template>
      </global>
    </xsl:template>

    <xsl:template name="global_sub">
      <xsl:param name="varname"/>
      <xi:include href="globvars.xml">
    <!--
        <xsl:attribute name="xpointer">
          <xsl:text>id(&quot;global</xsl:text>
          <xsl:value-of select="$varname"/>
          <xsl:text>&quot;)</xsl:text>
        </xsl:attribute>
    -->
      </xi:include>
    </xsl:template>

    With or without the attribute included, and whether the attribute is id() or element() or just some XPath, the global element emerging from the pipeline is empty.

  • Interesting...

    I added a fallback to the template:

    <xi:include href="globvars.xml">
      <xi:fallback><xsl:text>Not found</xsl:text></xi:fallback>
    </xi:include>

    and "Not found" appears in the <global> element emerging from the transform.

    In IE, document("globvars.xml") retrieves the document. In both IE and Chrome, xi:include("globvars.xml") does not. The globvars XML file is in the same directory as the pipeline stylesheets and schema, although not in the same directory as the XML file being edited via the pipeline. Perhaps that is significant, although it seems to me that both should resolve the same way.

  • And even more interesting... when I supply the full path from root as the href property

    <xi:include href="/home/trevor/..etc../globvars.xml">

    it still fails to find the document. The path is correct, because document("/home/trevor/..etc../globvars.xml") succeeds (just in IE, of course).

    Yet you have this working? Where are your files accessed from?

  • No we're getting somewhere! Instead of the full path from /home I hardcoded a relative path from the XML file I'm editing for my test.

    <xi:include href="../../editing/globvars.xml">

    This actually succeeds in sucking in all the content of the globvars page. Why a relative path works and an absolute path does not I will have to leave to a true guru to explain.

    Unfortunately the entire globvars page is extensive, and each reference to it needs to be pruned down to the specific element identified by the global name property, hence (to get the version from <global name="version"/>):

    <xi:include href="relative/path/to/globvars.inc">
      <xsl:attribute name="xpointer">
        <xsl:text>id(&quot;globalversion&quot;)</xsl:text>
      </xsl:attribute>
    </xi:include>

    When I try this Xopus displays the error

    No XSL output. Try Internet Explorer for better error messages.  /path/to/preparexi.xsl

    That's not actually very helpful, because when I try it in IE there is no error at all (and the xpointer attribute is completely ignored).