如何使用JavaScript 结合XSLT转换XML文档

一、             开发描述图


二、            
如何使用JavaScript 结合XSLT转换XML文档

1.     主界面效果如下:

 

2.     使用跨浏览器的JavaScript 代码 加载XSLT XML代码如下:

a.     先要去判断浏览器的类型,判断是否是IE浏览器,选择合适的加载方法,因为不同的浏览器加载转换文件所使用的对象是不同的

b.     在配置的网络地址里面找到XSL文件和XML文件进行组合转换

c.      将转换后的HTML文档插入到页面的右侧区域的DIV标签内部显示出来

d.     代码如下,是当点击某个报表按钮后,所做的前台操作(标有注释):

e.     效果1

f.       效果2

g.     源代码如下

$(document).ready(function() {

    $('#MPayPremium').click(function() {

        if (document.implementation && document.implementation.createDocument) { //

            // 支持Mozilla浏览器

            try {

                xmlDoc = document.implementation.createDocument("", "", null);

                xmlDoc.async = false;

                xmlDoc.load(hostAddress + "MPayPremium/Index.xml" + "?time=" + getExcelFileName('a'));

            }

            catch (e) {

                alert("error:001");

            }

            try {

                xslDoc = document.implementation.createDocument("", "", null);

                xslDoc.async = false;

                xslDoc.load("chartDir/MPayPremium/index.xsl");

            }

            catch (e) {

                alert("error:002");

            }

            try {

                // 定义XSLTProcessor对象   

                var xsltProcessor = new XSLTProcessor();

                xsltProcessor.importStylesheet(xslDoc);

                var oResultFragment = xsltProcessor.transformToFragment(xmlDoc, document);

                // 将解析过的文本输出到页面

                $('#rightside').html(oResultFragment);

            }

            catch (e) {

                alert("error:003");

            } 

           

        }

        else if (typeof window.ActiveXObject != 'undefined') { //IE浏览器

 

            // Load XML

            var xml = new ActiveXObject("Microsoft.XMLDOM")

            xml.async = false

            xml.load(hostAddress + "MPayPremium/Index.xml" + "?time=" + getExcelFileName('a'))

 

            // Load XSL

            var xsl = new ActiveXObject("Microsoft.XMLDOM")

            xsl.async = false

            xsl.load("chartDir/MPayPremium/index.xsl")

 

            $('#rightside').html(xml.transformNode(xsl));

 

 

            $('.divTitle').hover(function() {

                $(this).addClass('hover');

            }, function() {

                $(this).removeClass('hover');

            });

 

            $('.divTitle').click(function() {

                //设置导出XML的地址

                currentXMLUrl = this.title;

                //设置导出XML的XSL地址

                currentExcelXslUrl = "chartDir/MPayPremium/MPayPremiumToExcel.xsl";

                //设置导出文件的名字

                currentXslName = this.innerText;

 

                CallMppTable();

            })

        }

    });

});

 

 

3.     注意自适应的高度问题

a.     报表的需求希望能够将所有的内容填充到内容区域,如果超出可是范围的显示滚动条。

b.     在没有数据的时候页脚要在页面的最下面,我使用了Js控制,代码如下

c.      判断浏览器的类型,为为浏览器的窗口添加,加载和窗口改变事件代码,将页脚自动的放在最下面,同时如果页面超出了最大视角,页脚还可以向下延伸。

var isIE6 = navigator.userAgent.indexOf('MSIE 6') > 0;

var isIE = navigator.userAgent.indexOf('MSIE') > 0;

function setFooterPosition() {

    var objBodycontainer = document.getElementById("container");

    var footerHeight = document.getElementById('foot').offsetHeight;

    var headerHeight = document.getElementById('header').offsetHeight;

    if (!isIE) {

        if (window.innerHeight > footerHeight)

            document.getElementById('container').style.minHeight = (window.innerHeight - footerHeight) + 'px';

    }

    else {

        if (isIE6) {

            if (document.documentElement.clientHeight > footerHeight)

                document.getElementById('container').style.height = (document.documentElement.clientHeight - footerHeight) + 'px';

        }

        else {

            if (document.documentElement.clientHeight > footerHeight) {

                document.getElementById('container').style.minHeight = (document.documentElement.clientHeight - footerHeight) + 'px';

                document.getElementById('showBtn').style.minHeight = (document.documentElement.clientHeight - footerHeight - headerHeight) + 'px';

                document.getElementById('leftSpace').style.minHeight = (document.documentElement.clientHeight - footerHeight - headerHeight - 40 * 10) + 'px';

                document.getElementById('leftside').style.minHeight = document.getElementById('showBtn').style.minHeight;

            }

        }

    }

}

