代码如下:
![](/Images/OutliningIndicators/ContractedBlock.gif)
Using directives#region Using directives
![](/Images/OutliningIndicators/InBlock.gif)
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/None.gif)
namespace testXsltTransform
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
class Program
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
static string xml0, xslt0, prefix;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
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
![](/Images/OutliningIndicators/InBlock.gif)
public Program(string _prefix, string xml, string xslt)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
prefix = _prefix;
xml0 = xml;
xslt0 = xslt;
}
![](/Images/OutliningIndicators/InBlock.gif)
public interface IXmlLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XPathNavigator GetXml();
}
![](/Images/OutliningIndicators/InBlock.gif)
public interface ITransformLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XslTransform GetTransform();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
XPath Loader#region XPath Loader
public class XPathXmlLoader : IXmlLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XPathNavigator GetXml()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XPathDocument doc = new XPathDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class XPathXsltLoader : ITransformLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XslTransform GetTransform()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XPathDocument xslt = new XPathDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
XmlDocument Loader#region XmlDocument Loader
public class XDocXmlLoader : IXmlLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XPathNavigator GetXml()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class XDocXsltLoader : ITransformLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XslTransform GetTransform()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument xslt = new XmlDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
XmlDataDocument Loader#region XmlDataDocument Loader
public class XmlDataDocumentXmlLoader : IXmlLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XPathNavigator GetXml()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDataDocument doc = new XmlDataDocument();
doc.LoadXml(xml0);
return doc.CreateNavigator();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class XmlDataDocumentXsltLoader : ITransformLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public XslTransform GetTransform()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDataDocument xslt = new XmlDataDocument();
xslt.LoadXml(xslt0);
XslTransform trans = new XslTransform();
trans.Load(xslt as IXPathNavigable);
return trans;
}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
cache#region cache
public class XmlLoaderCache : IXmlLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XPathNavigator nav;
public XmlLoaderCache(IXmlLoader loader)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
nav = loader.GetXml();
}
![](/Images/OutliningIndicators/InBlock.gif)
public XPathNavigator GetXml()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return nav;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class XsltLoaderCache : ITransformLoader
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XslTransform trans;
public XsltLoaderCache(ITransformLoader t)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
trans = t.GetTransform();
}
![](/Images/OutliningIndicators/InBlock.gif)
public XslTransform GetTransform()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return trans;
}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
void trans(IXmlLoader xml, ITransformLoader trans)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//using (MemoryStream output = new MemoryStream())
using(NullStream output = new NullStream())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
trans.GetTransform().Transform(xml.GetXml(), null, output);
output.Flush();
//Console.WriteLine(Encoding.Default.GetString(output.ToArray()));
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class NullStream : System.IO.Stream
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override bool CanRead
{get
{ return false; }}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override bool CanSeek
{get
{ return false; }}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override bool CanWrite
{get
{ return true; }}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override void Flush()
{}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override long Length
{get
{ throw new global::System.NotImplementedException(); }}
![](/Images/OutliningIndicators/InBlock.gif)
public override long Position
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{throw new global::System.NotImplementedException();}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{throw new global::System.NotImplementedException();}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override int Read(byte[] buffer, int offset, int count)
{throw new NotImplementedException();}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override long Seek(long offset, SeekOrigin origin)
{throw new NotImplementedException();}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override void SetLength(long value)
{throw new NotImplementedException();}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public override void Write(byte[] buffer, int offset, int count)
{}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class Tri
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public string descr;
public IXmlLoader xml;
public ITransformLoader trans;
public Tri(string _des, IXmlLoader _xml, ITransformLoader _trans)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
descr = _des; xml = _xml; trans = _trans;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
testcode#region testcode
void doTest()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Tri[] tris = new Tri[]
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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()),
![](/Images/OutliningIndicators/InBlock.gif)
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())),
![](/Images/OutliningIndicators/InBlock.gif)
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())),
![](/Images/OutliningIndicators/InBlock.gif)
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()))
};
![](/Images/OutliningIndicators/InBlock.gif)
object[,] result = new object[1 + 5, tris.Length]; // col:round, row:testcase
![](/Images/OutliningIndicators/InBlock.gif)
Tri t;
for (int j = 0; j < result.GetLength(0); ++j) // foreach round
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("round " + j.ToString());
for(int c = 0; c < tris.Length; ++c)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
t = tris[c];
if (j == 0)
result[j, c] = t.descr;
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DateTime start = DateTime.Now;
for (int i = 0; i < 100; ++i)
this.trans(t.xml, t.trans);
DateTime end = DateTime.Now;
![](/Images/OutliningIndicators/InBlock.gif)
int span = ((TimeSpan)(end - start)).Milliseconds;
result[j, c] = span;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
// print result
Console.WriteLine("result:");
for (int row = 0; row < result.GetLength(1); ++row)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
for (int col = 0; col < result.GetLength(0); ++col)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.Write(result[col, row]);
Console.Write('\t');
}
Console.WriteLine();
}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
static void Main(string[] args)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
Program prog = new Program("xslt1 ", const_xml0, const_xslt0);
prog.doTest();
![](/Images/OutliningIndicators/InBlock.gif)
prog = new Program("xslt2 ", const_xml0, const_xslt1);
prog.doTest();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*
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
*/
}
}
我的机器配置如下:赛扬900,512M内存。编译采用VS C# Express 2005
开始时候的测试循环次数是10次,结果发现太小,分辨不开,结果采用1000次循环,结果出现了很多性能异常情况,分析结果是循环次数太多导致内存耗用太大,影响评测,结果用循环100次得到这个结果,基本满意。
从结果中我们可以看到,XPathDocument支持的xslt转换速度始终最快,无论xslt中是否包含xpath引用。其次是XmlDocument支持的转换,最后才是XmlDataDocument。
而在优化方面,预先装入XML而运行时装入xslt要比预先装入XSLT而运行时装入xml的测试速度要慢差不多一个级别,说明系统装入xslt的耗费远比装入xml的耗费要大得多。大家以后一定要注意,不要经常去 new XslTransform() ,一定要预先装载好xslt。
另外需要注意的是,使用XmlDataDocument支持的转换,即使在全部cache的情况下,也和其他两种方法全部没有cache的情况一样速度。而且和最快方案的速度差距竟然有6倍之多!!!
最后,尝试了好几下去上传图片,结果都没有成功。怎么回事啊?图片17k,300x400点阵的gif。谁帮我一下?