以下几乎可以正常工作,但如果我删除<a>
json中断了一个空节点name:" "
,而且我相信我正在创建一个数组,而我需要下面格式的json。这里也是jsFiddle(参见下面我正在寻找的输出的结果)。
我要做的是生成一个我可以从嵌套列表中读取的对象,以生成思维导图(D3)like this
HTML
<div id="tree">
<ul class="sortable">
<li><a href="http://google.com">flare</a>
<ul class="sortable">
<li>analytics
<ul class="sortable">
<li><a href="http://google.com">cluster</a>
<ul class="sortable">
<li><a href="http://google.com">AgglomerativeCluster</a></li>
<li><a href="http://google.com">CommunityStructure</a></li>
<li><a href="http://google.com">HierarchicalCluster</a></li>
<li><a href="http://google.com">MergeEdge</a></li>
</ul>
</li>
<li><a href="http://google.com">graph</a>
<ul class="sortable">
<li><a href="http://google.com">BetweennessCentrality</a></li>
<li><a href="http://google.com">LinkDistance</a></li>
<li><a href="http://google.com">MaxFlowMinCut</a></li>
<li><a href="http://google.com">ShortestPaths</a></li>
<li><a href="http://google.com">SpanningTree</a></li>
</ul>
</li>
<li><a href="http://google.com">optimization</a>
<ul class="sortable">
<li><a href="http://google.com">AspectRatioBanker</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="http://google.com">Pippo</a></li>
<li><a href="http://google.com">buonanotte</a></li>
<li><a href="http://google.com">Avantieri</a></li>
</ul>
</div>
<div id="d" style="margin-top: 40px; padding-top: 20px;">Output:<br><br><pre></pre></div>
<div id="d" style="margin-top: 40px; padding-top: 20px;">Output:<br><br><pre></pre></div>
<div id="json_results" style="margin-top: 40px; padding-top: 20px;">
Needs to become:
<pre style="padding-top: 20px;">
var root = JSON.parse( ' {
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster","url":"http://google.com"},
{"name": "CommunityStructure"},
{"name": "HierarchicalCluster"},
{"name": "MergeEdge"}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality" },
{"name": "LinkDistance" },
{"name": "MaxFlowMinCut" },
{"name": "ShortestPaths" },
{"name": "SpanningTree" }
]
},
{
"name": "optimization",
"children": [
{"name": "AspectRatioBanker" }
]
}
]
},
{"name": "Pippo"},
{"name": "buonanotte" },
{"name": "Avantieri"}
]
} ') ;
</pre>
</div>
JS
$(document).ready(function () {
var out = [];
function processOneLi(node) {
var aNode = node.children("a:first");
var retVal = {
"name": aNode.text(),
"url": aNode.attr("href")
};
node.find("> .sortable > li").each(function() {
if (!retVal.hasOwnProperty("children")) {
retVal.children = [];
}
retVal.children.push(processOneLi($(this)));
});
return retVal;
}
$("#tree > ul > li").each(function() {
out.push(processOneLi($(this)));
});
$('#d pre').text(JSON.stringify(out, null, 2));
});
json应该成为:
var root = JSON.parse( ' {
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster","url":"http://google.com"},
{"name": "CommunityStructure"},
{"name": "HierarchicalCluster"},
{"name": "MergeEdge"}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality" },
{"name": "LinkDistance" },
{"name": "MaxFlowMinCut" },
{"name": "ShortestPaths" },
{"name": "SpanningTree" }
]
},
{
"name": "optimization",
"children": [
{"name": "AspectRatioBanker" }
]
}
]
},
{"name": "Pippo"},
{"name": "buonanotte" },
{"name": "Avantieri"}
]
} ') ;
但这就是我所得到的:
[
{
"name": "flare",
"url": "http://google.com",
"children": [
{
"name": "",
"children": [
{
"name": "cluster",
"url": "http://google.com",
"children": [
{
"name": "AgglomerativeCluster",
"url": "http://google.com"
},
{
"name": "CommunityStructure",
"url": "http://google.com"
},
{
"name": "HierarchicalCluster",
"url": "http://google.com"
},
{
"name": "MergeEdge",
"url": "http://google.com"
}
]
},
{
"name": "graph",
"url": "http://google.com",
"children": [
{
"name": "BetweennessCentrality",
"url": "http://google.com"
},
{
"name": "LinkDistance",
"url": "http://google.com"
},
{
"name": "MaxFlowMinCut",
"url": "http://google.com"
},
{
"name": "ShortestPaths",
"url": "http://google.com"
},
{
"name": "SpanningTree",
"url": "http://google.com"
}
]
},
{
"name": "optimization",
"url": "http://google.com",
"children": [
{
"name": "AspectRatioBanker",
"url": "http://google.com"
}
]
}
]
}
]
},
{
"name": "Pippo",
"url": "http://google.com"
},
{
"name": "buonanotte",
"url": "http://google.com"
},
{
"name": "Avantieri",
"url": "http://google.com"
}
]
这是jsFiddle(见下面我要找的输出结果)
答案 0 :(得分:1)
一个小的递归函数可以:
function listToObject(list) {
return $(list).first().children("li").map(function () {
var $this = $(this), $name = $this.children("a").first();
return {
// see http://stackoverflow.com/a/8851526
name: $name.text() || $this.clone().children().remove().end().text().trim(),
url: $name.attr("href"),
children: listToObject($this.children("ul"))
};
}).toArray();
}
var output = listToObject($("#tree > ul"));
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tree">
<ul class="sortable">
<li><a href="http://google.com">flare</a>
<ul class="sortable">
<li>analytics
<ul class="sortable">
<li><a href="http://google.com">cluster</a>
<ul class="sortable">
<li><a href="http://google.com">AgglomerativeCluster</a></li>
<li><a href="http://google.com">CommunityStructure</a></li>
<li><a href="http://google.com">HierarchicalCluster</a></li>
<li><a href="http://google.com">MergeEdge</a></li>
</ul>
</li>
<li><a href="http://google.com">graph</a>
<ul class="sortable">
<li><a href="http://google.com">BetweennessCentrality</a></li>
<li><a href="http://google.com">LinkDistance</a></li>
<li><a href="http://google.com">MaxFlowMinCut</a></li>
<li><a href="http://google.com">ShortestPaths</a></li>
<li><a href="http://google.com">SpanningTree</a></li>
</ul>
</li>
<li><a href="http://google.com">optimization</a>
<ul class="sortable">
<li><a href="http://google.com">AspectRatioBanker</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="http://google.com">Pippo</a></li>
<li><a href="http://google.com">buonanotte</a></li>
<li><a href="http://google.com">Avantieri</a></li>
</ul>
</div>
输出比你要求的要严格得多。每个对象都有一个url
和children
,即使是空的。这实际上最终会使处理变得更容易。
答案 1 :(得分:0)
我发现了你的问题,有一个li元素没有你想要的元素。
这将为您提供您正在寻找的结果
$(document).ready(function () {
var out = [];
function processOneLi(node) {
var aNode = node.children("a:first");
var retVal = {};
if (aNode.text()) {
retVal = {
"name": aNode.text(),
"url": aNode.attr("href")
};
} else {
retVal = { "name": node.clone().children().remove().end().text().replace(/\r?\n|\r/g, " ") };
}
node.find("> .sortable > li").each(function() {
if (!retVal.hasOwnProperty("children")) {
retVal.children = [];
}
retVal.children.push(processOneLi($(this)));
});
return retVal;
}
$("#tree > ul > li").each(function() {
out.push(processOneLi($(this)));
});
$('#d pre').text(JSON.stringify(out, null, 2));
});
答案 2 :(得分:0)
你的问题是Pippo,buonanotte和Avantieri是耀斑的兄弟姐妹,而不是在耀斑下嵌套。
我想我得到了你在这个小提琴中所期望的结果:http://jsfiddle.net/k7vSg/122/
<强> HTML:强>
<div id="tree">
<ul class="sortable">
<li><a href="http://google.com">flare</a>
<ul class="sortable">
<li>analytics
<ul class="sortable">
<li><a href="http://google.com">cluster</a>
<ul class="sortable">
<li><a href="http://google.com">AgglomerativeCluster</a></li>
<li><a href="http://google.com">CommunityStructure</a></li>
<li><a href="http://google.com">HierarchicalCluster</a></li>
<li><a href="http://google.com">MergeEdge</a></li>
</ul>
</li>
<li><a href="http://google.com">graph</a>
<ul class="sortable">
<li><a href="http://google.com">BetweennessCentrality</a></li>
<li><a href="http://google.com">LinkDistance</a></li>
<li><a href="http://google.com">MaxFlowMinCut</a></li>
<li><a href="http://google.com">ShortestPaths</a></li>
<li><a href="http://google.com">SpanningTree</a></li>
</ul>
</li>
<li><a href="http://google.com">optimization</a>
<ul class="sortable">
<li><a href="http://google.com">AspectRatioBanker</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="http://google.com">Pippo</a></li>
<li><a href="http://google.com">buonanotte</a></li>
<li><a href="http://google.com">Avantieri</a></li>
</ul>
</li>
</ul>
</div>
<div id="d" style="margin-top: 40px; padding-top: 20px;">Output:<br><br><pre></pre></div>
<div id="json_results" style="margin-top: 40px; padding-top: 20px;">
Needs to become:
<pre style="padding-top: 20px;">
var root = JSON.parse( ' {
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster","url":"http://google.com"},
{"name": "CommunityStructure"},
{"name": "HierarchicalCluster"},
{"name": "MergeEdge"}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality" },
{"name": "LinkDistance" },
{"name": "MaxFlowMinCut" },
{"name": "ShortestPaths" },
{"name": "SpanningTree" }
]
},
{
"name": "optimization",
"children": [
{"name": "AspectRatioBanker" }
]
}
]
},
{"name": "Pippo"},
{"name": "buonanotte" },
{"name": "Avantieri"}
]
} ') ;
</pre>
</div>
<强> JS:强>
$(document).ready(function () {
var out = [];
function processOneLi(node) {
var aNode = node.children("a:first");
var retVal = {
"name": aNode.text(),
"url": aNode.attr("href")
};
node.find("> .sortable > li").each(function() {
if (!retVal.hasOwnProperty("children")) {
retVal.children = [];
}
retVal.children.push(processOneLi($(this)));
});
return retVal;
}
$("#tree > ul > li").each(function() {
out.push(processOneLi($(this)));
});
$('#d pre').text(JSON.stringify(out[0], null, 2));
});