XSL: Applying Transformation to a Single Node / SubTree in .NET 1.1

I'm a recent XSL recruit oohing and aahing my way thru XML Transformations. It's pretty neat. Sadly we coders am not supposed to be in a happy state for too long. Soon enough I ran into the following issue:
How do I transform a single sub-tree in XML?
For example, I should be able to transform one subtree (e.g. Authors) with StyleSheet 1 and second subtree (e.g. Publishers) with stylesheet2.
StyleSheet 1 and 2 may contain overlapping templates, but that should not be an issue ... or so I thought. So I soon had my XML Ready, the XSL StyleSheet ready. I put up code similar to the one below.


----------------------Code Snippet

using
System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Multiconn.Xml;
namespace XslPeeves{
///
/// Summary description for Class1.
///

class XslDemo {
///
/// The main entry point for the application.
///

[STAThread]
static void Main (string[] args){
try {
XmlDocument obXMLDoc=
new XmlDocument();
obXMLDoc.Load(
@"..\..\DemoSample.xml");
XslTransform obTransformer=
new XslTransform();
using (FileStream fs=new FileStream("Output.html", FileMode.Create, FileAccess.Write, FileShare.None)){
XmlTextWriter xtw=
new XmlTextWriter(fs, System.Text.Encoding.Unicode);

obTransformer.Load(
@"..\..\StyleSheet1.xsl");
obTransformer.Transform(
obXMLDoc.SelectSingleNode("/DocRoot/Authors"), null, xtw, new XmlUrlResolver());

obTransformer.Load(
@"..\..\StyleSheet2.xsl");
obTransformer.Transform(
obXMLDoc.SelectSingleNode("/DocRoot/Pubs"), null, xtw, new XmlUrlResolver());
xtw.Close();
}
}
catch (Exception obExcep){
Console.WriteLine(
"Oops!"+Environment.NewLine+obExcep.ToString());
}
}

}

}

Yikes! it's a mess, I have elements being transformed repeatedly. It is not honouring my sub-tree specification. It seems to be taking the entire document each time. Google was initially reluctant to divulge anything. A couple of search hacks and soon I see the light.
XslCompiledTransform in .NET 2.0 is supposed to handle this. XslTransform for .NET 1.1 always takes the entire tree even if you pass in an XMLNode. Crap! I need this now. Google finally takes pity and gives me the following link ..
http://www.tkachenko.com/blog/archives/000117.html
Code Download at
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=599837ac-6a0a-4da1-b666-baea91e2dacc

Thank you Mr. Oleg, you're a life saver. I referenced the XMLNodeNavigator as a DLL and made the following mods to the code
*snip
XmlTextWriter xtw=new XmlTextWriter(fs, System.Text.Encoding.Unicode);
XPathNavigator obNavigator=
new XmlNodeNavigator(obXMLDoc.SelectSingleNode("/DocRoot/Authors"));
obTransformer.Load(
@"..\..\StyleSheet1.xsl");
obTransformer.Transform(obNavigator,
null, xtw, new XmlUrlResolver());
*snip
It works! It works! The XmlNodeNavigator is a custom derivation that prevents navigation outside of the sub-tree.
Another solution was loading the sub-tree in a seperate XMLDocument and passing that into XsTransform.Transform(). Naah!

Just got to slip Mr.Oleg a mail asking him permission to use this. There ends one of the tougher Xsl fights to date..

No comments:

Post a Comment