• 如何将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样式的设计以及相关的函数、模板的应用。

  • 相关阅读:
    2017 年终总结 —— 在路上
    尝试造了个工具类库,名为 Diana
    走近 Python (类比 JS)
    Node.js 异步异闻录
    使用 Node.js 搭建一个 API 网关
    不就是语法和长难句吗—笔记总结Day4
    不就是语法和长难句吗—笔记总结Day3
    不就是语法和长难句吗—笔记总结Day2
    不就是语法和长难句吗—笔记总结Day1
    Kali Day1
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2059319.html
Copyright © 2020-2023  润新知