如何在到达特定标签名称时在 php 中中断 'foreach'?

How to break 'foreach' in php when reach a specific tag name?

我正在尝试使用 php 将 .xml table 文件导入到 mysql,它工作正常,但我想升级我的代码,所以我可以识别 xml table 的更多变体。 所以基本上问题是,我得到了这段代码(只是一个例子,我真正的 table 更大)我正在尝试阅读的 .xml 文件:

...
<Table ss:StyleID="s62">
   <Column ss:StyleID="s62"/>
   <Column ss:StyleID="s62"/>
   <Column ss:StyleID="s62"/>
   <Row ss:AutoFitHeight="0">
     <Cell ss:StyleID="s75"><Data ss:Type="String">Mercado</Data></Cell>
     <Cell ss:StyleID="s75"><Data ss:Type="String">Segmento</Data></Cell>
     <Cell ss:StyleID="s76"><Data ss:Type="String">Codigo do Projeto</Data></Cell>
   </Row>
   <Row ss:AutoFitHeight="0">
     <Cell ss:StyleID="s90"><Data ss:Type="String">Mineração</Data></Cell>
     <Cell ss:StyleID="s90"><Data ss:Type="String">Portuário</Data></Cell>
     <Cell ss:StyleID="s90"/>
   </Row>
   <Row ss:AutoFitHeight="0">
     <Cell ss:StyleID="s90"><Data ss:Type="String">Portuário</Data></Cell>
     <Cell ss:StyleID="s90"/>
     <Cell ss:StyleID="s90"><Data ss:Type="String">Greenfield</Data></Cell>
   </Row>
   <Row ss:AutoFitHeight="0">
     <Cell ss:StyleID="s90"/>
     <Cell ss:StyleID="s90"><Data ss:Type="String">Greenfield</Data></Cell>
     <Cell ss:StyleID="s90"><Data ss:Type="String">Large CapEx&gt;&gt;maior que 500MBRL</Data></Cell>
   </Row>
</Table>

<Worksheet ss:Name="cod">

  <Table ss:StyleID="s62">
... ...
  </Table>

...

好吧,我想做的是使用 getElementByTagName 获取行和数据元素,但我只想获取第一个 Table 元素中的内容,而不是第二个、第三个等等。 .

这是我试过的:

    $tabelas = $arquivo->getElementsByTagName("Table");
    $rows = $arquivo->getElementsByTagName("Row");

    $contRow = 1; (This is just to create a condition to jump the first row)
    $contTabelas = TRUE;
    foreach ($tabelas as $tabela) {
        if ($contTabelas) {
            foreach ($rows as $row) {
                if ($contRow > 1) {
                    $Mercado = $row->getElementsByTagName("Data")->item(0)->nodeValue;
                    $Segmento = $row->getElementsByTagName("Data")->item(1)->nodeValue;
                    $CodigoDoProjeto = $row->getElementsByTagName("Data")->item(2)->nodeValue;

                }
                $contRow++;
            }
            $contTabelas = FALSE;
        }
    }

似乎 "foreach($rows as $row)" 正在从 xml 文件中获取所有行,但我只想要 "Table" 标签中的内容。我该怎么做?

P.S:稍后我还有一个问题要解决,有很多行里面没有项目(数据标签),所以我无法获取这些,程序只是跳到下一个,但是我认为解决方案只是获取 'cell' 标签而不是 'data'.

您可以通过 $tablas[0] 访问 tables 数组中的第一个 table。现在您甚至不需要 foreach 循环。

<?php

$tabelas = $arquivo->getElementsByTagName("Table");

$tablea = $tabelas[0];

$rows = $tablea->getElementsByTagName("Row");

$contRow = 1;

foreach ($rows as $row) {
    if ($contRow > 1) {
        $Mercado = $row->getElementsByTagName("Data")->item(0)->nodeValue;
        $Segmento = $row->getElementsByTagName("Data")->item(1)->nodeValue;
        $CodigoDoProjeto = $row->getElementsByTagName("Data")->item(2)->nodeValue;

    }
    $contRow++;
}
?>

这看起来像一个 OpenXML 电子表格,如果是这种情况,您应该查找命名空间定义。我希望您能找到 xmlns="urn:schemas-microsoft-com:office:spreadsheet"xmlns::ss="urn:schemas-microsoft-com:office:spreadsheet"

这实际上是同一个命名空间,但是 XML 属性没有默认命名空间,因此它们需要一个 prefix/alias.

有了它,您可以使用 Xpath 表达式从文档中获取特定数据:

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('spreadsheet', 'urn:schemas-microsoft-com:office:spreadsheet');

$records = [];
$rows = $xpath->evaluate('((//spreadsheet:Table)[1]/spreadsheet:Row)[position() > 1]');
foreach ($rows as $row) {
    $records[] = [
      'Mercado' => $xpath->evaluate('string(spreadsheet:Cell[1])', $row),
      'Segmento' => $xpath->evaluate('string(spreadsheet:Cell[2])', $row),
      'CodigoDoProjeto' => $xpath->evaluate('string(spreadsheet:Cell[3])', $row)
    ];
}


var_dump($records);

输出:

array(3) {
  [1]=>
  array(3) {
    ["Mercado"]=>
    string(11) "Mineração"
    ["Segmento"]=>
    string(10) "Portuário"
    ["CodigoDoProjeto"]=>
    string(0) ""
  }
  [2]=>
  array(3) {
    ["Mercado"]=>
    string(10) "Portuário"
    ["Segmento"]=>
    string(0) ""
    ["CodigoDoProjeto"]=>
    string(10) "Greenfield"
  }
  [3]=>
  array(3) {
    ["Mercado"]=>
    string(0) ""
    ["Segmento"]=>
    string(10) "Greenfield"
    ["CodigoDoProjeto"]=>
    string(30) "Large CapEx>>maior que 500MBRL"
  }
}

//spreadsheet:Table 获取任何 Table(//spreadsheet:Table)[1] 将此限制为第一个,(//spreadsheet:Table)[1]/spreadsheet:Row return 是第一个的 Row 个元素Table.

spreadsheet:Cell[1]return是第一个Cellstring(spreadsheet:Cell[1])return的正文内容。如果它不匹配节点,它将 return 一个空字符串。