如何在到达特定标签名称时在 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>>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是第一个Cell
和string(spreadsheet:Cell[1])
return的正文内容。如果它不匹配节点,它将 return 一个空字符串。
我正在尝试使用 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>>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是第一个Cell
和string(spreadsheet:Cell[1])
return的正文内容。如果它不匹配节点,它将 return 一个空字符串。