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