我有一个像这样的数组:
SimpleXMLElement Object
(
[BrowseNodes] => SimpleXMLElement Object
(
[BrowseNode] => SimpleXMLElement Object
(
[BrowseNodeId] => 969391031
[Name] => Bambine e ragazze
[Children] => SimpleXMLElement Object
(
[BrowseNode] => Array
(
[0] => SimpleXMLElement Object
(
[BrowseNodeId] => 969394031
[Name] => Calze
)
[1] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635837031
[Name] => Felpe
)
[2] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635838031
[Name] => Giacche
)
[3] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635839031
[Name] => Guanti da giocatore
)
[4] => SimpleXMLElement Object
(
[BrowseNodeId] => 969392031
[Name] => Maglie
)
[5] => SimpleXMLElement Object
(
[BrowseNodeId] => 4351854031
[Name] => Maglie per tifosi
)
[6] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635840031
[Name] => Magliette da portiere
)
[7] => SimpleXMLElement Object
(
[BrowseNodeId] => 969393031
[Name] => Pantaloncini
)
[8] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635841031
[Name] => Pantaloncini da portiere
)
[9] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635842031
[Name] => Pantaloni
)
[10] => SimpleXMLElement Object
(
[BrowseNodeId] => 3635843031
[Name] => Tute da ginnastica
)
)
)
[Ancestors] => SimpleXMLElement Object
(
[BrowseNode] => SimpleXMLElement Object
(
[BrowseNodeId] => 969386031
[Name] => Abbigliamento
[Ancestors] => SimpleXMLElement Object
(
[BrowseNode] => SimpleXMLElement Object
(
[BrowseNodeId] => 937258031
[Name] => Calcio
[Ancestors] => SimpleXMLElement Object
(
[BrowseNode] => SimpleXMLElement Object
(
[BrowseNodeId] => 524013031
[Name] => Categorie
[IsCategoryRoot] => 1
[Ancestors] => SimpleXMLElement Object
(
[BrowseNode] => SimpleXMLElement Object
(
[BrowseNodeId] => 524012031
[Name] => Sport e tempo libero
)
)
)
)
)
)
)
)
)
)
)
我需要做的是使用Anchestors构建面包屑。列表末尾的那个应该是第一个。所以,作为一个例子:
Sport e tempo libero>分类> CALCIO ...
我试图以这种方式用函数迭代xml但没有成功:
$rec=$result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;
$bread=array();
function recursive($r)
{
do{
$bread[]=$r->BrowseNodeId;
recursive($r->Ancestors->BrowseNode);
}while(isset($r->Ancestors));
$bread=array_reverse($bread);
return $bread;
}
print_r(recursive($rec));
我在stackoverflow上发现了类似的东西,但没有任何建议帮助我解决这个问题。
答案 0 :(得分:9)
要使用输出创建递归函数,您需要三件事:
$r
。
你有这个权利。$bread
,但它没有任何值,因为每次调用recursive()
时它都是空的。
一个简单的解决方案是在函数内声明它为global
。if
语句,用于检查您没有的停止条件。
相反,您的代码中有一个do-while
循环。所以,你有两个错误。 根据您的代码并尽可能少地修改它,这是正确的代码:
$rec = $result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;
$bread = array();
function recursive($r)
{
global $bread;
$bread[] = strval($r->BrowseNodeId);
if(isset($r->Ancestors)){
return recursive($r->Ancestors->BrowseNode);
}else{
return array_reverse($bread);
}
}
print_r(recursive($rec));
你去。
更新:我同意@FlameStorm,如果可能,应该避免使用global
。
我还收到了使用static
的建议,但它引入了一个错误。
因此,如果您不确定如何使用它,我建议您不要使用static
。
这是改进的代码:
$rec = $result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;
function recursive($r)
{
if(isset($r->Ancestors))
$bread = recursive($r->Ancestors->BrowseNode);
$bread[] = strval($r->BrowseNodeId);
return $bread;
}
print_r(recursive($rec));
不再需要函数外部的$bread
变量。
此外,未使用global
或static
。
答案 1 :(得分:4)
SimpleXMLElement
不是数组。您可以将其转换为数组,但PHP提供了专门针对此案例的迭代器SimpleXMLIterator
。
由于你有一个递归结构,我的建议是用RecursiveIteratorIterator
展平它。假设您的数据位于名为$xml
的变量中,您的解决方案可能如下所示:
$xmlIterator = new SimpleXMLIterator($xml->Ancestors);
$flatIterator = new RecursiveIteratorIterator($xmlIterator, RecursiveIteratorIterator::SELF_FIRST);
$breadcrumb = [];
foreach($flatIterator as $node) {
$breadcrumb[] = $node['Name'];
}
$breadcrumb = array_reverse($breadcrumb);
答案 2 :(得分:0)
<?php
$sxe = new SimpleXMLElement("BrowseNodes.xml", NULL, TRUE);
// prepare a String for the SimpleXMLIterator.
// The SimpleXMLIterator expects:
// "A well-formed XML string or the path or URL to an XML document"
// therefore get the xml-string by calling asXML() on the
$partitialXMLString = $sxe->BrowseNodes->BrowseNode->Ancestors->asXML();
$recursiveIterator = new RecursiveIteratorIterator(
new SimpleXMLIterator($partitialXMLString),
RecursiveIteratorIterator::CHILD_FIRST
);
// if you need only the names
$name = array();
// if you need the links to something
$link = array();
$baseUrl = "http://example.com/BrowseNodeId/";
// if you need just the nodes in an array, and create the output later from it
// $xmlNode = array()
foreach($recursiveIterator as $node) {
if (false == empty($node->Name)){
$name[] = (string) $node->Name;
$link[] = "<a href='" . $baseUrl . $node->BrowseNodeId . "'>" . $node->Name . "</a>\n";
// for later processing
// $xmlNode[] = $node;
}
}
// Add the top BrowseNode->Name, from the node, where the First "Ancestors" is.
// This could be done also in the loop, when looping over all elements,
// by adding conditions in order to differentiate between Children and Ancestors
// But this is more readable, and for your structure should be enough.
$firstNode = $sxe->BrowseNodes->BrowseNode;
$name[] = $firstNode->Name;
$link[] = "<a href='" . $baseUrl . $firstNode->BrowseNodeId . "'>" . $firstNode->Name . "</a>\n";
// $xmlNode[] = $firstNode;
//output the path (child first)
// > is >
echo implode(' > ', $name);
echo "<br>\n";
//output the links (child first)
echo implode(' > ', $link);
浏览器中的输出:
Sport e tempo libero&gt;分类&gt; Calcio&gt; Abbigliamento&gt; Bambine e ragazze
Sport e tempo libero&gt;分类&gt; Calcio&gt; Abbigliamento&gt; Bambine e ragazze
(带链接的第二行)
生成的html代码:
Sport e tempo libero > Categorie > Calcio > Abbigliamento > Bambine e ragazze<br>
<a href='http://example.com/BrowseNodeId/524012031'>Sport e tempo libero</a>
> <a href='http://example.com/BrowseNodeId/524013031'>Categorie</a>
> <a href='http://example.com/BrowseNodeId/937258031'>Calcio</a>
> <a href='http://example.com/BrowseNodeId/969386031'>Abbigliamento</a>
> <a href='http://example.com/BrowseNodeId/969391031'>Bambine e ragazze</a>
答案 3 :(得分:0)
修正了上面的一个答案 - 如果可以的话,你应该避免使用global
。
所以,代码将是
$rec = $result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;
function recursive($r)
{
$breads = [strval($r->BrowseNodeId)];
if (isset($r->Ancestors)) {
$breads = array_merge(recursive($r->Ancestors->BrowseNode), $breads);
}
return $breads;
}
$breadcrumbs = recursive($rec); // You got it.
print_r($breadcrumbs);
答案 4 :(得分:0)
或者,您可以使用$ _SESSION从递归中获取数据
function start(){
$_SESSION['new1']=[];
$this->recursive($array);
$newVal = $_SESSION['new1'];
$_SESSION['new1']=[];
return $newVal;
}
function recursive($array){
...
$_SESSION['new1'][] = $val;
...
}