6

Adobe RoboHelpから生成された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>は記事、a<book>はフォルダです。

彼女は私のjQueryコードであり、タグの1レベルの深さしか見ることができません

   //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);

すべての要素をループして、要素に子があるかどうかなどを判断するより良い方法があることは知っていますが、その方法を考えることはできません。

どんな助けでも大歓迎です!

4

5 に答える 5

9

これには再帰関数が適しています。内部再帰クロージャを作成して使用する関数を作成すると、すべてをきちんとした小さなパッケージにまとめることができます。

    $.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);
});
于 2009-10-15T21:55:02.110 に答える
1

キースに感謝します。それがチケットでした。ほとんどの場合、マイナーな変更を1つ行う必要がありましたが、それで完全に機能しました。

私のコードは以下の通りです。

$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);

これは、子がページまたは本である可能性があるためですが、あなたが持っていたのはページのみに制限されていたためです。

再度、感謝します!

于 2009-10-15T23:28:39.313 に答える
1

使用できます

$(el).children().lengthこれは「0」または正の数を返し、それがtrueと評価される正の数である場合はループします。whileループを使用してこれを再帰的に実行し、参照ハンドラーを再設定することもできますが、後続の各子のnodeNamesが異なるため(またはそれらは異なりますか?)..最もネストされているものは何ですか?あなたが提供できる例?

于 2009-10-15T18:21:51.113 に答える
1

このリンクは、xmlhttp://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');
        }
    })

});
于 2012-02-04T19:42:57.790 に答える
0

ここにもう少し賞賛を得る何かがあります。これを無名関数呼び出しにし、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>");
});
于 2010-10-08T05:01:50.510 に答える