if (isIE) {

    window.attachEvent("onload", setFooterPosition);

    window.attachEvent("onresize", setFooterPosition);

} else {

    window.addEventListener("load", setFooterPosition, false);

    window.addEventListener("resize", setFooterPosition, false);

}

 

4.     XSLT 文件的编写:

XSLT 用于将一种 XML 文档转换为另外一种 XML 文档,或者可被浏览器识别的其他类型的文档,比如 HTML XHTML。通常,XSLT 是通过把每个 XML 元素转换为 (X)HTML 元素来完成这项工作的。

通过 XSLT,您可以向或者从输出文件添加或移除元素和属性。您也可重新排列元素,执行测试并决定隐藏或显示哪个元素,等等。

描述转化过程的一种通常的说法是,XSLT 把 XML 源树转换为 另一种XML 结果树

XSLT 使用 XPath

XSLT 使用 XPath XML 文档中查找信息。XPath 被用来通过元素和属性在 XML 文档中进行导航。

它如何工作?

在转换过程中,XSLT 使用 XPath 来定义源文档中可匹配一个或多个预定义模板的部分。一旦匹配被找到,XSLT 就会把源文档的匹配部分转换为结果文档。

5.     举例XSLT转换的示例:

XSL 文件

<?xml version="1.0" encoding="utf-8"?>

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

    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

 <xsl:output method="xml" indent="yes"/>

 <xsl:template match="/">

      <div class="tl1">应付保费列表</div>

    <xsl:for-each select="Index/file">

      <a class="divTitle" >

        <xsl:attribute name="title">

          <xsl:value-of select="url" />

        </xsl:attribute>

        <xsl:attribute name="coords">

          <xsl:value-of select="createDate" />

        </xsl:attribute>

        <xsl:attribute name="charset">

          <xsl:value-of select="type" />

        </xsl:attribute>

        <xsl:value-of select="name"/> </a>

    </xsl:for-each>

 </xsl:template>

</xsl:stylesheet>

XML 文件

<?xml version="1.0" encoding="utf-8" ?>

<Index>

 <file id="1">

    <name>2009年7月</name>

    <url>http://localhost/CharDir/MPayPremium/2009/20097.xml</url>

    <createDate>2009-6-12 19:32:32</createDate>

    <type>M</type>

 </file>

 <file id="2">

    <name>2009年8月</name>

    <url>http://localhost/CharDir/MPayPremium/2009/20097.xml</url>

    <createDate>2009-6-12 19:32:32</createDate>

    <type>M</type>

 </file>

 <file id="1">

    <name>2009年9月</name>

    <url>http://localhost/CharDir/MPayPremium/2009/20097.xml</url>

    <createDate>2009-6-12 19:32:32</createDate>

    <type>M</type>

 </file>

 <file id="1">

    <name>2009年10月</name>

    <url>http://localhost/CharDir/MPayPremium/2009/20097.xml</url>

    <createDate>2009-6-12 19:32:32</createDate>

    <type>M</type>

 </file>

</Index>

6.     示例说明如下:

a.     模板标记

XSL 样式表由一个或多套被称为模板(template)的规则组成。

每个模板含有当某个指定的节点被匹配时所应用的规则。

<xsl:template> 元素

<xsl:template> 元素用于构建模板。

match 属性用于关联 XML 元素和模板。match 属性也可用来为整个文档定义模板。match 属性的值是 XPath 表达式(举例,match="/" 定义整个文档)。

 

b.     循环语句

     <xsl:for-each> 元素允许您在 XSLT 中进行循环。

语句会匹配select="Index/file"中的每一个标记进行遍历

c.      值输出语句

<xsl:value-of> 元素用于提取某个选定节点的值,并把值添加到转换的输出流中

比如:<xsl:value-of select="type" /> 会将Type元素的值输出

 

d.     属性输出

    <a class="divTitle" >

        <xsl:attribute name="title">

          <xsl:value-of select="url" />

        </xsl:attribute>

</a >

上面的语句可以将Url的元素值创建一个Title 的属性给a 标签

 

e.     效果

 

7.     XPath 的应用:

 XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

XPath W3C XSLT 标准的主要元素,并且 XQuery XPointer 同时被构建于 XPath 表达之上。

因此,对 XPath 的理解是很多高级 XML 应用的基础。

 

XPath 路径表达式

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

XPath 标准函数

XPath 含有超过 100 个内建的函数。这些函数用于字符串值、数值,日期和时间比较、节点和 QName 处理、序列处理、逻辑值等等。

XPath XSLT 中使用

XPath XSLT 标准中的主要元素。如果没有 XPath 方面的知识,您就无法创建 XSLT 文档。

8.     XPath 举例:

选取价格高于 35 price 价格

