为了账号安全,请及时绑定邮箱和手机立即绑定

到达特定标签名称时,如何在 php 中打破“foreach”?

到达特定标签名称时,如何在 php 中打破“foreach”?

PHP
眼眸繁星 2021-11-26 19:38:07
我正在尝试使用 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 元素中的内容,而不是第二个、第三个等等......似乎“foreach($rows as $row)”正在从xml文件中获取所有行,但我只想要“Table”标签中的内容。我怎样才能做到这一点??PS:稍后我还有另一个问题要解决,里面有很多行没有项目(数据标签),所以我无法得到那些,程序只是跳到下一个,但我认为解决方案只是得到 '单元格”标签而不是“数据”。
查看完整描述

2 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

如果是这种情况,您应该查找命名空间定义,这看起来像一个 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:Tablefetch any Table,(//spreadsheet:Table)[1]将其限制为第一个,(//spreadsheet:Table)[1]/spreadsheet:Row返回第一个的Row元素Table。


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


查看完整回答
反对 回复 2021-11-26
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

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

}

?>


查看完整回答
反对 回复 2021-11-26
  • 2 回答
  • 0 关注
  • 190 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信