首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

4.3.2  IE中的XSLT

IE中有两种方法来完成XML文档的转换,这两种方法都必需使用MSXML。从MSXML 3.0版开始,MSXMLXSLT1.0提供完整的支持。如果没有Windows XPIE 6,那么应当升级。你可以在http://msdn.microsoft.com/XML/XMLDownloads/中找到并下载最新的MSXML

首先,使用最简单的方法将XMLXSLT文档载入到各自的XML DOM对象中:

var oXmlDom = zXmlDom.createDocument();

var oXslDom = zXmlDom.createDocument();

 

oXmlDom.async = false;

oXslDom.async = false;

 

oXmlDom.load(books.xml);

oXslDom.load(books.xsl);

当载入文档后,就可以调用transformNode()方法进行转换:

var sResults = oXmlDom.transformNode(oXslDom);

transformNode()方法的参数为XML DOM对象(本示例为XSL文档),并以字符串形式返回转换后的数据。但是不一定要在文档对象处调用transformNode()方法,也可以在XML文档的任何元素处调用该方法:

var sResults = oXmlDom.documentElement.firstChild.transformNode(oXslDom);

transformNode()方法只会从调用的元素开始转换该元素及其子元素。示例中转换了第一个<book/>元素,如图4-3所示。这是因为对没有子元素的元素调用transformNode()方法只会转换一个节点。

  4-3

IE中第二个转换方法稍微有些复杂,但提供更多的控制权和特性。该过程需要创建多个MSXML库中的对象。这个稍长过程的第一步是创建一个线程安全的XML DOM对象,并将XSL样式表载入该对象:

var oXmlDom = zXmlDom.createDocument();

oXmlDom.async = false;

oXmlDom.load("books.xml");

 

var oXslDom = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");

oXslDom.async = false;

oXslDom.load("books.xsl");

FreeThreadedDOMDocument类是另一个ActiveX类,且是MSXML库中的一部分。必须使用FreeThreadedDOMDocument类来创建XSLTemplate对象,如该示例所示(下一个示例将显示XSLTemplate对象的创建)。在MSXML的早期版本中,对每个transformNode()方法的调用都需要对XSL样式表进行重新编译,这在一定程度上会降低了转换的速度。如果基于FreeThreadedDOMDocument,编译后的样式表会放入缓存供以后使用,直到从内存中移出。

XML DOM对象创建后,还需要创建另一个ActiveX对象,即XSL模板对象:

var oXslTemplate = new ActiveXObject("Msxml2.XSLTemplate.3.0");

oXslTemplate.stylesheet = oXslDom;

XSLTemplate类用于缓存XSL样式表并创建XSLProcessor,所以当模板创建后,XSL文档赋值给XSLTemplate类的stylesheet属性,实现缓存功能并载入XSL样式表。

该过程的下一步是创建XSLProcessor,通过调用XSLTemplate类的createProcessor()方法创建:

var oXslProcessor = oXslTemplate.createProcessor();

oXslProcessor.input = oXmlDom;

创建处理器后,其input属性将赋值为oXmlDom,也就是包含待转换XML文档的XML DOM对象。现在,处理器所需一切都准备就绪,所以余下工作就是实际的转换和获取输出:

oXslProcessor.transform();

document.body.innerHTML = oXslProcessor.output;

transformNode()不一样,transform()方法并不以字符串形式返回结果。为了得到转换的输出,需要使用XSLProcessor对象的output属性。其整个过程比transformNode()方法需要更多的代码,并得到相同的结果。为什么要使用这样的过程呢?

MSXML提供一些额外的可以用于转换的方法。第一个方法是addObject()。该方法往样式表中添加一个JavaScript对象,可以在转换后的文档中调用方法和output属性值。考虑下面的对象:

var oBook = {

    propertyOne : "My Current Books",

    methodOne    : function () {

       alert("Welcome to my Book List");

       return "";

    }

};

如果想要在转换中使用该信息,该怎么样呢?使用addObject()方法,就可以将该信息传到XSLT样式表,这里需要传入两个参数:oBook对象和命名空间URI。所以,要将"http:// my-object"的命名空间URI添加到该对象,可以按下述代码所示的方法来完成:

