Using directives#region Using directives
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
#endregion
namespace testXsltTransform
{
class Program
{
static string xml0, xslt0, prefix;
definition#region definition
const string const_xml0 =
"<?xml version=/"1.0/" encoding=/"UTF-8/"?>" +
"<Table>" +
" <Row>" +
" <Caption>Hello</Caption>" +
" <Text>this is a hello</Text>" +
" </Row>" +
" <Row>" +
" <Caption>Hello2</Caption>" +
" <Text>this is a hello2</Text>" +
" </Row>" +
" <Row>" +
" <Caption>Hello3</Caption>" +
" <Text>this is a hello3</Text>" +
" </Row>" +
"</Table>";
const string const_xslt0 =
"<?xml version=/"1.0/" encoding=/"UTF-8/"?>" +
"<xsl:stylesheet version=/"1.0/" " +
" xmlns:xsl=/"http://www.w3.org/1999/XSL/Transform/">" +
" <xsl:output method=/"html/" version=/"1.0/" encoding=/"UTF-8/" indent=/"yes/"/>" +
"" +
" <xsl:template match=/"//">" +
" <html>" +
" <head>" +
" <title>hello</title>" +
" </head>" +
" <body>" +
" <xsl:apply-templates />" +
" </body>" +
" </html>" +
" </xsl:template>" +
" " +
" <xsl:template match=/"Table/">" +
" <table border=/"1/">" +
" <body>" +
" <xsl:apply-templates />" +
" </body>" +
" </table>" +
" </xsl:template>" +
" " +
" <xsl:template match=/"Row/">" +
" <tr>" +
" <xsl:apply-templates />" +
" </tr>" +
" </xsl:template>" +
" " +
" <xsl:template match=/"Caption/">" +
" <td><xsl:value-of select=/"./"/></td>" +
" </xsl:template>" +
"" +
" <xsl:template match=/"Text/">" +
" <td><xsl:value-of select=/"./"/></td>" +
" </xsl:template>" +
"</xsl:stylesheet>";
const string const_xslt1 =
"<?xml version=/"1.0/" encoding=/"UTF-8/"?>" +
"<xsl:stylesheet version=/"1.0/" xmlns:xsl=/"http://www.w3.org/1999/XSL/Transform/">" +
" <xsl:output method=/"html/" version=/"1.0/" encoding=/"UTF-8/" indent=/"yes/"/>" +
"" +
" <xsl:template match=/"//">" +
" <html>" +
" <head>" +
" <title>hello</title>" +
" </head>" +
" <body>" +
" <xsl:apply-templates />" +
" </body>" +
" </html>" +
" </xsl:template>" +
" " +
" <xsl:template match=/"Table/">" +
" <table border=/"1/">" +
" <body>" +
" <xsl:apply-templates select=/"//Row/" />" +
" </body>" +
" </table>" +
" </xsl:template>" +
" " +
" <xsl:template match=/"Row/">" +
" <tr>" +
" <td><xsl:value-of select=/"Caption/"/></td>" +
" <td><xsl:value-of select=/"Text/"/></td>" +
" </tr>" +
" </xsl:template>" +
" " +
"</xsl:stylesheet>";
#endregion
public Program(string _prefix, string xml, string xslt)
{
prefix = _prefix;
xml0 = xml;
xslt0 = xslt;
}
public interface IXmlLoader
{
XPathNavigator GetXml();
}
public interface ITransformLoader
{
XslTransform GetTransform();
}
XPath Loader#region XPath Loader
public class XPathXmlLoader : IXmlLoader
{
public XPathNavigator GetXml()
{
XPathDocument doc = new XPathDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
public class XPathXsltLoader : ITransformLoader
{
public XslTransform GetTransform()
{
XPathDocument xslt = new XPathDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
XmlDocument Loader#region XmlDocument Loader
public class XDocXmlLoader : IXmlLoader
{
public XPathNavigator GetXml()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
public class XDocXsltLoader : ITransformLoader
{
public XslTransform GetTransform()
{
XmlDocument xslt = new XmlDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
XmlDataDocument Loader#region XmlDataDocument Loader
public class XmlDataDocumentXmlLoader : IXmlLoader
{
public XPathNavigator GetXml()
{
XmlDataDocument doc = new XmlDataDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
public class XmlDataDocumentXsltLoader : ITransformLoader
{
public XslTransform GetTransform()
{
XmlDataDocument xslt = new XmlDataDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
cache#region cache
public class XmlLoaderCache : IXmlLoader
{
XPathNavigator nav;
public XmlLoaderCache(IXmlLoader loader)
{
nav = loader.GetXml();
}
public XPathNavigator GetXml()
{
return nav;
}
}
public class XsltLoaderCache : ITransformLoader
{
XslTransform trans;
public XsltLoaderCache(ITransformLoader t)
{
trans = t.GetTransform();
}
public XslTransform GetTransform()
{
return trans;
}
}
#endregion
void trans(IXmlLoader xml, ITransformLoader trans)
{
//using (MemoryStream output = new MemoryStream())
using(NullStream output = new NullStream())
{
trans.GetTransform().Transform(xml.GetXml(), null, output);
output.Flush();
//Console.WriteLine(Encoding.Default.GetString(output.ToArray()));
}
}
public class NullStream : System.IO.Stream
{
public override bool CanRead{get { return false; }}
public override bool CanSeek{get { return false; }}
public override bool CanWrite{get { return true; }}
public override void Flush(){}
public override long Length{get { throw new global::System.NotImplementedException(); }}
public override long Position
{
get{throw new global::System.NotImplementedException();}
set{throw new global::System.NotImplementedException();}
}
public override int Read(byte[] buffer, int offset, int count){throw new NotImplementedException();}
public override long Seek(long offset, SeekOrigin origin){throw new NotImplementedException();}
public override void SetLength(long value){throw new NotImplementedException();}
public override void Write(byte[] buffer, int offset, int count){}
}
public class Tri
{
public string descr;
public IXmlLoader xml;
public ITransformLoader trans;
public Tri(string _des, IXmlLoader _xml, ITransformLoader _trans)
{
descr = _des; xml = _xml; trans = _trans;
}
}
testcode#region testcode
void doTest()
{
Tri[] tris = new Tri[]
{
new Tri(prefix + "doc: no cache", new Program.XDocXmlLoader(), new Program.XDocXsltLoader() ),
new Tri(prefix + "xpath: no cache", new Program.XPathXmlLoader(), new Program.XPathXsltLoader() ),
new Tri(prefix + "datadoc: no cache", new Program.XmlDataDocumentXmlLoader(), new Program.XmlDataDocumentXsltLoader()),
new Tri(prefix + "doc: doc cache", new Program.XmlLoaderCache(new Program.XDocXmlLoader()), (new Program.XDocXsltLoader()) ),
new Tri(prefix + "xpath: doc cache", new Program.XmlLoaderCache(new Program.XPathXmlLoader()), (new Program.XPathXsltLoader()) ),
new Tri(prefix + "datadoc: doc cache", new Program.XmlLoaderCache(new Program.XmlDataDocumentXmlLoader()), (new Program.XmlDataDocumentXsltLoader())),
new Tri(prefix + "doc: xslt cache", (new Program.XDocXmlLoader()), new Program.XsltLoaderCache(new Program.XDocXsltLoader()) ),
new Tri(prefix + "xpath: xslt cache", (new Program.XPathXmlLoader()), new Program.XsltLoaderCache(new Program.XPathXsltLoader()) ),
new Tri(prefix + "datadoc: xslt cache", (new Program.XmlDataDocumentXmlLoader()), new Program.XsltLoaderCache(new Program.XmlDataDocumentXsltLoader())),
new Tri(prefix + "doc: all cache", new Program.XmlLoaderCache(new Program.XDocXmlLoader()), new Program.XsltLoaderCache(new Program.XDocXsltLoader()) ),
new Tri(prefix + "xpath: all cache", new Program.XmlLoaderCache(new Program.XPathXmlLoader()), new Program.XsltLoaderCache(new Program.XPathXsltLoader()) ),
new Tri(prefix + "datadoc: all cache", new Program.XmlLoaderCache(new Program.XmlDataDocumentXmlLoader()), new Program.XsltLoaderCache(new Program.XmlDataDocumentXsltLoader()))
};
object[,] result = new object[1 + 5, tris.Length]; // col:round, row:testcase
Tri t;
for (int j = 0; j < result.GetLength(0); ++j) // foreach round
{
Console.WriteLine("round " + j.ToString());
for(int c = 0; c < tris.Length; ++c)
{
t = tris[c];
if (j == 0)
result[j, c] = t.descr;
else
{
DateTime start = DateTime.Now;
for (int i = 0; i < 100; ++i)
this.trans(t.xml, t.trans);
DateTime end = DateTime.Now;
int span = ((TimeSpan)(end - start)).Milliseconds;
result[j, c] = span;
}
}
}
// print result
Console.WriteLine("result:");
for (int row = 0; row < result.GetLength(1); ++row)
{
for (int col = 0; col < result.GetLength(0); ++col)
{
Console.Write(result[col, row]);
Console.Write('/t');
}
Console.WriteLine();
}
}
#endregion
static void Main(string[] args)
{
Program prog = new Program("xslt1 ", const_xml0, const_xslt0);
prog.doTest();
prog = new Program("xslt2 ", const_xml0, const_xslt1);
prog.doTest();
}
/**//*
Console Display:
round 0
round 1
round 2
round 3
round 4
round 5
result:
xslt1 doc: no cache 220 210 240 220 210
xslt1 xpath: no cache 210 190 180 180 190
xslt1 datadoc: no cache 370 360 360 350 360
xslt1 doc: doc cache 180 190 190 200 190
xslt1 xpath: doc cache 150 150 150 160 150
xslt1 datadoc: doc cache 620 640 640 620 610
xslt1 doc: xslt cache 90 90 70 90 80
xslt1 xpath: xslt cache 80 70 80 70 80
xslt1 datadoc: xslt cache 180 190 180 180 180
xslt1 doc: all cache 50 50 50 60 50
xslt1 xpath: all cache 40 50 40 40 40
xslt1 datadoc: all cache 430 440 420 450 410
round 0
round 1
round 2
round 3
round 4
round 5
result:
xslt2 doc: no cache 220 200 220 230 220
xslt2 xpath: no cache 160 250 170 170 160
xslt2 datadoc: no cache 360 390 360 350 370
xslt2 doc: doc cache 170 180 180 170 170
xslt2 xpath: doc cache 150 140 140 150 160
xslt2 datadoc: doc cache 630 650 711 701 761
xslt2 doc: xslt cache 80 80 80 80 80
xslt2 xpath: xslt cache 140 70 80 70 70
xslt2 datadoc: xslt cache 200 180 170 180 180
xslt2 doc: all cache 80 50 50 40 50
xslt2 xpath: all cache 50 40 40 40 30
xslt2 datadoc: all cache 550 430 440 450 450
*/
}
}