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



我正在尝试使用 php 将.xml表文件导入 mysql,它工作正常,但我想升级我的代码,以便我可以识别 xml 表的更多变体。 所以基本上问题是,我得到了我正在尝试读取.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 文件中获取所有行,但我只想要"表"标签内的内容。我该怎么做??

PS:我稍后还有另一个问题要解决,里面有很多行没有项目(数据标签(,所以我无法得到这些,程序只是跳到下一个,但我认为解决方案只是获取"单元格"标签而不是"数据"。

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

这实际上是相同的命名空间,但 XML 属性没有默认命名空间,因此它们需要前缀/别名。

有了它,您可以使用 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返回第一个TableRow元素。

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

你可以通过执行 $tablas[0] 来访问 tables 数组中的第一个表。现在你甚至不需要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++;
}
?>

最新更新