在HTML,JSP当中使用XML与XSL展示部分数据
需求分析:
通常项目当中有一些固化或不经常变化的内容,且这些内容通常是使用XML保存。
但在前台页面上需要使用到这些数据,而且有可能会将其中的内容做为网页的一部分用来展示给用户。通常的做法是使用JavaScript读取这个XML进行解释,然后再创建相应的HTML标签,并将内容插入相应的位置上。这种做法不但需要编写大量的JS,而且会影响页面加载速度。如果利用XML+XSL进行数据的格式转化,再利用JS动态加载XML与XSL,便可以很方便的获取所需的数据,而且调用不同的XSL,可以展示不同的格式。
所牵涉到的基本技术:
1:XML
2:XPATH
3:JavaScript
先看一个示例:
如图
这是一个使用XML+XSL生成的地区下拉列表。
整个演示所需文档如下:
一、地区信息来自XML文档
Area.xml
<root> <!-- i_ID,n_名称,p_上一级ID,s_是否有下级 --> <a i="107" n="安徽省" p="0" s="false"/> <a i="93" n="北京市" p="0" s="false"/> <a i="103" n="北京市" p="93" s="false"/> <a i="77" n="长宁区" p="67" s="true"/> <a i="105" n="朝阳区" p="103" s="false"/> <a i="91" n="崇明县" p="67" s="true"/> <a i="89" n="奉贤区" p="67" s="true"/> <a i="108" n="福建省" p="0" s="false"/> <a i="109" n="甘肃省" p="0" s="false"/> <a i="110" n="广东省" p="0" s="false"/> <a i="101" n="广西区" p="0" s="false"/> <a i="111" n="贵州省" p="0" s="false"/> <a i="112" n="海南省" p="0" s="false"/> <a i="130" n="合肥市" p="107" s="false"/> <a i="113" n="河北省" p="0" s="false"/> <a i="114" n="河南省" p="0" s="false"/> <a i="102" n="黑龙江" p="0" s="false"/> <a i="80" n="虹口区" p="67" s="true"/> <a i="97" n="湖北省" p="0" s="false"/> <a i="96" n="湖南省" p="0" s="false"/> <a i="75" n="黄浦区" p="67" s="true"/> <a i="115" n="吉林省" p="0" s="false"/> <a i="85" n="嘉定区" p="67" s="true"/> <a i="116" n="江苏省" p="0" s="false"/> <a i="117" n="江西省" p="0" s="false"/> <a i="86" n="金山区" p="67" s="true"/> </root> <!-- 演示数据,与图片所示有所不同-->
以上是一个地区的XML文档,其中包含了三级省市区数据,通过属性"p"来寻找上一级,如果p=0,则代表当值数据为省份(顶级)
二、XSL文档
<?xml version="1.0" encoding="UTF-8"?> <!--定义当前XML文档为xsl格式--> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!--math表示匹配当前XML所有内容,也可以指定具体的某些值,取值方式参考XPATH语法--> <xsl:template match="/"> <!--在此可以编写HTML代码--> <h2>地区下拉表</h2> <div> <div>省市:</div> <div> <select> <!--读取root下所有属性p=0的a标签,进行循环--> <xsl:for-each select="root/a[@p='0']"> <!--对于需要给HTML标签赋值时,只能使用{}来取值, 不可以使用<xsl:value-of>的形式取值。这里取的是当前标签的i属性的值, 因为是在循环里,所以每次取值都不同--> <option value="{@i}"> <!--如果是在HTML内,或外面赋值,则只能使用<xsl:value-of>的形式取值, 这里取的是当前标签的n属性的值--> <xsl:value-of select="@n"/> </option> </xsl:for-each> </select> </div> </div> </xsl:template> </xsl:stylesheet>
三、在准备好了XML,XSL之后,剩下的事就是如何在页面上根据需要调用此XML文档来显示了,这里我们需要使用JS来加载XML与XSL并对其进行解析。由于IE与FF解析XML与XSL的方法及加载XML的方法不同,所以这里采用jquery框架进行判断,也可以自行写相关的方法以区别IE\FF的不同。
用到的两个最主要的方法
1:load(xmlPath) 所有方法都有部分代码基于jquery
//兼容大部分浏览器 读取外部XML文档返回xmlDoc对象 function load(x) { var xmlDoc; if ($.browser.msie) { xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.load(x); return xmlDoc; } else if ($.browser.safari) { xmlDoc = getxml(x).responseXML; return xmlDoc; } else if ($.browser.mozilla) { xmlDoc = document.implementation.createDocument('', '', null); xmlDoc.async = false; xmlDoc.load(x); return xmlDoc; } else { xmlDoc = getxml(x).responseXML; return xmlDoc; } } //供load方法调用 function getXmlHttp() { var xmlhttp; if (window.ActiveXObject) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } else if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); return xmlhttp; } return xmlhttp; } //供load方法调用 function getxml(x) { var xmlhttp = getXmlHttp(); if (xmlhttp != null) { xmlhttp.open("GET", x, false); xmlhttp.send(null); return(xmlhttp); } else { alert("对不起,您的浏览器不支持 XMLHTTP.11"); return false; } }
2:showXML() 在网页上显示XML内容,并使用相应的XSL进行解析
<!--EndFragment-->
/** * 加载XML及对应的XSL文档,直接在页面上进行显示 * @param xml XML路径 * @param xsl XML样式文件 */ function showXML(xml, xsl) { // Load XML 这里的load方法调用的是上面的laod方法 var xmlDoc = load(xml); // Load XSL var xslDoc = load(xsl); // 如果是非IE浏览器,则对解析器进行重写 if (!$.browser.msie) { Node.prototype.transformNode = function (oXslDom) { var oProcessor = new XSLTProcessor(); oProcessor.importStylesheet(oXslDom); var oResultDom = oProcessor.transformToDocument(this); var xmls = new XMLSerializer(); var sResult = xmls.serializeToString(oResultDom); if (sResult.indexOf(" <transformiix:result") > -1) { sResult = sResult.substring(sResult.indexOf(">") + 1, sResult.lastIndexOf(" <")); } return sResult; }; } document.write(xmlDoc.transformNode(xslDoc)); }
四、到此所有准备工作已完成,可以开始编写 HTML代码,当前你也可以将这此内容放入其它的页面当中如JSP\ASP
<!--EndFragment-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Simple jsp page</title></head>
<script type="text/javascript" src="/js/serv/comm/jquery.js"></script>
//这个JS包含有上面的laod等方法
<script type="text/javascript" src="/js/public/comm.js"></script>
<body>
<script type="text/javascript">
showXML("/x/comm/area.xml","/test/xml/area.xsl");
</script>
</body>
</html>
<!--EndFragment-->
<!--EndFragment-->
以下附件为整个文章涉及到的内容,但不能直接在本地打开浏览,原因是load方法不能直接读取本地文件,需要部署到项目当中。
有问题或有好的建议,欢迎大家一起探讨
<!--EndFragment--><!--EndFragment-->
<!--EndFragment-->