473,385 Members | 1,542 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

xsl template startMode in system.xml.xsl.xslTransform

Is there any way of specifying the startMode when using the xslTransform class?

We are updating code which used msxml to the system.xml classes but can find
no way to specify the startMode.
We use this so that we can specify different templates to be used by the
same xml node.

Know that we could use global params, but would rather not have to update
all teh stylesheets and any code that uses msxml and the same stylesheets.

Thanks
Nov 12 '05 #1
3 2250
"Steve" <st***@nospam.com> wrote in message news:C7**********************************@microsof t.com...
Is there any way of specifying the startMode when using the xslTransform class?
The XslTransform class doesn't afford a direct means of setting a
so-called "start mode" that I'm aware of. Start mode is just an
MSXML-specific means of having multiple 'root' template rules each
with a different mode attribute and choosing one of them to apply.
Know that we could use global params, but would rather not have to update
all the stylesheets and any code that uses msxml and the same stylesheets.


Parameters would make your stylesheets more portable in the long
run, because "start mode" is an implementation-specific feature that
you may not be able to take with you when migrating to another XSLT
processor.

However, I think you can accomplish the same effect by using an
<xsl:import> in a "wrapper" stylesheet. The <xsl:apply-templates>
in the wrapper could select the 'root' template rule in the imported
stylesheet having your desired start mode.

Of course, this <xsl:apply-templates> would appear in the 'root' template
rule of the wrapper stylesheet, thus superceding any 'root' template that
doesn't have a mode attribute in the imported stylesheet. Therefore, you
only want to create this wrapper when you're actually going to specify a
start mode (if no start mode is specified, or start mode is null or the empty
string, then the imported stylesheet is simply used directly; which is exactly
as it would be for the start mode property in MSXML).

Here's a concrete example of an XslTransform-aggregating class that I've
dubbed StartModeTransform exposing a StartMode property and managing
when to use, or not to use, the "wrap and import" stylesheet design.

- - - StartModeTransform.cs
using System;
using System.IO;
using System.Security.Policy;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

/// <summary>
/// Encapsulates an <b>XslTransform</b> and adds <i>start mode</i> capability
/// by "wrapping and importing" the loaded stylesheet as required.
/// </summary>
public class StartModeTransform
{
private XslTransform transformer;
private string startMode;
private bool isAdjusted;
private string baseUrl;

public StartModeTransform( ) : this( new XslTransform( ))
{
;
}

public StartModeTransform( XslTransform xslt)
{
this.transformer = xslt;
}

public string StartMode
{
get
{
return this.startMode;
}

set
{
if ( value != this.startMode )
{
this.startMode = value;
this.isAdjusted = false;

if ( ( ( value == null ) || ( 0 == value.Length ) ) && isAdjusted )
// Un-adjust when StartMode is reset to none.
Load( this.baseUrl);
else
// Re-adjust when StartMode changes.
AdjustForStartMode( );
}
}
}

public virtual void Load( string url)
{
this.baseUrl = url;
this.transformer.Load( url);
}

// Implementation of other Load( ) methods left as an
// exercise for the reader.

public virtual void Transform( IXPathNavigable input, XsltArgumentList args,
TextWriter output, XmlResolver resolver)
{
this.transformer.Transform( input, args, output, resolver);
}

// Implementation of other Transform( ) methods left as
// an exercise for the reader.

protected virtual void AdjustForStartMode( )
{
if ( this.isAdjusted || ( null == this.startMode ) || ( 0 == this.startMode.Length ) )
return;

// Import current XSLT stylesheet inside of wrapper that
// honors StartMode.

XmlDocument adjustedXsl = new XmlDocument();
adjustedXsl.Load( "startMode.xsl");

// Replace two placeholders, one for the xsl:import href
// that points to the wrapped stylesheet.

XmlAttribute hrefAttr = ((XmlElement)(adjustedXsl.DocumentElement.FirstChi ld)).Attributes[ "href"];
hrefAttr.Value = String.Format( "{0}", this.baseUrl); // use Format to allow for http:// URLs

// The other placeholder specifies the xsl:apply-templates mode
// that is the start mode to be called in the wrapped stylesheet.

XmlAttribute modeAttr = ((XmlElement)(adjustedXsl.DocumentElement.ChildNod es[ 1].FirstChild)).Attributes[ "mode"];
modeAttr.Value = this.startMode;

// Depending on where you keep the XSLT stylesheet being
// loaded, you may need to subclass XmlResolver and specify
// it here (instead of resolver).

XmlUrlResolver resolver = new XmlUrlResolver( );
Evidence evidence = XmlSecureResolver.CreateEvidenceForUrl( this.baseUrl);
this.transformer.Load( adjustedXsl.CreateNavigator(), resolver, evidence);

this.isAdjusted = true;
return;
}
}
- - -

