我的食品开发应用程序要求将XML树压平。听起来很简单,但我遇到了麻烦。该算法要求所有<stream>...</stream>
节点和一个子<disposition>Break out overall</disposition>
节点到顶层<root>...</root>
节点。
<root>
<stream>
<name>Corn Oil</name>
<quantity>0.3</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Potatoes</name>
<quantity>0.5</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Seasoning</name>
<quantity>0.1</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
<stream>
<name>Salt</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Maltodextrin</name>
<quantity>0.03</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Spice Blend</name>
<quantity>0.04</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
<stream>
<name>Black Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Garlic</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Red Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
</stream>
</stream>
</root>
<root>
<stream>
<name>Corn Oil</name>
<quantity>0.3</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Potatoes</name>
<quantity>0.5</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Seasoning</name>
<quantity>0.1</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
</stream>
<stream>
<name>Salt</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Maltodextrin</name>
<quantity>0.03</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Spice Blend</name>
<quantity>0.04</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
</stream>
<stream>
<name>Black Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Garlic</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Red Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
</root>
<root>
<stream>
<name>Corn Oil</name>
<quantity>0.3</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Potatoes</name>
<quantity>0.5</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Seasoning</name>
<quantity>0.1</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
<stream>
<name>Salt</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Maltodextrin</name>
<quantity>0.03</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Spice Blend</name>
<quantity>0.04</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
<stream>
<name>Black Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Garlic</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Red Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
</stream>
</stream>
<stream>
<name>Salt</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Maltodextrin</name>
<quantity>0.03</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Spice Blend</name>
<quantity>0.04</quantity>
<disposition>Break out overall</disposition>
<isstream>true</isstream>
<stream>
<name>Black Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Garlic</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Red Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
</stream>
<stream>
<name>Black Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Garlic</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
<stream>
<name>Red Pepper</name>
<quantity>0.02</quantity>
<disposition>Break out overall</disposition>
</stream>
</root>
下面JsFiddle处的算法与顶级流,玉米油,土豆和调味料完全一样,可以按需删除<stream>...</stream>
节点下的每个<root>...</root>
节点并追加它返回到<root>...</root>
节点下。但是,对于公式中的所有其他嵌套<stream>...</stream>
节点(香料混合,麦芽糊精,盐,红辣椒,大蒜,黑胡椒),算法的$(this).remove()
部分无效,即这些流被复制到<root>...</root>
节点,但原始节点未删除。
var xmlAsStr = "<root><stream><name>Corn Oil</name><quantity>0.3</quantity><disposition>Break out overall</disposition></stream><stream><name>Potatoes</name><quantity>0.5</quantity><disposition>Break out overall</disposition></stream><stream><name>Seasoning</name><quantity>0.1</quantity><disposition>Break out overall</disposition><isstream>true</isstream><stream><name>Salt</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Maltodextrin</name><quantity>0.03</quantity><disposition>Break out overall</disposition></stream><stream><name>Spice Blend</name><quantity>0.04</quantity><disposition>Break out overall</disposition><isstream>true</isstream><stream><name>Black Pepper</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Garlic</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Red Pepper</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream></stream></stream></root>";
var xmlDoc = $.parseXML( xmlAsStr );
var $xml = $( xmlDoc );
$('stream',$xml).each(function(){
if($(this).children('disposition').text()=="Break out overall" )
{
var thisHtml = $(this).html();
$(this).remove();
$xml.find('root').append('<stream>'+thisHtml+'</stream>');
}
});
除了$(this).remove();
之外,我还尝试过:
$xml.find('root').find(this).remove();
$xml.find(this).remove();
$(this,$xml).remove();
但是从XML树中删除这些嵌套节点似乎无济于事。
对于如何完成上述XML操作的任何帮助或见解将不胜感激。谢谢。
答案 0 :(得分:1)
自下而上的递归算法可以按预期方式平整XML树。我最初的错误是试图仅依靠jQuery隐式迭代和遍历来解决此问题,而无需显式递归。下面提供了已解决的代码以及有效的jsFiddle供您参考。抱歉给您打扰,问题已解决。非常感谢。
$(function(){
var xmlAsStr = "<root><stream><name>Corn Oil</name><quantity>0.3</quantity><disposition>Break out overall</disposition></stream><stream><name>Potatoes</name><quantity>0.5</quantity><disposition>Break out overall</disposition></stream><stream><name>Seasoning</name><quantity>0.1</quantity><disposition>Break out overall</disposition><isstream>true</isstream><stream><name>Salt</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Maltodextrin</name><quantity>0.03</quantity><disposition>Break out overall</disposition></stream><stream><name>Spice Blend</name><quantity>0.04</quantity><disposition>Break out overall</disposition><isstream>true</isstream><stream><name>Black Pepper</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Garlic</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream><stream><name>Red Pepper</name><quantity>0.02</quantity><disposition>Break out overall</disposition></stream></stream></stream></root>";
var xmlDoc = $.parseXML( xmlAsStr );
var $xml = $( xmlDoc );
var $myResultingXml;
var streamNodeArray = [];
$('root',$xml).children('stream').each(function(){
streamNodeArray.push($(this));
});
var i = 0;
for(i=0;i<streamNodeArray.length;i++)
{
$myResultingXml = flattenXmlRecursive(streamNodeArray[i],$xml);
}
var resultingXmlString = '<root>'+$myResultingXml.find("root").html()+'</root>'
console.log(resultingXmlString );
});
function flattenXmlRecursive(xmlFragment,xmlDoc)
{
var i = 0;
var streamNodeArray = [];
xmlFragment.children('stream').each(function(){
streamNodeArray.push($(this));
});
for(i=0;i<streamNodeArray.length;i++)
{
flattenXmlRecursive(streamNodeArray[i],xmlDoc);
}
if(xmlFragment.children('disposition').text()=='Break out overall')
{
xmlDoc.find(xmlFragment).remove();
xmlDoc.find('root').append(xmlFragment);
}
return xmlDoc;
}