如何将List<T>转换相应的Html(xsl动态转换)(二)
一、前言
紧跟着上一篇随笔,本文主要涉及到如何将xml与xsl动态转换成html,这个才是最关键的地方,所有的内容都是围绕这个主题来进行开展的。根据指定的xsl样式将List<T>转换相应的Html,相关的随笔如下:
(一)、 将List<T>转换成DataTable 。
(二)、 将Xml与Xsl动态转换成Html 。
(三)、设置以及控制Xsl的内容样式。
二、XslTransform的具体实现
XslTransform主要的职责为:将xml与xsl动态转换成html。其中,XslCompiledTransform 提供了很多方法可以进行相关的转换,但使用起来并不是十分方便,因此必须在该基础上来对目前的类进行相关封装以及提取。具体的代码如下:
1 public class XslTransform : IDisposable
2 {
3 public StringWriter StringWriter
4 {
5 get ;
6 private set ;
7 }
8
9 public StringReader XmlStringReader
10 {
11 get ;
12 private set ;
13 }
14
15 public StringReader XslStringReader
16 {
17 get ;
18 private set ;
19 }
20
21 public XslTransform()
22 {
23 this .StringWriter = new StringWriter();
24 }
25
26 public string Transfer( string xmlText, string xslText)
27 {
28 if ( string .IsNullOrWhiteSpace(xmlText)
29 || string .IsNullOrWhiteSpace(xslText))
30 {
31 return string .Empty;
32 }
33 this .XmlStringReader = new StringReader(xmlText);
34 this .XslStringReader = new StringReader(xslText);
35
36 return TransferXmlAndXslToHtml();
37 }
38
39 private string TransferXmlAndXslToHtml()
40 {
41 try
42 {
43 using (XmlTextWriter writer = new XmlTextWriter( this .StringWriter))
44 {
45 return ToHtml(writer);
46 }
47 }
48 catch
49 {
50 return string .Empty;
51 }
52 }
53
54 private string ToHtml(XmlTextWriter writer)
55 {
56 XslCompiledTransform xslTransform = new XslCompiledTransform();
57 xslTransform.Load(XmlReader.Create( this .XslStringReader));
58 xslTransform.Transform(XmlReader.Create( this .XmlStringReader), writer);
59
60 return this .StringWriter.ToString();
61 }
62
63 #region IDisposable 成员
64
65 public void Dispose()
66 {
67 this .Dispose( true );
68 GC.SuppressFinalize( this );
69 }
70
71 private void Dispose( bool disposing)
72 {
73 if ( this .StringWriter != null )
74 {
75 this .StringWriter.Dispose();
76 }
77 if ( this .XslStringReader != null )
78 {
79 this .XslStringReader.Dispose();
80 }
81 if ( this .XmlStringReader != null )
82 {
83 this .XmlStringReader.Dispose();
84 }
85 }
86
87 #endregion
88 }
XslTransform 类主要的方法为54-61行的代码,如下所示:
54 private string ToHtml(XmlTextWriter writer)
55 {
56 XslCompiledTransform xslTransform = new XslCompiledTransform();
57 xslTransform.Load(XmlReader.Create( this .XslStringReader));
58 xslTransform.Transform(XmlReader.Create( this .XmlStringReader), writer);
59
60 return this .StringWriter.ToString();
61 }
第57行加载XSL的样式文本,58行在原有基础上将XML转换成XmlTextWriter对象。其中XmlTextWriter在初始化时,StringWriter对象作为参数传递进去,如以下的43行代码:
43 using (XmlTextWriter writer = new XmlTextWriter( this .StringWriter))
因此直接返回 this .StringWriter.ToString();就获取到了我们所需的Html了。
其次,XslTransform 类还有一个注意的要点:实现IDisposable接口主要是将用到的资源及时释放掉,避免造成其他影响。
三、Xsl文件的设置以及添加到资源文件中
(1)创建MapperInfoXslContent.xslt样式文件,内容如下(目前使用最简单的,不做任何处理的样式文件):
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< xsl:stylesheet version = " 1.0 " xmlns:xsl = " http://www.w3.org/1999/XSL/Transform " >
< xsl:template match = " / " >
< html >
< head >
< title > demo </ title >
</ head >
< body >
< table >
< tr >
< td >
< table border = " 1px " bordercolor = " #000000 " cellspacing = " 0px " style = " border-collapse:collapse " >
< tr bgcolor = " #9acd32 " >
< th width = " 80 " > Name </ th >
< th width = " 80 " > Value </ th >
< th width = " 80 " > Percent </ th >
< th width = " 230 " > CreatedTime </ th >
< th width = " 60 " > IsActive </ th >
< th width = " 190 " > TargerUrl </ th >
</ tr >
< xsl: for - each select = " DataSet/MapperInfo " >
< tr >
< td bgcolor = " #ff00ff " width = " 80 " >
< xsl:value - of select = " Name " />
</ td >
< td width = " 80 " >
< xsl:value - of select = " Value " />
</ td >
< td bgcolor = " #ff00ff " width = " 80 " >
< xsl:value - of select = " Percent " />
</ td >
< td width = " 230 " >
< xsl:value - of select = " CreatedTime " />
</ td >
< td bgcolor = " #ff00ff " width = " 60 " >
< xsl:value - of select = " IsActive " />
</ td >
< td width = " 190 " >
< xsl:value - of select = " TargetUrl " />
</ td >
</ tr >
</ xsl: for - each >
</ table >
</ td >
</ tr >
</ table >
</ body >
</ html >
</ xsl:template >
</ xsl:stylesheet >
(2)然后再创建XslResource.resx资源文件,将MapperInfoXslContent.xslt样式文件添加到XslResource.resx资源文件中,如下图所示:
四、转换后的效果
经过转换后得到的Html显示效果如下(测试过程中可以以HTML格式来查看字符串):
五、相关的单元测试
示例的单元测试代码如下(仅做了一些最基础的测试,验证内容是否存在):
[TestMethod()]
public void TransferTest()
{
string xmlText = GetXmlText();
string xslText = XslResource.MapperInfoXslContent;
string htmlContent = string .Empty;
using (XslTransform xslTransform = new XslTransform())
{
htmlContent = xslTransform.Transfer(xmlText, xslText);
}
Assert.IsTrue( ! string .IsNullOrWhiteSpace(htmlContent));
Assert.IsTrue(htmlContent.Contains( " true " ));
Assert.IsTrue(htmlContent.Contains( " false " ));
for ( int index = 0 ; index < 3 ; index ++ )
{
Assert.IsTrue(htmlContent.Contains(
string .Concat( " MapperInfoIndex " , index.ToString())));
Assert.IsTrue(htmlContent.Contains(
string .Format( @" www.codeplex.com?Id={0} " , index)));
Assert.IsTrue(htmlContent.Contains(index.ToString()));
}
}
private string GetXmlText()
{
List < MapperInfo > entities = CreateMapperInfos( 3 );
DataTable dataTable = EntityMapper.ToDataTable < MapperInfo > (entities);
DataSet dataSet = new DataSet( " DataSet " );
dataSet.Tables.Add(dataTable);
return dataSet.GetXml();
}
private List < MapperInfo > CreateMapperInfos( int count)
{
List < MapperInfo > entities = new List < MapperInfo > ();
for ( int index = 0 ; index < count; index ++ )
{
entities.Add( new MapperInfo()
{
Name = string .Concat( " MapperInfoIndex " , index.ToString()),
IsActive = (index % 2 == 0 ? true : false ),
CreatedTime = DateTime.Now,
Value = index,
Percent = GetPercent(index),
TargetUrl = string .Format( @" www.codeplex.com?Id={0} " , index)
});
}
return entities;
}
private decimal ? GetPercent( int index)
{
if (index % 2 == 0 )
{
return index;
}
return null ;
}
六、总结
上面涉及的仅仅是其中的一种,代码应该是比较精简的。还有另外一种采用XPathNavigator的,也就是笛子说的:“如果使用 XmlWriter 或 XmlDocument,则可以避开这个问题。另外,XslCompiledTransform.Transform 方法重载了几个版本中,如果我没记错的话,最应优先使用的是xml数据源为 XPathNavigator 的版本。”。关于这种情况,可以通过XmlDocument来创建相关的XPathNavigator对象,即:XPathNavigator navigator = XmlDocument.DocumentElement.CreateNavigator(),这种版本的我也重写了一份,但是好像没有转换成功,因此就采用这种模式了。下一篇主要涉及到XSL样式的设计以及相关的函数、模板的应用。
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于如何将List<T>转换相应的Html(xsl动态转换)(二)的详细内容...