2012-09-24 41 views
2

我有一个表,看起来像这样:http://pastebin.com/jjZxeNHFPHP的DOMDocument解析嵌套表

我把它作为一个PHP-DOM文档。

现在我想“解析”这张表。

如果我是正确的,像下面这样的东西是不会工作的,因为$superTable->getElementsByTagName('tr')不仅要获得外部tr而且还要获得内部。

foreach ($superTable->getElementsByTagName('tr') as $superRow) { 
    foreach ($superRow->getElementsByTagName('td') as $superCol) { 
     foreach ($superCol->getElementsByTagName('table') as $table) { 
      foreach ($table->getElementsByTagName('tr') as $row) { 
       foreach ($row->getElementsByTagName('td') as $col) { 
       } 
      } 
     } 
    } 
} 

我怎样才能去槽所有的表,字段的字段,如第二段所述。

+1

你能举一个真实的表格吗?不知道您是否只需要定位内部表格或各种条件。其次,你如何要td内容?只是一个数组转储,或使用任何键的?是否有可变列? – pp19dd

+0

它总是一个包含x * y rows *列的外部表。现在有另一个表嵌套到外部表的每个字段中。该内部表格具有可变数量的行和列。我想按照上面的示例去查看表格,所以我可以添加一些格式并重新输出。 – Zulakis

+0

也许使这些'foreach'es成为一个函数,然后递归地调用它。 –

回答

1

这是我的解决方案:

foreach ($raumplan->getElementsByTagName('tr') as $superRow) { 
    if ($superRow->getElementsByTagName('table')->length > 0) { 
     foreach ($superRow->getElementsByTagName('td') as $superCol) { 
      if ($superCol->getElementsByTagName('table')->length > 0) { 
       foreach ($superCol->getElementsByTagName('table') as $table) { 
        foreach ($table->getElementsByTagName('tr') as $row) { 
         foreach ($row->getElementsByTagName('td') as $col) { 
         } 
        } 
       } 
      } 
     } 
    } 
} 

它检查,如果你是在外部表看是否有包含在元素的表。

1

您可以使用XPath消除大量的公然的低级循环,并减少这一切明显的复杂...

$xpath = new DOMXPath($document); 
foreach ($xpath->query('//selector/for/superTable//table') as $table) { 
    // in case you really wanted them... 
    $superCol = $table->parentNode; 
    $superRow = $superCol->parentNode; 

    foreach ($table->getElementsByTagName('td') as $col) { 
     $row = $td->parentNode; 
     // do your thing with each cell here 
    } 
} 

你可以比这更深入,如果你想要的 - 如果您只想要内表中的每个单元格,则可以通过//selector/for/superTable//table//td将其减少为一个循环。

当然,如果你正在处理有效的HTML,那么你也可以遍历每个元素的子元素。这完全取决于HTML的外观,以及你需要的东西。

编辑:如果你不能使用XPath出于某种原因,你可能会做这样的事情

// I assume you've found $superTable already 
foreach ($superTable->getElementsByTagName('table') as $table) { 
    $superCol = $table->parentNode; 
    $superRow = $superCol->parentNode; 
    foreach ($table->getElementsByTagName('td') as $col) { 
     $row = $col->parentNode; 
     // do your thing here 
    } 
} 

注意,无论是解决困扰遍历行等等。这是一个大的一部分是什么不需要仅获取当前表中的行。您只在表中寻找,根据定义(1)将是子表,并且(2)将在主表内的行内的列内,并且您可以获得父行和表格元素本身的列。

当然,这两种解决方案都假设您只将表嵌套一层。如果不止于此,你会想看看递归解决方案和DOMElement的childNodes属性。或者,更专注的XPath查询。

+0

我正在寻找一个基于DOMDocument的解决方案。我还在最初的帖子中添加了一个更好的例子,看看。 – Zulakis

+1

是否有特殊的原因需要使用DOMDocument? XPath是为这样的东西做出的,并且是DOM东西的标准部分。如果有一个很好的理由,我可能会考虑只使用DOMDocument会带来的丑陋,但如果你只是随意不想使用它,我不能支持它。 – cHao