代码之家  ›  专栏  ›  技术社区  ›  Chris Barr

使用jquery循环XML

  •  6
  • Chris Barr  · 技术社区  · 15 年前

    我有一些基本的代码可以循环使用一些由AdobeRobohelp生成的XML(用于我们的帮助文档)。这很好,但是由于主题可以按照作者的需要嵌套任意多个时间,所以我需要一种更好的方法来循环此XML,而不仅仅是嵌套 .each() 循环。

    以下是XML的外观

    <?xml version="1.0" encoding="utf-8"?>
    <!--RoboML: Table of Content-->
    <roboml_toc>
      <page title="Welcome" url="Welcome.htm"/>
     <book title="Getting Started" url="Getting_Started/Initial_Setup.htm">
       <page title="Initial Setup" url="Getting_Started/Initial_Setup.htm"/>
       <page title="Customize Settings" url="Getting_Started/Settings.htm"/>
     </book>
     <book title="Administrator Services" url="Administrator_Services/General_Administrator.htm">
      <book title="Portal Workspace" url="Administrator_Services/Portal_Workspace/AdminHome.htm">
        <page title="Home" url="Administrator_Services/Portal_Workspace/AdminHome.htm"/>
        <page title="Portal Accounts" url="Administrator_Services/Portal_Workspace/Portal_Accounts.htm"/>
    
      </book>
      <book title="SpamLab" url="Administrator_Services/SpamLab/SpamLab_Admin_General.htm">
        <page title="Alerts" url="Administrator_Services/SpamLab/Alerts.htm"/>
        <page title="Spam Quarantine" url="Administrator_Services/SpamLab/Admin_Spam_Quarantine_.htm"/>
    
      </book>
    
     </book>
     <book title="User Services" url="User_Services/General_User.htm">
      <book title="Portal Workspace" url="User_Services/Portal_Workspace/Home.htm">
        <page title="Home" url="User_Services/Portal_Workspace/Home.htm"/>
        <page title="Self Help" url="User_Services/Portal_Workspace/Self_Help.htm"/>
      </book>
      <book title="SpamLab" url="User_Services/SpamLab/SpamLab_General.htm">
        <page title="Spam Quarantine" url="User_Services/SpamLab/Spam_Quarantine.htm"/>
        <page title="Virus Quarantine" url="User_Services/SpamLab/Virus_Quarantine.htm"/>
      </book>
    
      <book title="Encryption" url="User_Services/Encryption/Encryption_General.htm">
        <page title="Outlook Plug-in" url="User_Services/Encryption/Encryption_Outlook_Plug_in.htm"/>
      </book>
     </book>
    </roboml_toc>
    

    A <page> 是一篇文章,和 <book> 是一个文件夹。

    她是我的jquery代码,只能看到一个层次的标签

       //Get the TOC
    $tocOutput="";
    $.get(tocURL,function(toc){
        $(toc).children().each(function(){
            $tocOutput+="<li><a href='"+$(this).attr("url")+"'>"+$(this).attr("title")+"</a>";
            if(this.tagName=="BOOK"){
                $tocOutput+="<ul>";
                $(this).find("page").each(function(){
                    $tocOutput+="<li><a href='"+$(this).attr("url")+"'>"+$(this).attr("title")+"</a></li>";
                });
                $tocOutput+="</ul>";
            }
            $tocOutput+="</li>";
        });
        $("#list").html($tocOutput);
    

    我知道有一种更好的方法可以循环遍历所有元素,然后确定元素是否有子元素,等等,但我就是想不出该怎么做。

    非常感谢您的帮助!

    5 回复  |  直到 10 年前
        1
  •  9
  •   keithm    15 年前

    递归函数在这方面工作得很好。当您创建一个创建并使用内部递归闭包的函数时,您可以将它包装在一个整洁的小包中:

        $.get(tocURL, function(toc) {
        function makeToc($xml) {
            // variable to accumulate markup
            var markup = "";
            // worker function local to makeToc
            function processXml() {
                markup += "<li><a href='" + $(this).attr("url") + "'>" + $(this).attr("title") + "</a>";
                if (this.nodeName == "BOOK") {
                    markup += "<ul>";
                    // recurse on book children
                    $(this).find("page").each(processXml);
                    markup += "</ul>";
                }
                markup += "</li>";
            }
            // call worker function on all children
            $xml.children().each(processXml);
            return markup;
        }
        var tocOutput = makeToc($(toc));
        $("#list").html(tocOutput);
    });
    
        2
  •  1
  •   meder omuraliev    15 年前

    你可以用

    $(el).children().length 它将返回“0”或正数,然后如果正数的计算结果为真,则循环通过。您也可以使用while循环来递归地执行此操作,并重新设置引用处理程序,但是我不太确定这是否可行,因为您的每个后续子代的节点名都不同(或是它们?)…你能提供的最嵌套的例子是什么?

        3
  •  1
  •   Chris Barr    15 年前

    非常感谢基思,那就是门票——好吧,几乎,我必须做一个小小的改变,然后它完美地工作了!

    我的代码在下面。

    $tocOutput="";
    $.get(tocURL,function(toc){
     function makeToc($xml) {
      // worker function local to makeToc
      function processXml() {
       console.log($(this));
       $tocOutput += "<li><a href='" + $(this).attr("url") + "'>" + $(this).attr("title") + "</a>";
       if (this.nodeName == "BOOK") {
        $tocOutput += "<ul>";
        // recurse on book children
        $(this).children().each(processXml);
        $tocOutput += "</ul>";
       }
       $tocOutput += "</li>";
      }
      // call worker function on all children
      $xml.children().each(processXml);
     }
     var tocOutput = makeToc($(toc));
     $("#toc").html($tocOutput);
     completed($("#toc"));
    });
    

    您会注意到我所做的就是在 $.get() 然后我用 $xml.children().each(processXml); 而不是 $(this).find("page").each(processXml); 你曾经拥有的。

    这样做的原因是孩子们可能是一页纸 书,但你只限于几页。

    再次感谢!

        4
  •  1
  •   Ima    10 年前

    这个链接提供了一个很好的例子,可以使用迭代XML http://anasthecoder.blogspot.in/2012/02/looping-through-xml-with-jquery.html

    xml.find('result').find('permissionDetails').each(function(){
        $(this).children().each(function(){
            var tagName=this.tagName;
            var val=$(this).text();
            if(val==1){
                $('input:checkbox[name='+tagName+']').attr('checked',true);
            }
            else if(val==0){
                $('input:checkbox[name='+tagName+']').removeAttr('checked');
            }
        })
    
    });
    
        5
  •  0
  •   Sanjeev Satheesh    14 年前

    这里有一些东西可以赢得更多的赞誉。我做了一个匿名函数调用,并使用arguments.callee来递归。我自己在找这个方法,StackOverflow的这个线程和另一个线程帮助我解决了这个问题,我想把它还回去:—)

    $.get(tocURL,function(data){
        var markup = "<ul>";
        $(data).each(function(){
            markup += "<li><a href='" + $(this).attr("url") + "'>" + $(this).attr("title") + "</a>";
            if (this.nodeName == "BOOK") {
                $markup += "<ul>";
                $(this).children().each(arguments.callee);    
                $markup += "</ul>";
            }
            markup += "</li>";
        });
        $("#list").html(markup+"</ul>");
    });