下面的例子会选取所有价格高于 35 price 节点:

xmlDoc.selectNodes("/bookstore/book[price>35]/price")

 

9.     Excel 的导出:

Excel 的导出,为了能够自适应浏览器插件我使用了JavaScript 的方法去控制导出一个文件到桌面。

示例:

 

function getXlsFromTbl(xmlUrl,xslUrl,xmlName) {

 

    try {

 

        //xmlUrl = "demo";

 

        var xml = new ActiveXObject("Microsoft.XMLDOM")

        xml.async = false

        xml.load(xmlUrl)

 

        // Load XSL

        var xsl = new ActiveXObject("Microsoft.XMLDOM")

        xsl.async = false

        xsl.load(xslUrl)

        var d = " " + xml.transformNode(xsl);

       

        //去掉 xml 头

        var arr = d.split("?>");

        //获得文件名

        var fileName = getExcelFileName(xmlName);

        //导出

        doFileExport(fileName, arr[1]);

 

 

 

    }

 

    catch (e) {

 

        alert("导出发生异常:" + e.name + "->" + e.description + "!");

 

    }

 

}

 

//获得一个文件名

function getExcelFileName(xmlUrl) {

 

    var d = new Date();

 

 

 

    var curYear = d.getYear();

 

    var curMonth = "" + (d.getMonth() + 1);

 

    var curDate = "" + d.getDate();

 

    var curHour = "" + d.getHours();

 

    var curMinute = "" + d.getMinutes();

 

    var curSecond = "" + d.getSeconds();

 

 

 

    if (curMonth.length == 1) {

 

        curMonth = "0" + curMonth;

 

    }

 

    if (curDate.length == 1) {

 

        curDate = "0" + curDate;

 

    }

 

    if (curHour.length == 1) {

 

        curHour = "0" + curHour;

 

    }

 

    if (curMinute.length == 1) {

 

        curMinute = "0" + curMinute;

 

    }

 

    if (curSecond.length == 1) {

 

        curSecond = "0" + curSecond;

 

    }

 

 

 

    var fileName = xmlUrl + "_" + curYear + curMonth + curDate + "_"

 

            + curHour + curMinute + curSecond + ".csv";

 

    //alert(fileName);

 

    return fileName;

 

}

 

//导出Excel

function doFileExport(inName, inStr) {

 

    var xlsWin = null;

 

 

 

    if (!!document.all("glbHideFrm")) {

 

        xlsWin = glbHideFrm;

 

    }

 

    else {

 

        var width = 6;

 

        var height = 4;

 

        var openPara = "left=" + (window.screen.width / 2 - width / 2)

 

                + ",top=" + (window.screen.height / 2 - height / 2)

 

                + ",scrollbars=no,width=" + width + ",height=" + height;

 

        xlsWin = window.open("", "_blank", openPara);

 

    }

 

 

 

    xlsWin.document.write(inStr);

 

    xlsWin.document.close();

 

    xlsWin.document.execCommand('Saveas', true, inName);

 

    xlsWin.close();

 

}

10. 一次性的导出所有的内容,为了支持分页,我创建了一个专门用于导出ExcelXSL转换文件:

示例:

<?xml version="1.0" encoding="utf-16"?>

 

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

 

 <xsl:template match="/">

    序号&#9;月份&#9;数量&#9;险种&#9;应付保费&#9;实付保费&#9;保险公司&#9;

    <xsl:for-each select="MPayPremium/record">

      <xsl:value-of select=" position()"/>&#9;<xsl:value-of select="month"/>&#9;<xsl:value-of select="count"/>&#9;<xsl:value-of select="combo_name"/>&#9;<xsl:value-of select="premiumspayable"/>&#9;<xsl:value-of select="premiumspayed"/>&#9;<xsl:value-of select="supplier_name"/>&#9;

    </xsl:for-each>&#9;合计:&#9;<xsl:variable name="x">

 

      <xsl:for-each select="MPayPremium/record">

        <span>

          <xsl:value-of select="number(count)"/>

        </span>

      </xsl:for-each>

    </xsl:variable>

    <xsl:value-of select="sum(msxsl:node-set($x)/span)" xmlns:msxsl="urn:schemas-microsoft-com:xslt" />&#9;&#9;<xsl:variable name="y">

      <xsl:for-each select="MPayPremium/record">

        <span>

          <xsl:value-of select="number(premiumspayable)"/>

        </span>

      </xsl:for-each>

    </xsl:variable>

    <xsl:value-of select="sum(msxsl:node-set($y)/span)" xmlns:msxsl="urn:schemas-microsoft-com:xslt" />&#9;<xsl:variable name="z">

      <xsl:for-each select="MPayPremium/record">

        <span>

          &lt