0

0

使用jQuery在浏览器中处理XML

黄舟

黄舟

发布时间:2016-12-15 09:38:14

|

1570人浏览过

|

来源于php中文网

原创

xml 是 web 的 sgml,但是它还没有像 xml 社区那样在 web 上引人注目。xml 在 web 上最突出的成就 —— xhtml —— 已经被政治和委员会设计所纠缠,并且其他雄心壮志、技术良好的规范 —— 例如 xforms 和 svg —— 一直受到低使用率的困扰。有时候 xml 会在意想不到的方面在 web 上获得成功,包括 xml 格式的 web 提要(例如 rss 类型和 atom)的流行。

常用缩略词

Ajax:异步 JavaScript + XML

API:应用程序编程接口

CSS:层叠样式表

DOM:文档对象模型

HTML:超文本标记语言

RSS:真正简单聚合

SGML:标准通用标记语言

SVG:可缩放矢量图形

URI:统一资源标识符

URL:统一资源定位符

W3C:万维网联盟

XHTML:可扩展超文本标记语言

XML:可扩展标记语言

和其他 Web 上的技术一样,Web 上的 XML 以浏览器为中心,但是大部分关于在 Web 上处理 XML 的讨论都集中在服务器端。在 developerWorks 的 Firefox and XML 系列中,我介绍了几种在 Firefox 浏览器中使用 XML 的方法。遗憾的是,跨浏览器处理 XML 甚至比跨浏览器处理 HTML 更加奇怪,这就是为什么这么多 Web 上的 XML 处理坚持相对安全的服务器端领域的部分原因。

许多动态 HTML 开发人员厌烦了跨浏览器的痛苦和浏览器之间脚本编写的怪癖。几种出色的 JavaScript 库的出现使开发人员的工作更加轻松。这些库中最流行一种就是 jQuery,developerWorks 上有几篇文章已经对它进行了介绍。如果您知道如何绕开这些巨大的陷阱,您还可以使用 jQuery 来处理 XML。在本文中,我将展示如何在实际场景中联合使用 jQuery 和 XML,如何使用 Atom Web 提要,介绍一种在 jQuery 中处理 XML 的实用模式,并解决不幸遇到的实际问题。您需要对 XML、XML 名称空间、HTML、JavaScript 和 jQuery 库有基本的了解。

XML 名称空间的问题

我将首先介绍最严重的问题。jQuery 并不能完全解决 XML 名称空间问题。这个众所周知的问题由来已久,人们尝试了各种解决方案,但结果都不太令人满意。理想的解决方案可能是利用 jQuery 支持 CSS Level 3 名称空间选择器,它将添加一个新的选择器,如下所示:

