使用 jQuery 遍历 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1574113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping through XML with jQuery
提问by CBarr
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.
我有一些基本的代码,可以循环遍历从 Adobe RoboHelp 生成的一些 XML(用于我们的帮助文档)。这工作正常,但由于可以根据作者的需要多次嵌套主题,因此我需要一种更好的方法来遍历此 XML,而不仅仅是嵌套.each()
循环。
Here's what the XML looks like
这是 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>
is an article, and a <book>
is a folder.
A<page>
是文章,a<book>
是文件夹。
Her's my jQuery code, which only can look one level deep of tags
她是我的 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 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!
任何帮助是极大的赞赏!
回答by keithm
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);
});
回答by meder omuraliev
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?
$(el).children().length
这将返回“0”或一个正数,如果它是一个评估为真的正数,则循环遍历。您也可以使用 while 循环来递归地执行此操作,并重新设置引用处理程序,但是我不太确定这是否可行,因为每个后续子项的 nodeNames 都不同(或者它们是否不同?).. 嵌套最多的是什么你能提供的例子吗?
回答by CBarr
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.
你会注意到我所做的只是在外面声明变量$.get()
,然后我使用$xml.children().each(processXml);
而不是$(this).find("page").each(processXml);
你拥有的变量。
The reason for this is that the children could be pages ORbooks, but what you had was limiting it to only pages.
这样做的原因是孩子们可以是页面或书籍,但您所拥有的只是将其限制为页面。
Thanks again!
再次感谢!
回答by Ima
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 迭代的好例子 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');
}
})
});
回答by Sanjeev Satheesh
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 :-)
这里有一些可以赢得更多赞誉的东西。我将其设为匿名函数调用,并使用 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>");
});