【问题标题】:What would be the best way to simplify this foreach?简化此 foreach 的最佳方法是什么?
【发布时间】:2013-11-06 15:17:37
【问题描述】:

我正在测试一个 xml 对象以查看它深入了多少层,发现它深入了 11 个元素。我想知道如何才能更简单地完成这项工作,以便将来节省几分钟。

$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);
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

注意:drupal_get_path 和 dpm 是 Drupal CMS 函数,这里可以忽略。

【问题讨论】:

  • 你可能想要一个递归函数。

标签: php parsing xml-parsing


【解决方案1】:

这应该可行。 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);

您可以使用第二个参数指定要降低的最大级别,就像我在键盘示例中所做的那样。

【讨论】:

    【解决方案2】:

    由于您在每个级别都在做类似的事情,您可以将此逻辑放入一个函数并在每个级别调用该逻辑。一个(未经测试的)示例如下:

    $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);
        }
    }
    

    【讨论】:

    • +1。虽然这里假设整个 xml 文件都想被转储 - 但情况可能并非如此(可能有 200 个级别)。
    【解决方案3】:

    你可以使用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】:

      你需要一个递归函数:

      $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
      }
      

      递归函数是一种会调用自身的函数,非常适合您的问题。这个例子应该可以解决你的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        • 2017-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多