2009-10-15 5 views
6

저는 Adobe RoboHelp (도움말 문서 용)에서 생성 된 일부 XML을 반복 할 수있는 기본 코드를 가지고 있습니다. 이것은 잘 작동하지만, 주제가 작성자가 원하는만큼 중첩 될 수 있기 때문에, 나는 단지 .each() 루프를 중첩하는 것이 아니라이 XML을 반복하는 좋은 방법이 필요하다.jQuery로 XML 반복하기

다음은 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> 

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

내가 더 좋은 방법은 그냥 루프는 모든 요소를 ​​통해 거기 알고 요소가 어린이 등하지만이있는 경우 다음 결정 그것을하는 방법을 생각할 수 없다.

도움을 주시면 대단히 감사하겠습니다.

+1

그냥 궁금 해서요. 왜 클라이언트에서이 작업을 수행해야합니까? XSLT 변환을 서버에 적용하고 HTML을 보내지 않는 이유는 무엇입니까? xml은 동적입니까? 변환 된 html을 서버에 캐시 할 수 없습니까? –

+0

상관없이 해결책을 찾았 기 때문에 기쁘다 - 지금 키스 동의를 받아 들인다. –

+0

나는 환멸을 느낀다! 이것은 단지 개념의 증거였습니다 .... 실제로 저는 사람들에게 깊은 감명을주고 싶었습니다. 그들은 나를 칭찬과 함께 샤워하고 있으므로 가치가 있습니다. 결국 우리는이 서버 측을 수행 할 것이라고 생각합니다. –

답변

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); 
}); 
1

당신은 참으로 평가 양수의 경우를 통해

반환

$(el).children().length '0'또는 양수, 다음 루프를 사용할 수 있습니다. while 루프를 사용하여 재귀 적으로이 작업을 수행하고 참조 핸들러를 다시 설정할 수도 있지만 이후의 각 하위 노드에 대한 nodeNames가 다르거 나 (또는 ​​그렇다고해서) 작동하지 않을 것이라고 확신하지는 않습니다. 가장 중첩 된 것은 무엇입니까? 예를 들면?

+0

아니요, 노드 이름은 또는 입니다. 페이지는 책 안팎에 존재할 수 있습니다. 책은 다른 책이나 페이지를 포함 할 수 있습니다. 위에 게시 된 XML에는 2 권의 책 부모가있는 페이지가 있습니다. –

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);의 사용합니다.

이유는 아이들이 또는 권의 도서 일 수 있지만 그 책을 페이지로만 제한하는 것이었기 때문입니다.

다시 한번 감사드립니다!

+2

내 대답을 수락 해 주셔서 감사합니다! 부수적으로, 나의 목표는 귀하의 모든 문제를 해결하는 것이 아니라 귀하의 질문에 논리를 복제하는 것이 었습니다. 또한 makeToc()에 변수 선언을 배치하는 것이 가장 좋은 방법입니다. 그런 식으로하면 변수가 makeToc을 사용하여 결과를 누적하는 것임을 분명히 알 수 있습니다. – keithm

0

다음은 더 많은 칭찬을 얻는 방법입니다. 나는 그것을 익명의 함수 호출로 만들었고 arguments.callee를 사용하여 재귀했다. 나 자신이 방법을 찾고 있었다, 유래에서이 다른 스레드가 저를 도와 내가 다시 지불하고 싶지 :-)

$.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>"); 
}); 
1

이 링크는 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'); 
     } 
    }) 

});