惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Archives - TechRepublic
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 叶小钗
罗磊的独立博客
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
MyScale Blog
MyScale Blog
GbyAI
GbyAI
Help Net Security
Help Net Security
Y
Y Combinator Blog
Engineering at Meta
Engineering at Meta
Hacker News - Newest:
Hacker News - Newest: "LLM"
Latest news
Latest news
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
S
Schneier on Security
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
Security @ Cisco Blogs
Recorded Future
Recorded Future
S
Securelist
博客园 - Franky
Application and Cybersecurity Blog
Application and Cybersecurity Blog
A
About on SuperTechFans
N
News and Events Feed by Topic
AI
AI
T
Tenable Blog
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
V
V2EX - 技术
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
N
Netflix TechBlog - Medium
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
Webroot Blog
Webroot Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 三生石上(FineUI控件)
C
Comments on: Blog
G
GRAHAM CLULEY

博客园 - daniel-shen

精通EJB-概述 硬件基础知识大全 教程:关于XMLBeans的初步 jaxp笔记2007-4-17 6.ZK用户接口标记语言 5.事件的监听和处理 - daniel-shen - 博客园 4.组件的生命周期 3.zk体系结构 "tomcat启动分析"文章读后笔记 jdk5.0 范型说明 java 数组反射例子 HTML小技巧 MessageFormat初步 ResourceBundle 与locale的使用 jni中关于dll的装载问题 - daniel-shen java线程-消费者vs生产者 HttpSessionBindingListener实现与应用 用Java Servlets 2.4实现过滤 加和不加java:comp/env/前缀有什么区别?
在客户端进行xslt对xml的xuan渲染
daniel-shen · 2007-04-19 · via 博客园 - daniel-shen

链接样式表与脚本转换

如果使用 XSLT 转换把数据呈现为 HTML 并决定在客户端执行 XSLT 转换,还需要做进一步的选择。XML 数据文档可以使用链接样式表。这种情况下,浏览器将尝试加载该样式表、执行转换并呈现结果。但 XML 文档是数据。不应该规定它的可视化呈现。实际上,它有可能在应用程序的不同地方呈现为不同的形式。比如,一个页面可能像 清单 1 那样显示整个 CD 目录,而下一个页面可能通过层层选择只显示 Bonnie Tyler 的 CD。

可以将视图和数据分开,通过客户机 JavaScript 执行转换。JavaScript 决定执行什么样的转换或者通过提供转换参数来控制它。

这里判断浏览器的类型非常重要。Internet Explorer 6.0 及以下版本通过私有的 ActiveX 控件执行 XSLT,而 Mozilla 和 Opera 使用内建的 XSLTProcessor 对象。Internet Explorer 7.0 将支持 XSLTProcessor,但是您不能指望整个公共 Web 社区都装上了新的浏览器。

另一方面,如果企业 WAN 指定了某种浏览器,就可以把内部应用程序设计成与这种浏览器捆绑在一起。当然,如果企业要发布新的指定,您可能会后悔引入了这种依赖性。这些是在设计应用程序时必须要考虑和权衡的。

例子

我们用脚本来实现一个 XSLT 转换。可以从 W3Schools 获得 清单 1 所示的 cdcatalog.xml(详情参阅 参考资料)。

清单 1. cdcatalog.xml

            <?xml version="1.0" encoding="utf-8"?>
            <catalog>
            >cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
            </cd>
            <cd>
            <ttitle>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
            </cd>
            <cd>
            . . .
            <catalog>
            

然后再从 W3Schools 下载 cdcatalog.xsl,如 清单 2 所示。该样式表生成一个 HTML 文件表格,按照在文档中存在的顺序(如果需要也可以在转换中增加排序)列出了收藏的 CD。

