使用 jQuery 循环 XML
我有一些基本代码,可以循环处理从 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>
是一篇文章,
是一个文件夹。
她是我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
递归函数对此很有效。当您创建一个创建并使用内部递归闭包的函数时,您可以将其全部包装在一个整洁的小包中:
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:
您可以使用
$(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?非常感谢基思,这就是门票 - 好吧,几乎,我必须做一个小改变,然后它就完美了!
我的代码如下。
您会注意到我所做的只是在
$.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.
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!
此链接提供了一个使用 xml 迭代的好示例
http://anasthecoder.blogspot.in/2012/02 /looping-through-xml-with-jquery.html
This link provides a good example for use of iterating through xml
http://anasthecoder.blogspot.in/2012/02/looping-through-xml-with-jquery.html
这是值得更多赞扬的事情。我将其设为匿名函数调用,并使用arguments.callee 进行递归。我自己也在寻找这个方法,stackoverflow 上的这个和另一个线程帮助了我,我想偿还它:-)
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 :-)