@namespace ex url(http://example.com);
ex|quote { font-weight: bold }

第一行是 http://example.com 名称空间的前缀声明,第二行是一种使用新的名称空间组件的类型选择器,其中用竖线符号分隔已声明的前缀和本地名称。不幸的是,jQuery 并不支持这种方法,因此人们采取了各种方法来处理名称空间问题。

伪装前缀的重要性

一种最常见的黑客方法是在 jQuery 中处理 XML 和名称空间时忽略名称空间,并选择完整的 qname(前缀和本地部分)。

$(xml).find("x\\:quote").each(function() {
   //process each node
  });

该代码通过 jQuery 的节点名称概念选择,即 DOM nodeName 属性。它包含一个冒号,是 jQuery 选择器保留的符号,并且必须使用反斜杠进行转义。反斜杠是 JavaScript 脚本保留的符号并且必须是一对。这种黑客方法在使用不同前缀的名称空间等效文档中无法使用。
使用属性过滤器

据说有人成功地使用过以下方法的变体,即在伪属性 nodeName 上使用 jQuery 属性过滤器:

$(xml).find("[nodeName=x:quote]").each(function() {
   //process each node
  });

使用 jQuery 1.3.x 之前的版本,您需要在 nodeName 前面加上 @。但是,这样做与上一节 伪装前缀的重要性 中提到的方法有着相同的基本问题。它将破坏许多真实的名称空间场景。我尝试了以下变体,这种方法更合理:

$(xml).find("[namespaceURI='http://example.com'][localName='quote']")
  .each(function() {
   //process each node
  });

可惜这样不起作用。

寻找一个好的插件

这种混乱不完全是 jQuery 的错。DOM 为寻找节点提供了有效的方法:getElementsByTagName 和 getElementsByTagNameNS。后者旨在感知名称空间,接受名称空间的 URI 并忽略前缀,但遗憾的是,尽管其他浏览器都支持它,但 Microsoft® Internet Explorer® 除外。然而,jQuery 的目的是处理此类浏览器问题,以便消除人们的此类烦恼。一种可能的、牵强的理由是,jQuery 很大程度上以 CSS 作为其选择器的基础,并且即使是 W3C CSS Level 3 名称空间选择器也无法使它通过工作草案阶段。jQuery bug #155,“Get Namespaced Elements in XML Documents”,涵盖了这些问题,但是问题在 3 年之内没有得到解决。

Ryan Kelly 遇到此问题并做了一次大胆的尝试,为 XML Namespace Selector 创建了一个 jQuery 插件 jquery.xmlns.js。它试图支持以下代码。

$.xmlns["ex"] = "http://example.com";
$(doc).find("ex|quote").each(...);

第一行是对该插件的全局名称空间声明 — 由于底层 jQuery 机制的局限性。它的确用典型的 jQuery 用语为名称空间范围提供一个非全局块。 遗憾的是,我在使用这种扩展时成败参半。我希望它能够改变,并最终找到合适的方法进入 jQuery 。

一个更简单的插件

我最终选择的解决方案是创建一个简单插件,它不使用 jQuery 选择器做任何特殊工作,而是添加一个新的过滤器。您可以直接传递一个名称空间和本地名称到该过滤器,从而使结果集与节点匹配。请您按以下方法使用它:

$(xml).find('*').ns_filter('http://example.com', 'quote').each(function(){
 .each(function() {
  //process each node
 });

ns_filter 是我写的特殊过滤器。执行一个单独的 find('*') 的需求看起来可能不优雅,更简单的变化可能是:

$(xml).find('quote').ns_filter('http://example.com').each(function(){
 .each(function() {
  //process each node
 });

然而,这样做并不可行,因为您不能相信 jQuery 能够以名称空间中立(即作为本地名称选择器)的方式来处理查询,例如 find('quote')。我的过滤器实现将在下一节提供,作为安装 jQuery 来处理 XML 的一般系统的一部分。我在 Mac OS X Snow Leopard 操作系统下的 Firefox 3.5.5 和 Safari 4.0.4 ,以及 Windows® XP 操作系统最新的 Internet Explore 7 和 Internet Explorer 8 浏览器中对它进行了测试。

jQuery XML 工作台

名称空间问题只是以下事实的症状:说到底,jQuery 是一个 HTML 工具。我发现,使用 jQuery 处理 XML 最实用的方式就是为 XML 文档创建一个 HTML 工作台,通过可靠地跨浏览器方法引用脚本,然后建立需要的暂时性解决方案,例如针对 XML 名称空间问题的解决方案。您可以用工作台模式准备并测试您基于浏览器的 XML 处理的模式和技术,您甚至还可以把工作台作为基于浏览器的应用程序本身的基础。

清单 1 (quotes.html)是 HTML 使用工作台的简单例子。它能够动态地从 XML 文件加载引用。

极限网络办公Office Automation
极限网络办公Office Automation

专为中小型企业定制的网络办公软件,富有竞争力的十大特性: 1、独创 web服务器、数据库和应用程序全部自动傻瓜安装,建立企业信息中枢 只需3分钟。 2、客户机无需安装专用软件,使用浏览器即可实现全球办公。 3、集成Internet邮件管理组件,提供web方式的远程邮件服务。 4、集成语音会议组件,节省长途话费开支。 5、集成手机短信组件,重要信息可直接发送到员工手机。 6、集成网络硬

下载

清单 1 (quotes.html). 使用 jQuery XML 工作台的 HTML 例子


    


        jQuery XML workbench
        
        
        
        
    
    
    
    

A few quotations for your enjoyment


    

        

    您需要 script 元素来自动加载 jQuery、工作台 JavaScript 以及您的应用程序特定脚本。您还需要一个 link 元素来确定 target_XML 使用的 XML 文件。如果您需要使用多个 XML 文件,扩展工作台设置非常容易。清单 2(workbench.js)是工作台脚本。

    清单 2(workbench.js). jQuery XML 工作台 JavaScript

    /* 
    workbench.js
    */
    // The jQuery hook invoked once the DOM is fully ready
    $(document).ready(function(){
        // Get the target XML file contents (Ajax call)
        var fileurl = $("link[rel='target_XML']").attr('href');
      $.ajax({
        url: fileurl,
        type: "GET",
        dataType: "xml",
        complete: xml_ready,
        error: error_func
       });
    });

    // Callback for when the Ajax call results in an error
    function error_func(result) {
      alert(result.responseText);
    } 

    // ns_filter, a jQuery extension for XML namespace queries.
    (function($) {
     $.fn.ns_filter = function(namespaceURI, localName) {
      return $(this).filter(function() {
        var domnode = $(this)[0];
        return (domnode.namespaceURI == namespaceURI && domnode.localName == localName);
      });
     };

    })(jQuery);

    已经对工作台代码做了很好的注释,但这里还有一些需要注意的地方。名称空间过滤器是清单中最后一个函数。第一个函数是在主页 DOM 完全准备好之后调用一般的 jQuery hook。它为目标 XML 检索 URL,并调用 Ajax 来加载文件。注意,dataType: "xml" 命令 Ajax 机制来分析 XML 响应文件。如果出现错误,它将调用 error_func 回调函数,否则它将调用 xml_ready 回调函数,这是用户为实现应用程序行为而提供的。该回调函数使用了结果架构,您可以用responseXML 属性从中取回 XML 。清单 3(quotes.js)是这种情况下的应用程序代码。

    清单 3. (quotes.js)动态引用查看器的应用程序代码

    /* 
    quotes.js
    */
    function xml_ready(result){
      var xml = result.responseXML;
        //Make sure the target area for inserting data is clear
        $("#update-target ol").empty();
      $(xml).find('*').ns_filter('http://example.com', 'q').each(function(){
        var quote_text = $(this).text()

        $('

  1. ')
          .html(quote_text)
          .appendTo('#update-target ol');
      }); //close each(
    }

    清单 4 (quotes1.xml)是带有引用清单的 XML 文件。

    清单 4. (quotes1.xml)带有引用清单的 XML 文件



     Words have meaning and names have power
     Sticks and stones will break my bones, but names will never hurt me.
     The beginning of wisdom is to call things by their right names.
     Better to see the face than to hear the name. 

    请注意,我使用了 x 前缀,这意味着,理论上我可以尝试上文提到过的基于前缀的黑客方法。但是,如果我这样做,它将会被破坏,如果我用 清单 5(quotes2.xml)中的 quotes 文件代替,它是与 清单 4 完全相当的名称空间,以及相同的 Canonical XML。

    清单 5. (quotes2.xml)与清单 4 相当的 XML 文件,带有引用清单



     Words have meaning and names have power
     Sticks and stones will break my bones, but names will never hurt me.
     The beginning of wisdom is to call things by their right names.
     Better to see the face than to hear the name. 

    如果您替代 清单 1 中的 quotes2.xml,您将发现它还起作用,这是一个针对名称空间的重要测试。图 1 是 quotes.html 的浏览器显示。

    图 1. 使用 jQuery XML 工作台展示的引用

    Atom XML 的动态显示

    一旦您开始在 jQuery 中进行 XML 处理,您就能够处理更多有用的 XML 格式,包括 Web 提要格式,例如 RSS 和 Atom。在此部分我将使用 jQuery XML 工作台来显示来自一个 Web 页面上 Atom 提要的最新条目。清单 6 是 HTML 页面。

    清单 6. (home.html)托管动态 XML 的 Web 页面


        


            jQuery XML workbench
            
            
            
            
        
        
        
        

    Caesar's home page


        

    GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae,
      aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli
      appellantur. Hi omnes lingua, institutis, legibus inter se differunt.
      

      

    Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit.
      

      

    Horum omnium fortissimi sunt Belgae, propterea quod a cultu atque
      humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe
      commeant atque ea quae ad effeminandos animos pertinent important,
      proximique sunt Germanis, qui trans Rhenum incolunt, quibuscum continenter
      bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute
      praecedunt, quod fere cotidianis proeliis cum Germanis contendunt, cum aut 
      suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.

        

    My Web feed


        

        

    清单 7(atom1.xml)是引用的 Atom 文件。

    清单 7. (atom1.xml)Atom 文件示例


       xml:lang="en"
       xml:base="http://www.example.org">
     http://www.example.org/myfeed
     

    My Simple Feed
     2005-07-15T12:00:00Z
     
     
     Uche Ogbuji
     
      http://www.example.org/entries/1
      A simple blog entry
      
      2005-07-14T12:00:00Z
      This is a simple blog entry
     

     
      http://www.example.org/entries/2
      
      
      2005-07-15T12:00:00Z
      This is simple blog entry without a title
     


    清单 8 是 home.js,包含了加载到工作台上的动态应用程序代码。

    清单 8. (home.js)主页 Web 提要显示的应用程序代码

    /* 
    home.js
    */
    var ATOM_NS = 'http://www.w3.org/2005/Atom';

    function xml_ready(result){
      var xml = result.responseXML;
        //Make sure the target area for inserting data is clear
        $("#update-target").empty();
      $(xml).find('*').ns_filter(ATOM_NS, 'entry').each(function(){
        var title_elem = $(this).find('*').ns_filter(ATOM_NS, 'title').clone();
        var link_text = $(this).find('[rel="alternate"]')
                  .ns_filter(ATOM_NS, 'link')
                  .attr('href');
        var summary_elem = $(this).find('*').ns_filter(ATOM_NS, 'summary').clone();

        //Deal with the case of a missing title
        if (!title_elem.text()){
          title_elem = '[No title]';
        } 

        //Deal with the case where rel='alternate' is omitted 
        if (!link_text){
          link_text = $(this).find('*')
                    .ns_filter(ATOM_NS, 'link')
                    .not('[rel]')
                    .attr('href');
        } 

        //Update the target area with the entry information
        $('

    ')
          .append(
            $('')
            .append(title_elem)
          )
          .append(' - ')
          .append(summary_elem.clone())
          .fadeIn('slow') //bonus animation
          .appendTo('#update-target');
      }); //close each(
    }

    同样,我对该文件进行了注释,但是有几点值得特别强调。Atom 有许多可以接受的元素变体,其中多数是可选的。这就意味着您必须对异常情况进行处理。我举两个常见的异常情况:在一个必须的链接上的可选 rel="alternate";标题是可选的这一事实。正如您所看到的,jQuery 提供了处理这些情况的巨大灵活性,因此您甚至应该能够处理这种不规则的 XML 格式。在某些情况下,我直接从 XML 将结构复制到主文档(托管 HTML)。这需要非常小心,并且您会发现我使用了 clone() 方法,以确保我没有将某个文档的节点嫁接到另一个文档,否则 DOM 异常 WRONG_DOCUMENT_ERR 将会发出一个错误。另外,我使用了 jQuery 方法 fadeIn,以便添加的内容会慢慢从视线中消失。图 2 是 home.html 的浏览器显示。

     以上就是使用jQuery在浏览器中处理XML,更多相关文章请关注PHP中文网(www.php.cn)! 

  2. 相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    相关专题

    更多
    php源码安装教程大全
    php源码安装教程大全

    本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

    203

    2025.12.31

    php网站源码教程大全
    php网站源码教程大全

    本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

    111

    2025.12.31

    视频文件格式
    视频文件格式

    本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

    124

    2025.12.31

    不受国内限制的浏览器大全
    不受国内限制的浏览器大全

    想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

    93

    2025.12.31

    出现404解决方法大全
    出现404解决方法大全

    本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

    664

    2025.12.31

    html5怎么播放视频
    html5怎么播放视频

    想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

    19

    2025.12.31

    关闭win10系统自动更新教程大全
    关闭win10系统自动更新教程大全

    本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

    15

    2025.12.31

    阻止电脑自动安装软件教程
    阻止电脑自动安装软件教程

    本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

    6

    2025.12.31

    html5怎么使用
    html5怎么使用

    想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

    3

    2025.12.31

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Django 教程
    Django 教程

    共28课时 | 2.7万人学习

    SciPy 教程
    SciPy 教程

    共10课时 | 1.0万人学习

    Sass 教程
    Sass 教程

    共14课时 | 0.7万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号