使用 jQuery 循环 XML

发布于 2024-08-08 02:37:03 字数 2995 浏览 14 评论 0原文

我有一些基本代码,可以循环处理从 Adob​​e 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>

是一篇文章, 是一个文件夹。

她是我的 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);

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

非常感谢任何帮助!

I've got some basic code that can loop through some XML that's generated from Adobe RoboHelp (for our help documentation). This works fine, but since a topic could be nested as many time as the writer wants, i need a better way to loop through this XML rather than just nesting .each() loops.

Here's what the XML looks like

<?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> is an article, and a <book> is a folder.

Her's my jQuery code, which only can look one level deep of tags

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

I know there's a better way to just loop through all elements and then determine if the element has children, etc. but I just can't think of how to do it.

Any help is greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

阪姬 2024-08-15 02:37:03

递归函数对此很有效。当您创建一个创建并使用内部递归闭包的函数时,您可以将其全部包装在一个整洁的小包中:

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

Recursive functions work well for this. When you create a function that creates and uses an internal recursive closure you can wrap it all up in a neat little package:

    $.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);
});
旧伤还要旧人安 2024-08-15 02:37:03

您可以使用

$(el).children().length ,它会返回“0”或正数,然后循环遍历(如果它是计算结果为 true 的正数)。您还可以使用 while 循环递归地执行此操作,并重新设置引用处理程序,但是我不太确定这是否有效,因为每个后续子级的 nodeName 都不同(或者它们不同吗?).. 什么是最嵌套的你可以提供例子吗?

You can use

$(el).children().length which would return '0' or a positive number, then loop through if it's a positive number which evaluates to true. You could also use a while loop to do this recursively, and re-set the reference handler however I'm not quite sure that would work out because your nodeNames for each subsequent child differ ( or do they? ) .. What's the most nested example you can provide?

陌若浮生 2024-08-15 02:37:03

非常感谢基思,这就是门票 - 好吧,几乎,我必须做一个小改变,然后它就完美了!

我的代码如下。

$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);
你有过。

这样做的原因是子项可能是页面书籍,但您所拥有的只是将其限制为页面。

再次感谢!

THanks so much Keith, that was the ticket - well almost, I had to make one MINOR change and then it worked perfectly!

My code is below.

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

You'll notice all I'm doing is declaring the variable outside the $.get() and then I use $xml.children().each(processXml); instead of $(this).find("page").each(processXml);
that you had.

The reason for this is that the children could be pages OR books, but what you had was limiting it to only pages.

Thanks again!

瑾夏年华 2024-08-15 02:37:03

此链接提供了一个使用 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');
        }
    })

});

This link provides a good example for use of iterating through 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');
        }
    })

});
入画浅相思 2024-08-15 02:37:03

这是值得更多赞扬的事情。我将其设为匿名函数调用,并使用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>");
});

Here's something to earn some more praise. I made it an anonymous function call, and used the arguments.callee to recurse. I was myself looking for this method, this and another thread at stackoverflow helped me out and I want to pay it back :-)

$.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>");
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文