While using .NET 1.1 for XSL Transforms, I was running into funky special
characters ": Pump Go " which were sprinkled wherever I had intentionally added white space in the xsl stylesheet file.
Google didn't throw up anything on this... Could I be the first man to step here. No - couldn't be...
Here's the snippet I used
XmlResolver obResolver=new XmlUrlResolver();
XPathDocument obFasterPerfDoc=new XPathDocument(sDataStorePath);
XslTransform obTransformer=new XslTransform();
obTransformer.Load(sXSL_StyleSheetPath);
using (FileStream fs=new FileStream(sReportPath, FileMode.Create, FileAccess.Write, FileShare.None)){
using (TextWriter tw=new StreamWriter(fs)){
obTransformer.Transform(obFasterPerfDoc, null, tw, obResolver);
}
}
I struggled with it for a bit then let it be.. But now I seem to have run into the
solution. Use XMLTextWriter instead of TextWriter. XMLTextWriter doesn't implement
IDisposable. So can't use "using" blocks but the special character issue has gone away now.
So here's the modded code
*snip using (FileStream fs=new FileStream(sReportPath, FileMode.Create, FileAccess.Write, FileShare.None)){
XmlTextWriter xtw=new XmlTextWriter(fs, System.Text.Encoding.Unicode);
try {
XslTransform obTransformer=new XslTransform();
obTransformer.Transform(obFasterPerfDoc, null, xtw, obResolver);
}
finally {
xtw.Close();
}
}
*snip
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..
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..
Subscribe to:
Posts (Atom)