var oXmlDom = zXmlDom.createDocument();

oXmlDom.async = false;

oXmlDom.load("books.xml");

 

var oXslDom = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");

oXslDom.async = false;

oXslDom.load("books.xsl");

 

var oXslTemplate = new ActiveXObject("Msxml2.XSLTemplate.3.0");

oXslTemplate.stylesheet = oXslDom;

 

var oXslProcessor = oXslTemplate.createProcessor();

oXslProcessor.input = oXmlDom;

 

oXslProcessor.addObject(oBook, "http://my-object");

 

oXslProcessor.transform();

document.body.innerHTML = oXslProcessor.output;

oBook对象将传到XSLProcessor中,意味着XSLT样式表可以使用该对象。现在必须对XSL文档进行修改,才能够查找该对象并使用其信息。第一件事是添加新的命名空间到根元素<xsl:stylesheet/>中。该命名空间将匹配addObject()中的命名空间:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

 

     xmlns:bookObj="http://my-object">

前缀bookObj可以用来访问该信息。现在命名空间和前缀都准备好了,应当往文档中添加一些<xsl:value-of/>元素来获取对象成员:

<xsl:template match="/">

 

<html>

    <head>

        <link rel="stylesheet" type="text/css" href="books.css" />

    </head>

    <body>

 

       <xsl:value-of select="bookObj:methodOne()" />

       <div align="center">

           <b><xsl:value-of select="bookObj:get-propertyOne()" /></b>

       </div>

        <xsl:apply-templates />

    </body>

</html>

 

</xsl:template>

请记住,<xsl:value-of/>XSL指令获取元素或对象的值。第一个<xsl:value-of/>指令获取(或调用)methodOne(),该方法发送一个欢迎用户到该页面的信息。第二个<xsl:value-of/>指令与第一个非常相似,该指令获取oBook对象的propertyOne属性的值。当在浏览器中显示转换后的输出时,用户会在页面顶部看到“My Current Books”的字句。

当在转换中使用对象时,所有属性和方法都必须返回XSLProcessor能够理解的值:字符串、数字以及布尔值。返回其他值将会在执行转换时抛出JavaScript错误。

XSLProcessor另一个有用的特性是addParameter()方法。与将对象进行转换不同,该方法的参数是XSLT标准部分。参数传入XSL样式表,并可以作为变量使用。为了指定参数,并传入名称和值,如下所示:

var oXslProcessor = oXslTemplate.createProcessor();

oXslProcessor.input = oXmlDom;

oXslProcessor.addParameter("message", "My Book List");

这段代码将往XSLProcessor中添加"message"参数。当执行XSL转换时,处理器使用参数的值,"My Book List",并将其放置在相应的位置。XSL中的参数使用<xsl:param/>指令:

<xsl:param name="message" />

请注意,name属性匹配传入addParameter()的名称。该参数接收使用之前介绍的变量语法获取的值"My Book List"

<xsl:value-of select="$message" />

本示例中,通过<xsl:value-of/>指令得到参数值。更新后的XSL样式表如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 

<xsl:param name="message" />

 

<xsl:template match="/">

 

<html>

    <head>

        <link rel="stylesheet" type="text/css" href="books.css" />

    </head>

    <body>

 

       <xsl:value-of select="$message" />

 

        <xsl:apply-templates />

    </body>

</html>

 

</xsl:template>

更新后的样式表增加两行新的代码。第一行代码是<xsl:param/>指令,第二行代码则是获取参数值的<xsl:value-of/>指令。参数声明可以在XSL文档的任何位置出现。这段代码在文档顶部进行参数声明,但是并不限制只能在文档顶部出现。

使用XSLProcessor的最后一个特性是它的速度。XSLProcessor编译XSL样式表,所以后续的转换可以使用相同的样式表结果,转换速度更快(与使用transformNodes()相比)。如果要这样做,那么需要使用XSLProcessor对象的reset()方法。该方法清空inputoutput属性,但没有清空stylesheet属性。这就让处理器为下次基于相同样式表的转换做好了准备。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论