tags:

views:

48

answers:

3

I have written an xslt that reads some xml file names and does some operations on them.
I use a for-each to work them one-by-one. I have each path inside a parameter $path.

But now I would like to output the result of applying an external stylesheet to those files. I would write something like

<div> <something like xsl-transform($extern-xslt,$path)> </div>

to have the result tree of the transformation inside the main html output. It is possible?

+1  A: 

You can use the document() XPath function to load an external XML file. This returns a node-set which can be parsed with a <xml:apply-templates> call. Including an external stylesheet can be accomplished by using an <xsl:include> tag.

<xsl:include href="$external"/>
<xsl:apply-templates select="document($path)"/>

See also the documentation for document()

Rodin
+2  A: 

You could import the external stylesheet to your main stylesheet with xsl:import, and then just apply templates to that external XML file, which you can load with the document function.

<div><xsl:apply-templates select="document($path)"/></div>

If the templates in the external stylesheet would collide with the templates in the main stylesheet, you can use a different mode for them.

Jukka Matilainen
A: 

I have written an xslt that reads some xml file names and does some operations on them. I use a for-each to work them one-by-one. I have each path inside a parameter $path.

But now I would like to output the result of applying an external stylesheet to those files

The solution consists of these ingredients:

  1. Use the standard XSLT document() function to load and access the external XML document.

  2. Import the external stylesheet, using an <xsl:import> instruction.

  3. The templates in the external stylesheet must be in a special mode, not used by the primary stylesheet.

  4. At the place where the result of the "external transformation" is wanted, issue <xsl:apply-templates> selecting the necessary nodes of the external document (usually the root node /, or the top element /*). The mode, specified on the <xsl:apply-templates> should be the same as the mode used in the external stylesheet.

Here is a small, simplified example (No external stylesheet is imported, the "external document" is embedded in the stylesheet, and no mode is used):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:my="my:my"
>
<!--  <xsl:import href="myExternal.xsl"/> -->
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <my:div>
      <h2>Weather</h2>
      <p >It will be raining today</p>
    </my:div>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="insertContents">
   <xsl:apply-templates select="document('')/*/my:div/*"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on this XML document:

<html>
  <h1>Today's News </h1>
  <insertContents/>
</html>

the desired result is produced:

<html>

   <h1>Today's News </h1>

   <h2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="my:my">Weather</h2>
   <p xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="my:my">It will be raining today</p>

</html>

Note that the extraneous namespaces above are only due to the simplifications of this example -- they will not be generated if the external XML document were in its own file.

Dimitre Novatchev