This class depends on a placeholder XSLT stylesheet into which it adjusts the
<xsl:import>'s href attribute, and the <xsl:apply-templates>'s mode attribute,
to affect the "wrapping and importing" of your stylesheet when a StartMode is
assigned.

- - - startMode.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="X" />
<xsl:template match="/">
<xsl:apply-templates select="/" mode="X" />
</xsl:template>
</xsl:stylesheet>
- - -

The attribute values of this wrapper stylesheet import the originally loaded style-
sheet, and assign the StartMode used to apply the 'root' template of the imported
stylesheet.

Another advantage to using <xsl:import> is that it must appear as the first
child under the <xsl:stylesheet>, and therefore it honors any existing global
parameters in the stylesheets you're loading, and any namespace declarations
in the <xsl:stylesheet> that's imported are respected.

In conclusion, you can't expect every XSLT processor to directly support a
StartMode, but it is still something that can be simulated and overcome
through the skillful application of XSLT.
Derek Harmon
Nov 12 '05 #2
Derek,

Thanks for the very detailed info.
agree that "startMode" is msxml specific, but the mode attribute of an xslt
template is part of the xslt standard.
Is there no way to specify the mode to be used when evaluating what template
should be used?

As an example, if we have a stylesheet with some order processing templates:

<xsl:template match="order" mode="buy">
<!-- process here -->
</xsl:template>

<xsl:template match="order" mode="amend">
<!-- process here -->
</xsl:template>

<xsl:template match="order" mode="cancel">
<!-- process here -->
</xsl:template>

in a stylsheet we could specify what template should be called by:
<!-- processing stuff -->
<xsl:choose>
<xsl:when test="conditionA"><xsl:apply-templates select="."
mode="amend"/></xsl:when>
<xsl:when test="conditionB"><xsl:apply-templates select="."
mode="cancel"/></xsl:when>
<xsl:otherwise><xsl:apply-templates select="." mode="buy"/></xsl:otherwise>
</xsl:choose>

What I'd like to be able to do is, within my .NET code, when processing an
order node, get the stylesheet to process the template I want it to by
specifying the mode...?

Otherwise I will use the concrete example you have provided

Thanks very much for your input, very usefull
Steve

"Derek Harmon" wrote:
"Steve" <st***@nospam.com> wrote in message news:C7**********************************@microsof t.com...
Is there any way of specifying the startMode when using the xslTransform class?


The XslTransform class doesn't afford a direct means of setting a
so-called "start mode" that I'm aware of. Start mode is just an
MSXML-specific means of having multiple 'root' template rules each
with a different mode attribute and choosing one of them to apply.
Know that we could use global params, but would rather not have to update
all the stylesheets and any code that uses msxml and the same stylesheets.


Parameters would make your stylesheets more portable in the long
run, because "start mode" is an implementation-specific feature that
you may not be able to take with you when migrating to another XSLT
processor.

However, I think you can accomplish the same effect by using an
<xsl:import> in a "wrapper" stylesheet. The <xsl:apply-templates>
in the wrapper could select the 'root' template rule in the imported
stylesheet having your desired start mode.

Of course, this <xsl:apply-templates> would appear in the 'root' template
rule of the wrapper stylesheet, thus superceding any 'root' template that
doesn't have a mode attribute in the imported stylesheet. Therefore, you
only want to create this wrapper when you're actually going to specify a
start mode (if no start mode is specified, or start mode is null or the empty
string, then the imported stylesheet is simply used directly; which is exactly
as it would be for the start mode property in MSXML).

Here's a concrete example of an XslTransform-aggregating class that I've
dubbed StartModeTransform exposing a StartMode property and managing
when to use, or not to use, the "wrap and import" stylesheet design.

- - - StartModeTransform.cs
using System;
using System.IO;
using System.Security.Policy;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

