I have an array like this one:
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
)
)
)
)
)
)
)
)
)
)
)
What I need to do is to build a breadcrumb using Anchestors. The one that is at the end of the list should be the first one. So, as an example:
Sport e tempo libero > Categorie > calcio...
I'm trying to iterate the xml with a function in this way without success:
$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));
I found something similar on stackoverflow but no suggestions helped me to sort this out.
php function dofoo() { $array["a"] = "Foo"; $array["b"] = "Bar"; $array["c"] = "Baz"; return $array; } $foo = dofoo(); ?> Without returning an array, the only other way to pass data back to the calling script is by accepting parameters by reference and changing them inside the function.
Method 1(Using Recursion) : Create a recursive function say, largest_element (int n, int arr[]). Base Condition : If(n==1) return arr[0]. ( If the remaining array is of length 1, return the only present element i.e. arr[0] ) Else, return max(arr[n-1], largest_element(n-1, arr))
Recursion is a method of programming or coding a problem, in which a function calls itself one or more times in its body. Usually, it is returning the return value of this function call. If a function definition satisfies the condition of recursion, we call this function a recursive function.
Memory Allocation in Recursion. When a function is called, its memory is allocated on a stack.
To create a recursive function with an output, you need three things:
$r
in your code.
You got this one right.$bread
, but it is not holding any value because it is empty every time you call recursive()
.
A simple solution is to declare it as global
inside the function.if
statement that checks the stop condition, which you don't have.
Instead, you have a do-while
loop in your code.So, you have two mistakes there. Based on your code and modifying it as little as possible, this is the correct code:
$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));
There you go.
Update: I agree with @FlameStorm, global
should be avoided if possible.
I also received suggestion to use static
instead, but it introduces a bug.
Thus, I recommend avoiding static
as well if you're not sure how to use it.
This is the improved code:
$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));
The $bread
variable outside the function is no longer needed.
Also, neither global
or static
is used.
SimpleXMLElement
is not an array. You could convert it to an array, but PHP offers an iterator specifically for this case, SimpleXMLIterator
.
Since you have a recursive structure, my suggestion is to flatten it with RecursiveIteratorIterator
. Assuming your data is in a variable called $xml
, your solution might look something like this:
$xmlIterator = new SimpleXMLIterator($xml->Ancestors);
$flatIterator = new RecursiveIteratorIterator($xmlIterator, RecursiveIteratorIterator::SELF_FIRST);
$breadcrumb = [];
foreach($flatIterator as $node) {
$breadcrumb[] = $node['Name'];
}
$breadcrumb = array_reverse($breadcrumb);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With