Skip to main content
 首页 » 编程设计

PHP之如果元素每条记录具有相似的标签,则获取正确的 XML 值

2025年05月04日16jillzhang

PHP - 如果元素每条记录具有相似的标签,则获取正确的 XML 值

我正在获取以下 xml 文件:

XML 文件:

<?xml version='1.0' encoding='UTF-8'?> 
<abc:ABCData xmlns:abc="http://www.abc-example.com" xmlns:xyz="http:/www.xyz-example.com"> 
<abc:ABCRecords> 
 <abc:ABCRecord> 
 <abc:ABC>5EXZX4LPK</abc:ABC> 
  <abc:Entity> 
    <abc:Name>I Bornheim</abc:Name> 
    <abc:Periods> 
      <abc:Period> 
        <abc:Start>2017-01-01</abc:Start> 
        <abc:End>2017-12-31</abc:End> 
        <abc:Type>ACCOUNTING</abc:Type> 
      </abc:Period> 
      <abc:Period> 
        <abc:Start>2007-09-01</abc:Start> 
        <abc:Type>RELATIONSHIP</abc:Type> 
      </abc:Period> 
    </abc:Periods>       
  </abc:Entity> 
</abc:ABCRecord> 
<abc:ABCRecord> 
  <abc:ABC>5967007LI</abc:ABC> 
  <abc:Entity> 
    <abc:Name>SUN BANK</abc:Name> 
    <abc:Periods> 
      <abc:Period> 
        <abc:Start>2018-01-01</abc:Start> 
        <abc:End>2018-12-31</abc:End> 
        <abc:Type>BALANCED</abc:Type> 
      </abc:Period> 
      <abc:Period> 
        <abc:Start>2008-09-01</abc:Start> 
        <abc:Type>PARENT</abc:Type> 
      </abc:Period> 
    </abc:Periods>           
  </abc:Entity> 
</abc:ABCRecord> 
</abc:ABCRecords> 
</abc:ABCData> 

...使用此脚本,我将值输出为 csv:

PHP 文件:
<?php 
 
$reader = new XMLReader(); 
$reader->open('php://stdin'); 
 
$output = fopen('php://stdout', 'w'); 
fputcsv($output, ['id', 'name']); 
 
$xmlns = [ 
  'abc' => 'http://www.abc-example.com' 
]; 
 
$dom   = new DOMDocument; 
$xpath = new DOMXpath($dom); 
foreach ($xmlns as $prefix => $namespaceURI) { 
  $xpath->registerNamespace($prefix, $namespaceURI); 
} 
 
while ( 
  $reader->read() &&  
  ( 
    $reader->localName !== 'ABCRecord' ||  
    $reader->namespaceURI !== $xmlns['abc'] 
  ) 
) { 
  continue; 
} 
 
while ($reader->localName === 'ABCRecord') { 
  if ($reader->namespaceURI === 'http://www.abc-example.com') { 
    $node = $reader->expand($dom); 
    fputcsv( 
      $output,  
      [ 
        $xpath->evaluate('string(abc:ABC)', $node), 
        $xpath->evaluate('string(abc:Entity/abc:Name)', $node) 
      ] 
    ); 
  } 
 
  $reader->next('ABCRecord'); 
}  

... 像这样:

输出:
5EXZX4LPK,"I Bornheim" 
5967007LI,"SUN BANK" 

然而......如果每个周期记录具有相同的标签定义,我如何获取正确的“周期”值?

期望的输出:
5EXZX4LPK,"I Bornheim",2017-01-01,2017-12-31,"ACCOUNTING",2007-09-01,"RELATIONSHIP" 
5967007LI,"SUN BANK",2018-01-01,2018-12-31,"BALANCED",2008-09-01,"PARENT" 

请您参考如下方法:

您可以使用该类型对期间进行分组并获取第一个分组结果:

$xpath->evaluate( 
    'string( 
        abc:Entity/abc:Periods/abc:Period[ 
            abc:Type = "ACCOUNTING" or abc:Type="BALANCED" 
        ][1]/abc:Type 
    )',  
    $node 
), 

或者您检查这里是否是 abc:End子元素:
$xpath->evaluate( 
    'string( 
        abc:Entity/abc:Periods/abc:Period[ 
            count(abc:End) = 0 
        ][1]/abc:Type 
    )',  
    $node 
),