如何在Silverlight中使用XSLT格式化并输出XML文档

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

在.NET中,使用XslCompliedTransform可以非常方便地使用XSLT对XML文档进行格式化,

复制代码
// Load XML Document
XPathDocument xmlXPathDoc = new XPathDocument(HttpContext.Current.Server.MapPath("sample.xml");

// Load XSLT Document
XslCompiledTransform xslTransform = new XslCompiledTransform();

// Add parameters to XSLT Document (optional)
XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("param1",  string.Empty, "value1");
xslArg.AddParam("param2",  string.Empty, "value2");

// Output
TextWriter writer = new StringWriter();
xslTransform.Transform(xmlXPathDoc, xslArg, writer);
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.async = false;"
                                + "      xmlDoc.loadXML(xml);"
                                + "      var xslDoc = new ActiveXObject(\"MSXML2.FreeThreadedDOMDocument.6.0\");"
                                + "      xslDoc.async = false;"
                                + "      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文档的解析。

参考文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms763679(v=vs.85).aspx


本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2012/11/26/2788652.html,如需转载请自行联系原作者

相关文章
|
7月前
|
XML 存储 JavaScript
DOM 节点遍历:掌握遍历 XML文档结构和内容的技巧
**XML DOM 遍历、操作和导航概述** - 遍历XML节点树用于提取信息,例如,通过JavaScript的DOM API循环`&lt;book&gt;`子节点显示名称和值。 - DOM解析器处理XML文本数据,包括解析字符数据(PCDATA)和识别CDATA段。 - 节点导航涉及`parentNode`、`childNodes`等属性,`get_nextSibling`等辅助函数避免空文本节点。 - `getElementsByTagName`、`getAttribute`和`nodeValue`用于检索元素、属性值和文本。
100 6
DOM 节点遍历:掌握遍历 XML文档结构和内容的技巧
|
4月前
|
XML 数据采集 存储
使用Java和XPath在XML文档中精准定位数据
在数据驱动的时代,从复杂结构中精确提取信息至关重要。XML被广泛用于数据存储与传输,而XPath则能高效地在这些文档中导航和提取数据。本文深入探讨如何使用Java和XPath精准定位XML文档中的数据,并通过小红书的实际案例进行分析。首先介绍了XML及其挑战,接着阐述了XPath的优势。然后,提出从大型XML文档中自动提取特定产品信息的需求,并通过代理IP技术、设置Cookie和User-Agent以及多线程技术来解决实际网络环境下的数据抓取问题。最后,提供了一个Java示例代码,演示如何集成这些技术以高效地从XML源中抓取数据。
183 7
使用Java和XPath在XML文档中精准定位数据
|
2月前
|
XML 前端开发 数据格式
使用 XSLT 显示 XML
10月更文挑战第1天
|
6月前
|
XML 数据格式
程序技术好文:格式化xml
程序技术好文:格式化xml
101 0
|
7月前
|
XML 存储 C#
C# xml文档反序列化记事
本文介绍了使用XmlSerializer进行XML序列化和反序列化的关键点。包括:1) 以独占方式读取XML文件以避免并发问题;2) 当元素名与类型名不一致时,可通过`[XmlArrayItem]`指定元素名,或创建继承自原始类型的子类;3) 处理DateTime反序列化错误,通过中间字符串属性转换;4) 提到了常用C#特性如`[XmlRoot]`, `[XmlElement]`, `[XmlAttribute]`, `[XmlIgnore]`和`[XmlArrayItem]`的作用。
|
7月前
|
XML JavaScript 前端开发
XML文档节点导航与选择指南
XPath是XSLT的核心部分,用于XML文档的节点定位和选择。它采用路径表达式语法,包含200多个内置函数处理各种数据类型。XPath在编程语言如JavaScript中广泛使用,与XSLT配合进行XML转换和样式处理。它涉及7种节点类型,如元素、属性和文本,以及多种节点间关系,如父、子、同级等。XPath还使用轴(如ancestor、child)来描述节点间的关联,并支持运算符进行逻辑和数学操作。
99 0
XML文档节点导航与选择指南
|
7月前
|
XML JavaScript 数据格式
XML Schema(XSD)详解:定义 XML 文档结构合法性的完整指南
XML Schema(XSD)是用于定义XML文档结构的规范,它描述了元素、属性及其顺序、数据类型和约束。与DTD相比,XML Schema支持更多数据类型,如字符串、日期等,并且是基于XML的,允许扩展和重用。学习XML Schema有助于确保数据通信时双方对内容的理解一致,通过验证防止错误。示例展示了如何定义一个`note`元素,包含`to`, `from`, `heading`和`body`子元素,都是字符串类型。XML文档可以通过引用XML Schema进行验证,确保内容符合预设模式。
587 0
|
7月前
|
XML 存储 数据格式
探索 DTD 在 XML 中的作用及解析:深入理解文档类型定义
DTD(文档类型定义)用于定义XML文档的结构和合法元素、属性。它允许不同团体就数据交换标准达成一致,并用于验证XML数据的有效性。DTD可通过内部声明(在XML文档内)或外部声明(在单独文件中)来定义。内部声明示例显示了如何定义`note`元素及其子元素的结构,而外部声明则引用外部DTD文件。元素、属性、实体和PCDATA/CDATA是XML构建模块。DTD中,元素通过ELEMENT声明定义,属性通过ATTLIST声明定义,实体声明提供特殊字符或外部资源的快捷方式。
132 0
|
7月前
|
XML 数据格式 Ruby
Ruby 教程 之 Ruby XML, XSLT 和 XPath 教程 5
Ruby XML, XSLT 和 XPath 教程
123 0