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

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    go语言 注释编码
    go语言 注释编码

    本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

    2

    2026.01.31

    go语言 math包
    go语言 math包

    本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

    1

    2026.01.31

    go语言输入函数
    go语言输入函数

    本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

    1

    2026.01.31

    golang 循环遍历
    golang 循环遍历

    本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

    0

    2026.01.31

    Golang人工智能合集
    Golang人工智能合集

    本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

    1

    2026.01.31

    2026赚钱平台入口大全
    2026赚钱平台入口大全

    2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

    76

    2026.01.31

    高干文在线阅读网站大全
    高干文在线阅读网站大全

    汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

    73

    2026.01.31

    无需付费的漫画app大全
    无需付费的漫画app大全

    想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

    67

    2026.01.31

    漫画免费在线观看地址大全
    漫画免费在线观看地址大全

    想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

    19

    2026.01.31

    热门下载

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

    精品课程

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

    共28课时 | 3.7万人学习

    SciPy 教程
    SciPy 教程

    共10课时 | 1.3万人学习

    Sass 教程
    Sass 教程

    共14课时 | 0.8万人学习

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

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