清单 2. cdcatalog.xsl

            <?xml version="1.0" encoding="ISO-8859-1"?>
            <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="/">
            <html>
            <body>
            <h2>My CD Collection</h2>
            <table border="1">
            <tr bgcolor="#9acd32">
            <th align="left">Title</th>
            <th align="left">Artist</th>
            </tr>
            <xsl:for-each select="catalog/cd">
            <tr>
            <td><xsl:value-of select="title" /></td>
            <td><xsl:value-of select="artist" /></td>
            </tr>
            </xsl:for-each>
            </table>
            </body>
            </html>
            </xsl:template>
            </xsl:stylesheet>
            

然后建立 ajax.js 脚本,如 清单 3 所示,保存在和 XML 文件与 XSL 文件相同的工作目录中。该脚本是独立于浏览器的。Mozilla 或 Opera 浏览器使用的 createRequest 函数返回一个 XMLHttpRequest 对象,通过 URL 请求一个文件。请注意,对于 Internet Explorer 浏览器,它返回一个 Microsoft ActiveX® 对象。

清单 3. ajax.js

            function createRequest() {
            var request = null;
            try {
            request = new XMLHttpRequest();
            } catch (tryIE) {
            try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (otherIE) {
            try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
            request = null;
            }
            }
            }
            if (request == null) {
            alert("Could not create request object");
            } else {
            return request;
            }
            }
            

现在创建 清单 4 所示的 HTML 文件,其中的 JavaScript 代码创建了两个异步请求对象。它使用一个请求对象加载 XML 文件,另一个请求对象加载 XSL 文件。这些对象不能重用,因此需要两个。

脚本使用 XSLTProcessor 对象应用转换,然后创建 DOM 节点。它将该 DOM 节点插入 HTML div 节点,完成 CD 目录的呈现。要在文档加载过程中调用 render 函数,因此调用必须出现在文档快结束的时候,在 div 标签之后,以便能够访问这个标记。

清单 4. catalog.html

            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
            <html>
            <body>
            <script type="text/javascript" src="ajax.js"> </script>
            <script type="text/javascript">
            function render(insertionID){
            var request1 = createRequest();
            var request2 = createRequest();
            // load the xslt file
            request1.open("GET", "cdcatalog.xsl", false);
            request1.send(null);
            var xslStylesheet = request1.responseXML;
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslStylesheet);
            // load the xml file
            request3.open("GET", "cdcatalog.xml", false);
            request2.send(null);
            var xmlDoc = request2.responseXML;
            var fragment = xsltProcessor.transformToFragment(xmlDoc, document);
            document.getElementById(insertionID).innerHTML = "";
            document.getElementById(insertionID).appendChild(fragment);
            }
            </script>
            <div id="example"/>
            </body>
            <script  type="text/javascript">
            render("example")
            </script>
            </html>
            

图 1 显示了在 Firefox 浏览器中的执行结果。在 Opera 上应该也能正常运行。但是在 Internet Explorer 6.0 或更低版本中不能工作,因为缺少 XSLTProcessor 对象。

图 1. W3Schools 脚本例子在 Firefox 中的运行结果
W3Schools 脚本例子在 Firefox 中的运行结果

清单 5 显示的 catalogIE.html 按照 Internet Explorer 的方式执行同样的转换。该页面只能在 Internet Explorer 中打开,而不能用于 Firefox 或 Opera。如何将两个 JavaScript 控制的转换结合起来留给读者作为练习。如果使用 JavaScript 执行客户端转换,应小心地处理和测试浏览器的依赖问题。

清单 5. catalogIE.html

            <html>
            <body>
            <script type="text/javascript">
            // Load XML into Internet Explorer 6.0
            var xml = new ActiveXObject("Microsoft.XMLDOM")
            xml.async = false
            xml.load("cdcatalog.xml")
            // Load XSL into Internet Explorer 6.0
            var xsl = new ActiveXObject("Microsoft.XMLDOM")
            xsl.async = false
            xsl.load("cdcatalog.xsl")
            // Transform within Internet Explorer 6.0
            document.write(xml.transformNode(xsl))
            </script>
            </body>
            </html>