前言
最近一直忙於工作,沒時間來管理博客,同時電腦也不給力,壞了一陣又一陣,最后還是去給修理了,這不剛一回來迫不及待的就寫一篇文章來滿足兩個月未寫博客的緊迫感。
Nvelocity
關於nvelocity就不再過多介紹,這樣的文章已經太多太多,我只是將其封裝起來用用,其中遇到的問題也會在其中一一進行講解。為什么會用到該模板引擎是因為要定義不同的格式來進行后續的打印,關於打印后續有時間也和大家講解講解,關於打印可以透露一點,有想到過用現成比如園友伍華聰大大介紹的lodop,這款打印還是非常的強大,雖然有免費版,但是也就供學習用,在實際項目中還是要用到比較復雜的打印api,於是乎就得去寫了,這個過程幸好有基本的代碼供參考,還是學到不少有關打印的知識,無論是在餐廳還是在肯德基等地方都會有打印的小票,之前沒怎么去在意過,直到自己遇到要實現這樣的打印以及對應的格式在去仔細研究研究,其過程也是受益匪淺。
好,話說了這么多,我們開始進入主題,分割線
實現內容:需要將數據放到xml文件中然后將其反序列化為對象進行后續的傳輸。。。
如下直接給出封裝的Nvelocity。
NVelocityEngine
public class NVelocityEngine { private VelocityEngine _velocit; private static readonly string templateDir = System.Web.Hosting.HostingEnvironment.MapPath("~/Template"); public NVelocityEngine(string tempDir) { //創建NVelocity引擎的實例對象 this._velocit = new VelocityEngine(); //初始化該實例對象 ExtendedProperties props = new ExtendedProperties(); props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file"); props.AddProperty(RuntimeConstants.INPUT_ENCODING, "utf-8"); props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "utf-8"); //設置模板所在目錄 props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, tempDir); props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, true); props.AddProperty("file.resource.loader.modificationCheckInterval", "30"); this._velocit.Init(props); } private static Mutex _Mutex = new Mutex(); private static NVelocityEngine _MeObj; public static NVelocityEngine Create() { if (_MeObj != null) return _MeObj; _Mutex.WaitOne(); if (_MeObj == null) _MeObj = new NVelocityEngine(templateDir); _Mutex.ReleaseMutex(); return _MeObj; } public string GetHtml(IContext context, string templatePath) { StringWriter writer = new StringWriter(); Template template = this._velocit.GetTemplate(templatePath, "utf-8"); template.Merge(context, writer); return writer.GetStringBuilder().ToString(); } } }
NVelocityPage
public class NVelocityPage { private IContext _IContext; private string _templatePath; public NVelocityPage(string templatePath) { this._IContext = new VelocityContext(); this._templatePath = templatePath; } public void Add(string key, object value) { if (this._IContext.ContainsKey(key)) this._IContext.Remove(key); this._IContext.Put(key, value); } public string WriteHtml() { try { return NVelocityEngine.Create().GetHtml(this._IContext, this._templatePath); } catch (Exception e) { throw e; } } }
接下來則是需要反序列化為對象的幾個類,命名比較粗糙,將就點看吧。
[XmlRoot("Table")] public class Table { [XmlArrayItem(typeof(tr), ElementName = "TR")] public List<tr> TR { get; set; } } public class tr { [XmlArrayItem(typeof(td),ElementName="TD")] public List<td> TD { get; set; } } public class td { [XmlAttribute("tdValue")] public string tdValue { get; set; } }
XML文件
<?xml version="1.0" encoding="utf-8" ?> <Table> <TR> #foreach($d in $list) <tr> <TD> <td tdValue="$d.Age"/> </TD> </tr> #end </TR> </Table>
測試類:
var list = new List<Person>() { new Person(){Age=1,Name="1"}, new Person(){Age=2,Name="2"}, new Person(){Age=3,Name="3"}, new Person(){Age=4,Name="4"} }; var nvelocityPage = new NVelocityPage("table.xml"); nvelocityPage.Add("list", list); var tableXml = nvelocityPage.WriteHtml(); var memoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(tableXml));
var xmlSerializer = new XmlSerializer(typeof(Table)); var table = (Table)xmlSerializer.Deserialize(memoryStream);
結果如下:

反序列為對象時沒有正確,估計是在寫xml特性有問題結果進行如下修改即可。
將上述
[XmlArrayItem(typeof(tr), ElementName = "TR")]
修改為如下:
[XmlArray("TR")] [XmlArrayItem("tr")]
同理進行修改則如我們所期望,結果則不再演示。在其過程中在利用內存流進行反序列化時建議進行如下設置
memoryStream.Position = 0;
之前未進行設置則出現如下錯誤,后來又未出現,不明白是怎么情況
XML 文檔(0, 0)中有錯誤。缺少根元素
至此,我們利用模板引擎進行數據替換接着進行加載到內存中反序列化為對象就已結束。
總結
之前未接觸過將輸出的xml數據利用xml特性來進行反序列化為對象,也花了一點時間去看這方面的東西,本以為只能通過加載xml文件來進行反序列化,未曾想到這樣也是可以的,多次嘗試才最終完成任務,每一次的實際項目應用需要才會使我學習到更多且了解的更透徹。今天寫這篇文章腦子也是懵的,終於寫完,只是為了兩個月未寫博客做一個新的開始,后續會陸續講解項目當中學到的新的知識,希望對閱讀本文的你有所啟發和幫助,當然文章難免有錯誤之處、表述不清之處請指出或者錯別字,我好及時的修改和完善。
