Re: Sequentially processing XSL on an XML-File

Subject: Re: Sequentially processing XSL on an XML-File
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 20 Nov 2000 17:14:49 +0000

> 1. I want to transform an xml file "a.xml" to an xml-file
> "final.xml". In order to achieve the wanted result, somehow I have
> to use two xsl-stylesheets. The first to generate a redundant
> "b.xml" file. Then process this "b.xml" file to the "final.xml"
> file.
> How can I transform the "a.xml" file to the "final.xml" within one
> single style sheet using the two former ones? (So I could save a
> processing-step....) Is that possible at all? Is it possible to run
> another instance of the xsl-processor (xalan here) from the
> stylesheet?

It's not possible to run another instance of the XSLT Processor from
the stylesheet.

It is usually possible to create a stylesheet that does a
transformation in one go, but this depends on how complicated the
transformation is between a.xml and final.xml and I guess that since
you're going through an intermediary step, that's probably the best
way to approach your problem anyway.

It is always possible to create a stylesheet that does two separate
transformation steps, as long as you are prepared to use the node-set
function that's available as an extension in most XSLT Processors (and
will be in XSLT1.1 when it comes).  I forget what Xalan calls its
version, but I think it's xalan:nodelist() and it will be in the Xalan
documentation somewhere.

To use it, add modes to all your un-named templates, one mode for the
templates from the first stylesheet (say, 'a'), and one mode for the
templates in the second stylesheet (say, 'b'). This is to prevent
clashes between the templates in your first and second stylesheets.

Then create a master stylesheet that includes them both:

<xsl:include select="a.xsl" />
<xsl:include select="b.xsl" />

Create a master template that manages the entire process (matching on
the root node of the source):

<xsl:template match="/">

Within it, first create a variable in place of b.xml:

  <xsl:variable name="b-rtf">
    <xsl:apply-templates select="/" mode="a" />

This sets the variable b-rtf to hold the result of applying the
templates from the first stylesheet to the source XML.  Then you want
to apply the templates from the second stylesheet to the result of
this variable:

  <xsl:apply-templates select="xalan:nodelist($b-rtf)" mode="b" />

If you're not prepared to use the extension function, or if you don't
want to make any changes to your two stylesheets, then you can always
create a little script (a .bat file or whatever) to run the two
processes one after the other.  For Saxon, for example, I'd do:

--- transform.bat ---
saxon -o b.xml a.xml a.xsl
saxon -o final.xml b.xml b.xsl

and then just run 'transform.bat' to do both transformations.
> 2. I created a dtd for generating an xml-file, that should contain some
> functionality data to do some kind of processing in an xml-file (i.e. tag
> identifiers, what has to be done, how etc.). I want to include this data in a
> style sheet. How can I do that? 

I'm not exactly sure what you mean by this.  Do you mean that you've
created a DTD for the output that you get in final.xml and you want to
make sure that final.xml references that DTD?  If so, you're after the
'doctype-system' attribute on the xsl:output element:

<xsl:output doctype-system="final.dtd" />

Do you mean that the source XML has a DTD and you want to use some
information from it to help process the XML?  Your XSLT Processor will
usually read the DTD if you've referenced it from the source XML and
use it for default values for attributes and things like that.  Check
Xalan's documentation to see if there are any switches to turn this
validation process on or off.

Or do you mean that you've created a language for specifying how to
transform the source XML into the final output XML that you want, and
that you have a file with that specification in that you want the
XSLT stylesheet to use to do the transformation?  If that's the case,
you can access it through the document() function and then apply
templates to it or whatever.  If this *is* what you're talking about,
and you need specific help, you should probably post with more details
about what you're trying to achieve with it.

If you meant something else entirely, please clarify what it was :)

I hope that helps anyway,


Jeni Tennison

 XSL-List info and archive:

Current Thread