问题
I was testing an xml object to see how many levels deep it went and found that it goes 11 elements deep. I'm wondering how I could have done this simpler so that in the future I can save a few minutes.
$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
dpm($xml);
foreach($xml->section as $section_l1) {
dpm('L1-------------------------------');
foreach($section_l1->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l1->section as $section_l2) {
dpm('---L2--------------------------');
foreach($section_l2->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l2->section as $section_l3) {
dpm('------L3---------------------');
foreach($section_l3->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l3->section as $section_l4) {
dpm('------L4---------------------');
foreach($section_l4->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l4->section as $section_l5) {
dpm('------L5---------------------');
foreach($section_l5->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l5->section as $section_l6) {
dpm('------L6---------------------');
foreach($section_l6->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l6->section as $section_l7) {
dpm('------L7---------------------');
foreach($section_l7->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l7->section as $section_l8) {
dpm('------L8---------------------');
foreach($section_l8->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l8->section as $section_l9) {
dpm('------L9---------------------');
foreach($section_l9->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l9->section as $section_l10) {
dpm('------L10---------------------');
foreach($section_l10->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l10->section as $section_l11) {
dpm('------L11---------------------');
foreach($section_l11->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l11->section as $section_l12) {
dpm('------L12---------------------');
foreach($section_l12->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
foreach($section_l12->section as $section_l13) {
dpm('------L13---------------------');
foreach($section_l13->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
Note: drupal_get_path and dpm are Drupal CMS functions and can be ignored here.
回答1:
This should work. Here is an example
function recurse($xml, $maxLevel = -1, $level = 0) {
if ($maxLevel != -1 && $level > $maxLevel) {
return;
}
if ($level == 0) {
dpm($xml);
}
$string = '---------------------------------';
$pos = $level * 3;
$l = 'L'. ($level+1);
$string = substr_replace($string, $l, $pos, strlen($l));
foreach ($xml->section as $section) {
dpm($string);
foreach ($section->attributes() as $a=>$b) {
dpm($a .' = '. $b);
}
dpm('-----:');
recurse($section, $maxLevel, $level+1);
}
}
$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
recurse($xml);
You can specify the max level you want to go down using the second parameter, as I've done in the codepad example.
回答2:
Since you're doing a similar thing at each level you can put this logic into a function and call that logic at each level. An (untested) example would be something like:
$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
function processXML($xml, $level = 1){
dpm($xml);
foreach($xml->section as $section_l1) {
dpm('L'.$level.'-------------------------------');
foreach($section_l1->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
processXML($section_l1,$level+1);
}
}
回答3:
You could use a recursive function:
$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
dpm($xml);
traverse($xml, 1);
private function traverse($section, $level) {
dpm('L'.$level.'-------------------------------');
foreach($section->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
traverse($section->section, $level+1)
}
回答4:
You need a recursive function:
$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
dpm($xml);
$depth = $xml->section; // The array you want to find the depth
$iterator = 0; // The starting level
recurse_count($depth, $iterator); // Fire the function
function recurse_count($array, $iterator) {
foreach($array->section as $children) {
$iterator++; // Increment the iterator
dpm('---L'.$iterator.'--------------------------');
foreach($children->attributes() as $a => $b) {
dpm($a . ' = ' . $b);
}
dpm('-----:');
}
recurse_count($children, $iterator); // Fire the function again
}
A recursive function is one that will call itself and is well suited for your issue. This example should work for your problem.
来源:https://stackoverflow.com/questions/19815824/what-would-be-the-best-way-to-simplify-this-foreach