/// <summary>
/// Encapsulates an <b>XslTransform</b> and adds <i>start mode</i> capability
/// by "wrapping and importing" the loaded stylesheet as required.
/// </summary>
public class StartModeTransform
{
private XslTransform transformer;
private string startMode;
private bool isAdjusted;
private string baseUrl;

public StartModeTransform( ) : this( new XslTransform( ))
{
;
}

public StartModeTransform( XslTransform xslt)
{
this.transformer = xslt;
}

public string StartMode
{
get
{
return this.startMode;
}

set
{
if ( value != this.startMode )
{
this.startMode = value;
this.isAdjusted = false;

if ( ( ( value == null ) || ( 0 == value.Length ) ) && isAdjusted )
// Un-adjust when StartMode is reset to none.
Load( this.baseUrl);
else
// Re-adjust when StartMode changes.
AdjustForStartMode( );
}
}
}

public virtual void Load( string url)
{
this.baseUrl = url;
this.transformer.Load( url);
}

// Implementation of other Load( ) methods left as an
// exercise for the reader.

public virtual void Transform( IXPathNavigable input, XsltArgumentList args,
TextWriter output, XmlResolver resolver)
{
this.transformer.Transform( input, args, output, resolver);
}

// Implementation of other Transform( ) methods left as
// an exercise for the reader.

protected virtual void AdjustForStartMode( )
{
if ( this.isAdjusted || ( null == this.startMode ) || ( 0 == this.startMode.Length ) )
return;

// Import current XSLT stylesheet inside of wrapper that
// honors StartMode.

XmlDocument adjustedXsl = new XmlDocument();
adjustedXsl.Load( "startMode.xsl");

// Replace two placeholders, one for the xsl:import href
// that points to the wrapped stylesheet.

XmlAttribute hrefAttr = ((XmlElement)(adjustedXsl.DocumentElement.FirstChi ld)).Attributes[ "href"];
hrefAttr.Value = String.Format( "{0}", this.baseUrl); // use Format to allow for http:// URLs

// The other placeholder specifies the xsl:apply-templates mode
// that is the start mode to be called in the wrapped stylesheet.

XmlAttribute modeAttr = ((XmlElement)(adjustedXsl.DocumentElement.ChildNod es[ 1].FirstChild)).Attributes[ "mode"];
modeAttr.Value = this.startMode;

// Depending on where you keep the XSLT stylesheet being
// loaded, you may need to subclass XmlResolver and specify
// it here (instead of resolver).

XmlUrlResolver resolver = new XmlUrlResolver( );
Evidence evidence = XmlSecureResolver.CreateEvidenceForUrl( this.baseUrl);
this.transformer.Load( adjustedXsl.CreateNavigator(), resolver, evidence);

this.isAdjusted = true;
return;
}
}
- - -

This class depends on a placeholder XSLT stylesheet into which it adjusts the
<xsl:import>'s href attribute, and the <xsl:apply-templates>'s mode attribute,
to affect the "wrapping and importing" of your stylesheet when a StartMode is
assigned.

- - - startMode.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="X" />
<xsl:template match="/">
<xsl:apply-templates select="/" mode="X" />
</xsl:template>
</xsl:stylesheet>
- - -

The attribute values of this wrapper stylesheet import the originally loaded style-
sheet, and assign the StartMode used to apply the 'root' template of the imported
stylesheet.

Another advantage to using <xsl:import> is that it must appear as the first
child under the <xsl:stylesheet>, and therefore it honors any existing global
parameters in the stylesheets you're loading, and any namespace declarations
in the <xsl:stylesheet> that's imported are respected.

In conclusion, you can't expect every XSLT processor to directly support a
StartMode, but it is still something that can be simulated and overcome
through the skillful application of XSLT.
Derek Harmon

Nov 12 '05 #3
Hi Steve,

I don't think mode has been implemented in .net xml. However, I think we
can achieve the same goal with the concrete example Derek has provided.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: mike p. | last post by:
I have a docbook xml file, and am using standard docbook 1.61.3 xsl stylesheets to do xhtml transform. Transform works fine when using MSXML. When I try to do the following using asp.net 1.1: ...
4
by: schneider | last post by:
Anyone know if there is a way to dynamicly create a Xslt template/s and use them as an xml transform with-out use files for the Xslt? All the methods I see use files. I want to create a Xslt...
5
by: laks | last post by:
Hi I have the following xsl stmt. <xsl:for-each select="JOB_POSTINGS/JOB_POSTING \"> <xsl:sort select="JOB_TITLE" order="ascending"/> This works fine when I use it. But when using multiple...
2
by: KJS | last post by:
Hello, I'm receiving: 'System.Xml.Xsl.XsltException: Missing mandatory attribute 'version' After I try and run my transformation. I spent a good few days coming up with the appropriate (I think)...
1
by: rmgalante | last post by:
Hello, I have a VB.Net component that uses the XslTransform object. I am using the FXSL randomizeList function in my XSL template. When I transform the XML in the VB.Net component, my...
3
by: Grep J | last post by:
Hello, I'm using Visual Studio.NET 2003 and I'm wondering that is it possible to call XSL file's template to transform a XML file? I have following files. A XML file below <?xml...
17
by: VK | last post by:
Is there any possibility to detect any of UA's feature in the template? I have an XML data file with XSL template linked having HTML page as output. I would love to make some adjustments during...
1
by: Praveen | last post by:
Have a common function in Javascript which do transform for all .xsl's. XSL object is loaded like this. var xslobj=new ActiveXObject("MSXML2.FreeThreadedDOMDocument.4.0"); xslobj.async = false;...
1
by: lenzdata | last post by:
I am in the process of porting a VB6 ActiveX exe to a C# exe. The finished product will either be run directly from Windows or hosted by other .NET applications. The application's behavior will...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.