XSLT in MSXML
Go to Page: 1 | 2
|
Author:
|
Stuart Celarier, Fern Creek Corporation
Stuart Celarier is a software consultant and instructor in Portland, Oregon, focusing
on .NET, XML, Web Services, COM, C++ and C#. You can reach Stuart at
stuart@ferncrk.com
or through his web site
www.ferncrk.com.
Copyright © 2002, Stuart Celarier, Fern Creek Corporation. All rights reserved.
|
|
Article Date:
|
May 2002
|
|
Abstract:
|
Microsoft introduced full XSLT 1.0 support in MSXML 3.0.
However, earlier versions of MSXML are not XSLT 1.0 conformant (far from it)
but instead support an early draft of XSLT known as WD-xsl.
Even if you have the most recent MSXML 4.0 version installed,
you may get a nonconforming version of XSLT by default. It all
depends on both what versions of MSXML you have installed and how they are configured.
This article explains this situation and how to utilize the XSLT 1.0 conformant processor
in MSXML. It also examines the advanced classes that make XSLT efficient to use in
ASP applications and middle tier technology.
|
|
Audience:
|
This article
assumes that you are familiar with XSLT, HTML and JavaScript.
Visual Basic, C++ and COM are briefly used in a few examples.
|
|
Source code:
|
The source code accompanying this article can be downloaded from
http://www.perfectxml.com/downloads/XsltInMsxml.zip.
|
|
Demo:
|
Click here to see the demo (requires MSXML 4.0 on the client side).
|
The state of XSLT in MSXML
In order to discuss how the MSXML relates to the XSLT specification,
let's begin with a quick introduction to the development of specifications at the W3C.
Where to W3C specifications come from?
The World Wide Web Consortium (W3C) develops a majority of
specifications that comprise the World Wide Web and make it increasingly more
useful, including the specifications for HTML, XML, XSLT, and many more. The
W3C uses an established process for creating specifications.
W3C specifications are initially published as Working Drafts which are,
in the words of the W3C ,
...submitted for review by W3C
Members and other interested parties. These are draft documents and may be
updated, replaced or obsoleted by other documents at
any time. It is inappropriate to use W3C working drafts as reference material
or to cite them as other than “work in progress”.
After a successful Working Draft specification has received
"significant technical review” within the W3C, it is
promoted to a Candidate Recommendation
which is a call for implementation and technical feedback from the public. Following
that, a specification can become a Proposed
Recommendation indicating that the W3C group that working on the
specification have reached consensus and the W3C Director has proposed it for
review by the W3C Advisory Committee.
Once review of the Proposed Recommendation is complete, the
specification can finally become a W3C Recommendation.
Again quoting the W3C,
a Recommendation
...represents consensus within W3C and has the Director’s
stamp of approval. W3C considers that the ideas or technology specified by a
Recommendation are appropriate for widespread deployment and promote W3C's
mission.
In essence, only a Recommendation is the final
specification, everything else is a work in progress.
WD-xsl and XSLT 1.0 conformant processors
Now we can understand a very important point. The XSLT
technology in MSXML prior to MSXML 3.0 is based on one of the Working Draft
versions of the XSLT 1.0 specification. MSXML 3.0 was the first release to have
an XSLT conformant processor based on the XSLT 1.0 Recommendation. MSXML 4.0 further
improves in that regard and contineous to provide 100% XSLT 1.0 conformant processor.
The XSLT technology is so compelling that Microsoft chose to
become an early adopter of it, releasing it to developers even while XSLT was
still changing. And XSLT changed a lot before it final XSLT 1.0 Recommendation
was published.
It is easy to identify XSLT stylesheets written to the XSLT 1.0
Recommendation, as they use XML elements in the namespace
http://www.w3.org/1999/XSL/Transform.
The document (or root) element of an XSLT 1.0 stylesheet is generally written
like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"/>
On the other hand, Microsoft's XSLT processors prior to
MSXML 4.0 use a different XML namespace for their elements, so that the
document element of an XSLT stylesheet based on an XSLT Working Draft is
written like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"/>
For this reason, this is often called the WD-xsl version or Working Draft version of XSLT.
It needs to be emphasized that WD-xsl is not XSLT 1.0, not even close.
The XSLT specification, as well as the XPath specification on which it depends, changed a lot
between the version of the Working Draft that Microsoft used for WS-xsl
and the final Recommendation.
WD-xsl and XSLT 1.0 must be considered completely separate
languages, and I strongly advise you to consider WD-xsl
as a temporary solution which is now obsolete.
MSXML 3.0 has support for both the XSLT 1.0 recommendation and WD-xsl.
It selects which technology to use depending on the namespace used for the XSLT elements.
With MSXML 4.0 Microsoft dropped support for WD-xsl. If you try to
use the WD-xsl (http://www.w3.org/TR/WD-xsl) with MSXML 4.0 XSLT processor, you'll get an error
-2147467259 The "http://www.w3.org/TR/WD-xsl" namespace is no longer supported in this version of MSXML.
In case you have previously developed WD-xsl stylesheets,
your friends in Redmond have provided an conversion utility called
XSL to XSLT Converter 1.1
which is available for download from the MSDN web site.
The devil is in the details
That doesn’t seem so bad, we can all just use the XSLT 1.0 conformant processor from MSXML 3.0 or 4.0 and code happily ever after, right? Well, it is a little more complicated than that. A good deal depends on which versions of MSXML are installed and how they are configured.
In releases of MSXML prior to MSXML 4.0 you had a option to install MSXML in side-by-side or replace mode (via the XmlInst.exe utility). Installing a version of MSXML in replace mode involved configuration in the registry making that version be the default one for XML services. However it is not possible to install MSXML 4.0 to be the default XML technology, there is no replacement mode install any more.
What this means is that the only way you can make a XSLT 1.0 conformant processor be the default processor used by Windows is to have MSXML 3.0 installed in replacement mode. Otherwise, even if you have MSXML 4.0 installed, by default you will get a WD-xsl processor. And we just learned that WD-xsl is not XSLT 1.0.
In a moment we’ll look at what the term 'default' really
means and how to invoke the specific version of the XSLT processor that we
want. But first let’s figure out what versions of MSXML are installed on your system.
Microsoft provides MSXML as a free downloadable component (see
http://msdn.microsoft.com/xml), and
it also is included with recent versions of Internet Explorer. Specifically, IE
5.5 includes MSXML 2.0 and IE 6.0 includes MSXML 3.0. Separately, MSXML 2.6 was
also available for download. Depending on what you’ve installed you may have
one, two or all three of these versions of MSXML on your computer, and any one
of them may be the default version.
(By the way, if you need technical information on different versions of MSXML, their filenames, file version numbers and tracking down what products they were included in, check the Notes section near the bottom of the MSXML 3.0 SP1 .cab File Redistribution Package article on the MSDN web site. This is the most complete information I've found, and it seems to correct a few slight misstatements elsewhere in the Microsoft literature.)
If you want to find out which versions of MSXML are
installed on your system, fire up the RegEdit utility and navigate to the
HKEY_CLASSES_ROOT\Msxml2.DOMDocument entry. Mxsml2.DOMDocument is the version-independent
name of the COM class for the XML DOM in MSXML. Just below that entry you
should see one or more version-dependent COM class names such as
Msxml2.DOMDocument.2.6 and so forth, a different one for each version of MSXML
installed.
From Figure 1 you can see that I have MSXML 2.6, 3.0 and
4.0 installed on my computer, and from the value of the Msxml2.DOMDocument\CurVer key you can
tell that MSXML 3.0 is the default (version independent) one. When I drag an
XML file and drop it on Internet Explorer on my system it is displayed using
MSXML 3.0.
The fundamental reason why MSXML 4.0 cannot be made to be
the default is that Microsoft removed the version independent GUIDs and PROGIDs
in MSXML 4.0. If you would like more information about the reasons
for this and the implications of it, consult the MSDN Library article
XML Web Services / XML Core / MSXML / SDK Documentation / Microsoft
XML Core Services (MSXML) 4.0 / GUID and ProgID Information.
Sidebar: default XSLT styling in Internet Explorer
By the way, when Internet Explorer displays an XML file, it
is actually styling it with IE's default XSLT stylesheet. The default XSLT
stylesheet transforms arbitrary XML into a Dynamic HTML (DHTML) document which provides
fonts and colors and allows you to expand and collapse elements as shown in Figure 2.
This default stylesheet
is a resource in the MSXML DLL which is identified by the URN
res://msxml.dll/DEFAULTSS.xsl or res://msxml3.dll/DEFAULTSS.xsl.
You can view that document in Internet Explorer, too, and with all the
<xsl:template>
elements collapsed it looks like Figure 3
(notice the WD-xsl namespace).
If you are interested in this stylesheet, you probably want
to obtain a copy that has been converted to XSLT 1.0. Steve Muench, coeditor
for the W3C's requirements specifications for XSLT 2.0 and XPath 2.0, posted
one to the XSL-List Forum and archived at
http://www.biglist.com/lists/xsl-list/archives/200003/msg00769.html.
This has been tested on a variety of other XSLT processors for compatibility.
You can visit the XSL-List Forum and subscribe to the
mailing list at
http://www.mulberrytech.com/xsl/xsl-list/.
It is an incredible resource for both XSL and XSLT programming. One word of
warning, if you ask a WD-xsl question there you will no doubt be advised to change to XSLT 1.0 technology.
They've grown tired of saying it time and again. And, as always, please lurk before you leap.
Invoking the MSXML XSLT 1.0 processor
Now that we are thoroughly familiar with which versions of
MSXML may be installed on a computer and why the nonconforming WD-xsl processor
is used by default, let's turn our attention to using the XSLT 1.0 processor in
MSXML 3.0 and 4.0.
If you have the option, you would probably prefer to use the MSXML 4.0 XSLT processor over the 3.0 version. From a performance standpoint, the XSLT processor in MSXML 4.0 clocks in at about four times faster than its predecessor, eight times faster in some scenarios. Additionally, since MSXML 4.0 dropped support for WD-xsl, making explicit use of MSXML 4.0 will help ferret out any obsolete WD-xsl stylesheets early in the development process.
With XSLT 1.0 processors available in both MSXML 3.0 and 4.0, for the rest of this article we'll talk about using the latest, greatest MSXML 4.0 unless otherwise stated. This will help simplify the discussion, and in most cases you will be able to see immediately how to work with MSXML 3.0 if you'd like.
Generally there are three ways to invoke an XSLT processor:
using a distinguished XML processing instruction in the source document, from
the command line, or programmatically using an API call. Let's examine each of
these in turn and they can or can't be used to invoke MSXML 4.0's XSLT 1.0
processor.
The xml-stylesheet processing instruction
There is a short W3C Recommendation specification called
Associating Style Sheets with XML Documents
which defines an XML processing instruction (PI) that can be embedded in an XML
document to indicate one or more stylesheets to use when displaying the
document in a browser. The stylesheets could be cascading style sheets (CSS),
XSLT stylesheets and potentially other types as well. Typical xml-stylesheet
processing instructions look like this:
<?xml-stylesheet type="text/xsl" href="book.xsl"?>
<?xml-stylesheet type="text/css" href="ferncrk.css"?>
The first PI says to apply the XSLT stylesheet named
book.xsl, and the second says to then apply the CSS stylesheet named
ferncrk.css. While the PI allows the document to specify what stylesheet to
apply, it does not allow it to specify which XSLT processor to use. As a
result, Internet Explorer will use the default MSXML processor, which is a
WD-xsl processor. Conclusion: we can't use the xml-stylesheet PI to invoke an
XSLT 1.0 conformant processor.
In my opinion this is no great loss. Think about when you have
two applications, a server that produces XML data and a client that consumes
XML data, but the server and client use different data models. Historically we
might have provided an Export As... feature in the server to produce
client-compatible data, or an Import As... feature in the client so that it can
consume server-produced data. Of course the problem with this approach is that
it links the server and client software, so that a change in one (e.g.,
extending the data model) may require a corresponding change in the other. If
we instead use XSLT to abstract the transformation process, that is a separate activity
belonging to neither application, then the server and client remain uncoupled.
Uncoupling the server and client is especially important when one server has multiple
clients or visa versa.
But an xsl-stylesheet processing instruction embedded in the
XML document implies that the server must know which client is consuming the
data in order to select the correct stylesheet when it writes the data. From
this perspective, the xsl-stylesheet processing instruction looks like it is
explicitly linking server and client again, so it really is of limited use.
What's more, the XML crowd has been turning away from
processing instructions (see Aaron Skonnard's
XML Files
column in the May 2002 issue MSDN Magazine,
"Q: Are there any standard PIs in XML?")
and the xsl-stylesheet is the only processing
instruction that has been specified to date.
The msxsl command
The second way to invoke an XSLT processor is from the
command line. The W3C specification does not specify a command line syntax, so
it is left to each vendor to provide its own. In order to use the MSXML 4.0
processor from the command line you need to download and install the
MSXSL.EXE Command Line Transformation Utility from MSDN Downloads.
This is not included in the MSXML 4.0 download.
Running the msxsl -? command
displays the command line syntax shown here.
c:\>msxsl -?
Microsoft (R) XSLT Processor Version 4.0
Usage: MSXSL source stylesheet [options] [param=value...] [xmlns:prefix=uri...]
Options:
-? Show this message
-o filename Write output to named file
-m startMode Start the transform in this mode
-xw Strip non-significant whitespace from source and stylesheet
-xe Do not resolve external definitions during parse phase
-v Validate documents during parse phase
-t Show load and transformation timings
-pi Get stylesheet URL from xml-stylesheet PI in source document
-u version Use a specific version of MSXML: '2.6', '3.0', '4.0'
- Dash used as source argument loads XML from stdin
- Dash used as stylesheet argument loads XSL from stdin
Note that by default this command does not validate the source
or stylesheet documents, use the -v flag when validation
is required. The -m flag allows you to specify the
starting mode for the transformation, this corresponds to the mode
attributes on <xsl:template>
and <xsl:apply-templates> elements in the
stylesheet (see the section on modes
in the XSLT specification for more information).
The msxsl command is handy for batch processing. But you
should be aware that on each invocation it must parse (and validate if
specified) both the source document and the stylesheet. If you are performing
many transformations using the same stylesheet, it will be advantageous to load
the stylesheet once and apply it to several source XML documents. To get more
control over the transformation process we look to programmatic
invocation.
Invoking MSXML XSLT from JavaScript
In MSXML 4.0 the XSLT processor is exposed in the XML DOM
object named Msxml2.DOMDocument.4.0. Here is a
sample HTML file that uses JavaScript to load a source and stylesheet document
and display the result in the body of the HTML page.
<html>
<head>
<title>Transform Sample</title>
<script language="javascript">
function init()
{
// load XML source document
var source = new ActiveXObject("Msxml2.DOMDocument.4.0");
source.async = false;
source.load("record49a36bde.xml");
// load XSLT stylesheet document
var stylesheet = new ActiveXObject("Msxml2.DOMDocument.4.0");
stylesheet.async = false;
stylesheet.load("detail_view.xsl");
// transform the source using the XSLT stylesheet
target.innerHTML = source.transformNode(stylesheet);
}
</script>
</head>
<body onload="init()">
<div id="target" />
</body>
</html>
When this page gets loaded, the onload
attribute of the <body> element calls the init
function which is defined in the <script> block.
The init function loads the source and
stylesheet documents, performs the XSLT transformation, and sets the results as
the HTML contained in the element identified with and id="target"
attribute. That element is the <div> element that
makes up the HTML body. Well, that much of what's
going on is mostly Dynamic HTML (DHTML). You can learn more about DHTML from
the MSDN Library under Web Development / HTML and Dynamic HTML.
Let's take a closer look at the script that loads the
documents and performs the transformation.
The init function begins with
a three step process to load the XML source document. First an XML DOM object
is created. By using the version dependent name for the ActiveX object, Msxml2.DOMDocument.4.0,
we are specifying the MSXML 4.0
services and the cherished XSLT 1.0 compliant processor. Second, the asynch
property of the XML DOM object is set to false,
specifying that XML documents cannot be loaded into the DOM asynchronously. In
our case, we require the entire document to be loaded before transformation can
begin. Third, the source document is loaded into the XML DOM object by calling
its load method.
This three step process is repeated to load the XSLT
stylesheet into another XML DOM object. Then the transformNode
method is called on the source XML DOM object, passing in the stylesheet XML
DOM object as a parameter. The result is a string containing the serialized
result of the transformation, and that string is set into the innerHTML property of the <div>
element, causing the result to be displayed on the page.
Now that we understand how to do a simple transformation
using JavaScript, let's examine performing XSLT transformations in other
languages.
Invoking MSXML XSLT from Visual Basic
Here is a sample transformation written in Visual Basic.
Dim source As New Msxml2.DOMDocument4
Dim stylesheet As New Msxml2.DOMDocument40
' Load XML source document
source.async = False
source.Load "record49a36bde.xml"
' Load XSLT stylesheet document
stylesheet.async = False
stylesheet.Load "text_view.xsl"
' Perform transformation
MsgBox source.transformNode(stylesheet)
Notice that this code is also written against the XML DOM
object, but here object is known by its Visual Basic class name: Msxsml2.DOMDocument40,
not Msxml2.DOMDocument.4.0.
Other than the name change, this code is very similar to the JavaScript
example.
Invoking MSXML XSLT from C++
Here is an equivalent example written in C++. Aside from all
the trappings of COM, this example is substantially the same as the JavaScript
and Visual Basic examples.
#include "msxml2.h"
// ...
// Assume that COM is already initialized with CoInitialize(Ex)
// Error checking and handling elided for clarity
// load XML source document
IXMLDOMDocument40 * pSource;
::CoCreateInstance(CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument40, (void**)&pSource);
pSource->put_async(VARIANT_FALSE);
pSource->load("record49a36bde.xml");
// load XSLT stylesheet document
IXMLDOMDocument40 * pStylesheet;
::CoCreateInstance(CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument40, (void**)& pStylesheet);
pStylesheet->put_async(VARIANT_FALSE);
pStylesheet->load("text_view.xml");
// perform transformation
BSTR result;
pSource->transformNode(pStylesheet, &result);
::MessageBox(NULL, result, "Transform Result", MB_OK);
::SysFreeString(result);
Getting an XSLT result as a DOM
The astute reader may have noticed that there is something
slightly amiss revealed by the previous C++ code example. The result of the transformation
is a BSTR. Other than being a most foul and heinous data type (really, don't
get me started), BSTR is, by definition, UTF-16 encoded. But MSXML 4.0 has
built-in support for several different encodings including UTF-8, UTF-16,
ISO-8859-1, and many others.
In order to fully support XML encoding, it is necessary to
use the transformNodeToObject method of the XML
DOM object. A call to transformNodeToObject takes
two parameters: a stylesheet as an IXMLDOMNode,
and a VARIANT containing an object to receive the
output of the transformation. If the VARIANT is
an XML DOM object, DOMDocument, then the
transformation result is placed in the DOM. Alternatively, the output
VARIANT can be an object with the IStream
interface, in which case the transformation result
is sent to the stream.
One of the benefits of outputting the transformation result
as an XML DOM object is that the resulting output can be used directly as input
for another transformation. Here is an scripting example that illustrates this
kind of chaining.
Dim source As New Msxml2.DOMDocument4
// load XML source document
var source = new ActiveXObject("Msxml2.DOMDocument.4.0");
source.async = false;
source.load("record49a36bde.xml");
// load first XSLT stylesheet
var ssExtract = new ActiveXObject("Msxml2.DOMDocument.4.0");
ssExtract.async = false;
ssExtract.load("extractFromRecord.xsl");
// load second XSLT stylesheet
var ssFormat = new ActiveXObject("Msxml2.DOMDocument.4.0");
ssFormat.async = false;
ssFormat.load("format.xsl");
// create first resulting DOM document
var result1 = new ActiveXObject("Msxml2.DOMDocument.4.0");
result1.async = false;
// create second resulting DOM document
var result2 = new ActiveXObject("Msxml2.DOMDocument.4.0");
result2.async = false;
// perform two-stage transformation
source.transformNodeToObject(ssExtract, result1);
result1.transformNodeToObject(ssFormat, result2);
// do something interesting with result2...
Here we've got one stylesheet that extracts data from a
record, and another stylesheet that formats extracted data. This factoring enables
us to reuse one or the other or both stylesheets in other situations.
In this example the result of the first transformation was
used as the source document for the second transformation. It is equally easy
to handle the case where we are transforming XSLT stylesheets themselves, so
that result of one transformation is used as the stylesheet for another
transformation. Pretty cool.
Advanced XSLT performance and functionality
For performance reasons, implementers of XSLT processors
usually architect their software so that it first compiles the stylesheet into
an executable format, and then applies that to the source document. This is the
case with the MSXML XSLT processor. However, when transformNode
or transformNodeToObject is used, the stylesheet is
compiled each time the method is called. That is simply inefficient and that
overhead can be prohibitive in a middle tier or server application where
performance is (almost) everything. That means that if you are developing
something like an ASP application using XSLT, you'll want to become familiar
with the XSLTemplate and XSLProcessor
objects.
The XSLTemplate object
provides a mechanism for caching a compiled stylesheet and then retrieving the
compiled stylesheet as an XSLProcessor object for
performing transformations. In addition, XSLProcessor
also exposes other XSLT functionality that is not available anywhere else in
the MSXML toolkit. Specifically, using an XSLProcessor
object we can specify processing modes and
pass parameters into a stylesheet. As an extensibility point, we can even also pass arbitrary
COM objects into a stylesheet using an XSLProcessor
object (see the section on extensions in the XSLT 1.0 specification).
The MSXML documentation in the MSDN Library is a bit of a
muddle providing reference for XSLTemplate and XSLProcessor.
It will help you to know that an XSLTemplate object is one that implements the IXSLTemplate
interface, and similarly an XSLProcessor object is an object that implements the IXSLProcessor interface.
You can find these interfaces
documented in the MSDN Library section XML and Web Services / XML Core / XML
General / SDK Documentation / Microsoft XML Core Services (MSXML) 4.0 / XML
Reference / XML Helper Object/Interfaces.
More information can be gleaned from the examples in the
MSDN Library and elsewhere. Some particularly useful examples are located in the
MSDN Library article XML and Web Services / XML Core / XML General / SDK
Documentation / XML (Extensible Markup Language) / XML and XSL Samples / XML
Code Examples / Code Examples in Microsoft Jscript / XSLTemplate Examples. Please
be aware that this article is from the MSXML 3.0 SDK, so the actual XSLT is
WD-xsl, but the application of XSLTemplates is
still relevant.
Let's dig in to a simple script example to acquaint
ourselves with XSLTemplate and XSLProcessor.
<html>
<head>
<script language="javascript">
var ss, cache;
function init()
{
// create and load XSLT stylesheet – must be free-threaded
ss = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.4.0');
ss.async = false;
ss.load('stylesheet.xsl');
// create XSLTemplate object and compile stylesheet into it
cache = new ActiveXObject("Msxml2.XSLTemplate.4.0");
cache.stylesheet = ss;
}
function transform(source)
{
// create and load source document
var src = new ActiveXObject('MSXML2.DOMDocument.4.0');
src.async = false;
src.load(source);
// retrieve cached XSLProcessor and transform the source document
var proc = cache.createProcessor();
proc.input = src;
proc.transform();
target.innerHTML = proc.output;
}
</script>
</head>
<body onload="init();">
<div>
Select a data set to transform:
<a href="javascript:transform('data1.xml')">data1.xml</a>
<a href="javascript:transform('data2.xml')">data2.xml</a>
<a href="javascript:transform('data3.xml')">data3.xml</a>
</div>
<div id="target">[Transformed data will appear here]</div>
</body>
</html>
When the page is loaded the <body
onload="init();"> tag directs the init
function to be executed. The init function loads
an XSLT stylesheet which follows the same familiar process with one exception:
the object must be a FreeThreadedDOMDocument object
rather than the DOMDocument we've used up to this
point. The reason for this is that the IXSLProcessor
interface is designed to handle asynchronous transformations. Next an XSLTemplate
object is created and the stylesheet is set
into the XSLTemplate's stylesheet
property. This step compiles the stylesheet into its executable format for
later use. Do note that setting the stylesheet
property will fail unless the object being assigned is a free-threaded document
object.
When a user clicks on one of the XML data files displayed in
the first <div> element, the <a href="...">
link causes the
transform function to be called with the XML filename as a parameter. The
transform function loads the source XML file (using a regular DOMDocument object) and
then gets a new XSLProcessor object by calling the XSLTemplate's
createProcessor method. The XSLProcessor's
input property is set to the XML source document, the
transform method is called, and the result of the
transform is retrieved from the output property
and displayed in the <div id="target">
element.
Go to Page: 1 | 2