在.NET中,使用XslCompliedTransform可以非常方便地使用XSLT對XML文檔進行格式化
  1. // Load XML Document  
  2. XPathDocument xmlXPathDoc = new XPathDocument(HttpContext.Current.Server.MapPath("sample.xml");  
  3.  
  4. // Load XSLT Document  
  5. XslCompiledTransform xslTransform = new XslCompiledTransform();  
  6.  
  7. // Add parameters to XSLT Document (optional)  
  8. XsltArgumentList xslArg = new XsltArgumentList();  
  9. xslArg.AddParam("param1",  string.Empty, "value1");  
  10. xslArg.AddParam("param2",  string.Empty, "value2");  
  11.  
  12. // Output  
  13. TextWriter writer = new StringWriter();  
  14. xslTransform.Transform(xmlXPathDoc, xslArg, writer);  
  15. Response.Write(writer.ToString()); 
但是在Silverlight中我們卻無法使用XslCompiledTransform以及XsltTransform物件,有兩個方法可以解決該問題:
1. 將XslCompiledTransform相關代碼移到Web Service中,然後在Silverlight中非同步調用Web Service。
2. 借用瀏覽器進行解析。
第一種方法實現起來比較簡單,無非就是將.NET代碼放到Web Service中,然後在Silverlight中調用。但是這種方法有一定的局限性,例如需要在伺服器上進行額外的部署,訪問安全性以及許可權等問題。第二種方法是借用瀏覽器的ActiveX代替XslCompiledTransform來解析XML文檔,代碼由JAVAscript完成,然後在Silverlight中調用。不足之處就是需要做瀏覽器類型判斷,然後採用不同的方式進行解析。下面的代碼用於說明如何在IE瀏覽器中調用ActiveX解析XML文檔,並在Silverlight中使用。
HtmlPage.Window.Eval(@ "function transform(xml, xsl)
 {
     var xmlDOM = new ActiveXObject("MSXML2.DOMDocument.6.0");
     xmlDOM.LoadXML(xml);
     var xslDOM = new ActiveObject("MSXML2.DOMDocument.6.0");
     xslDOM.LoadXML(xsl);

     return xmlDOM.transformNode(xslDOM);
 }");

 

在Silverlight中使用的時候只需要將XML文檔和XSLT文檔的內容以字串形式傳遞進來就行了,
string result = HtmlPage.Window.Invoke("transform", xmlString, xslString) as string;
如何需要給XSLT文檔傳遞參數怎麼辦呢?看下面的代碼,我們同時將該功能封裝成一個類。

 

public class XsltTransformProxy
{
    private const string SCRIPT = "function transform(xml, xsl)"
                                + "  {{"
                                + "      var xmlDoc = new ActiveXObject(\"MSXML2.DOMDocument.6.0\");"
                                + "      xmlDoc.loadXML(xml);"
                                + "      var xslDoc = new ActiveXObject(\"MSXML2.DOMDocument.6.0\");"
                                + "      xslDoc.loadXML(xsl);"
                                + "      var xslt = new ActiveXObject(\"MSXML2.XSLTemplate.6.0\");"
                                + "      xslt.stylesheet = xslDoc;"
                                + "      var xslproc = xslt.createProcessor();"
                                + "      xslproc.input = xmlDoc;"
                                + "      {0}"
                                + "      xslproc.transform();"
                                + "      return xslproc.output;"
                                + "  }}";

    private List<XslParameter> xslArgumentList;

    public XElement XslDocument { get; set; }
    public XElement XmlDocument { get; set; }

    public void AddParam(string name, string param)
    {
        if (xslArgumentList == null)
        {
            xslArgumentList = new List<XslParameter>();
        }

        xslArgumentList.Add(new XslParameter(name, param));
    }

    public XElement Transform()
    {
        StringBuilder scriptBuilder = new StringBuilder();

        if (this.xslArgumentList != null && this.xslArgumentList.Count > 0)
        {
            foreach (XslParameter param in this.xslArgumentList)
            {
                scriptBuilder.Append("xslproc.addParameter(\"" + param.Name + "\", \"" + param.Parameter + "\");");
            }
        }
        
        HtmlPage.Window.Eval(string.Format(SCRIPT, scriptBuilder.ToString()));
        return XElement.Parse(HtmlPage.Window.Invoke("transform", XmlDocument.ToString(), XslDocument.ToString()) as string);
    }
}

public class XslParameter
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private string parameter;

    public string Parameter
    {
        get { return parameter; }
        set { parameter = value; }
    }

    public XslParameter()
    {
    }
    
    public XslParameter(string _name, string _parameter)
    {
        this.name = _name;
        this.parameter = _parameter;
    }
}
來看一下如何調用:

 

XElement xElement = new XElement("Items");
xElement.Add(new XElement("Item", "aa", new XAttribute("Id", "0")));
xElement.Add(new XElement("Item", "bb", new XAttribute("Id", "1")));

XsltTransformProxy transformProxy = new XsltTransformProxy();
transformProxy.XmlDocument = xElement;
transformProxy.AddParam("param1", "p1");
transformProxy.AddParam("param2", "p2");

transformProxy.XslDocument = XElement.Load(new Uri("sample.xslt", UriKind.Relative).ToString());
xmlDocument = transformProxy.Transform();
當然,其中注入到頁面上的JAVAscript代碼需要優化以支援多瀏覽器。使用該方法可以彌補在Silverlight中無法使用XslCompiledTransform以及XsltTransform物件進行XML文檔的解析。
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()