XsltObjectTransferService

在一些项目中我们经常需要将一种格式的XML或Object转化成另一种格式的XML或Object,我们经常需要为此写很多的代码,这些代码看上去非常不优雅,而且这种硬编码还导致如果转化规则发生了变化需要重新编译程序,如果能利用XSLT来实现这种转换那就能大大简化我们的程序,并且这种转换规则将变得可配置。下面的代码实现了一个服务这个服务就是用来实现这种转换。

定义转换服务接口:

using System;
using System.Collections.Generic;

namespace Zxf.Practices
{
public interface IXsltObjectTransferService
{
Object TransferObject(string transferName, Object inputObject, Dictionary<string,string> inputParameters, Type outputType);
}
}

实现转换服务:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Xsl;

namespace Zxf.Practices
{
public class XsltObjectTransferService : IXsltObjectTransferService
{
public Object TransferObject(string transferName, Object inputObject, Dictionary<string,string> inputParameters, Type outputType)
{
XslCompiledTransform xslCompiledTransform = XslTransferCacheManager.AcquireXslTransfer(transferName);
try
{
using (MemoryStream inputObjectMemoryStream = new MemoryStream())
{
if (inputObject is string)
{
string tempstr = inputObject as string;
inputObjectMemoryStream.Write(Encoding.UTF8.GetBytes(tempstr), 0,
Encoding.UTF8.GetByteCount(tempstr));
}
else
{
XmlSerializer inputSerializer = new XmlSerializer(inputObject.GetType());
inputSerializer.Serialize(new XmlTextWriter(inputObjectMemoryStream, Encoding.UTF8), inputObject);
}

using (StringWriter outputWriter = new StringWriter())
{
inputObjectMemoryStream.Seek(0, SeekOrigin.Begin);

XsltArgumentList xsltArgumentList = new XsltArgumentList();
if (inputParameters != null)
{
inputParameters.ToList().ForEach(pair => xsltArgumentList.AddParam(pair.Key, string.Empty, pair.Value));
}
xslCompiledTransform.Transform(new XmlTextReader(inputObjectMemoryStream), new XmlTextWriter(outputWriter));

if (outputType == typeof(string))
{
string temp = outputWriter.ToString();
return WebUtility.HtmlDecode(temp);
}
else
{
XmlSerializer outputSerializer = new XmlSerializer(outputType);
using (StringReader reader = new StringReader(outputWriter.ToString()))
{
using (XmlTextReader xmlReader = new XmlTextReader(reader))
{
return outputSerializer.Deserialize(xmlReader);
}
}
}
}
}
}
finally
{
XslTransferCacheManager.ReleaseXslTransfer(transferName, xslCompiledTransform);
}
}
}
}

实现XslCompiledTransform的Cache功能(如果不对XslCompiledTransform做Cache而是每次New并的话会导致内存溢出):

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Xsl;

namespace Zxf.Practices
{
public class XslTransferCacheManager
{
private static Dictionary<string, List<XslCompiledTransform>> s_CachedXslTransfers;

public static XslCompiledTransform AcquireXslTransfer(string transferName)
{
lock (typeof(XslTransferCacheManager))
{
if (s_CachedXslTransfers == null)
{
s_CachedXslTransfers = new Dictionary<string, List<XslCompiledTransform>>();
}

if (!s_CachedXslTransfers.ContainsKey(transferName))
{
s_CachedXslTransfers.Add(transferName, new List<XslCompiledTransform>());
}

if (s_CachedXslTransfers[transferName].Count == 0)
{

string fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "XslTransfers", transferName);
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(fileName);
s_CachedXslTransfers[transferName].Add(xslCompiledTransform);
}

XslCompiledTransform result = s_CachedXslTransfers[transferName][0];
s_CachedXslTransfers[transferName].RemoveAt(0);
return result;
}
}

public static void ReleaseXslTransfer(string transferName, XslCompiledTransform xslCompiledTransform)
{
lock (typeof(XslTransferCacheManager))
{
if (s_CachedXslTransfers == null)
{
s_CachedXslTransfers = new Dictionary<string, List<XslCompiledTransform>>();
}

if (!s_CachedXslTransfers.ContainsKey(transferName))
{
s_CachedXslTransfers.Add(transferName, new List<XslCompiledTransform>());
}

s_CachedXslTransfers[transferName].Add(xslCompiledTransform);
}
}
}
}



posted @ 2010-04-19 12:00  昝昝  阅读(242)  评论(0编辑  收藏  举报