使用PHP

时间:2017-11-07 14:25:25

标签: php xml

我正在尝试使用PHP来读取大型XML文件(gzip)。该文件包含重复的产品(实际上是书籍)。每本书都有1个或更多的贡献者。这是产品的一个例子。

<Product>

    <ProductIdentifier>
        <IDTypeName>EAN.UCC-13</IDTypeName>
        <IDValue>9999999999999</IDValue>
    </ProductIdentifier>
    <Contributor>
        <SequenceNumber>1</SequenceNumber>
        <ContributorRole>A01</ContributorRole>
        <PersonNameInverted>Bloggs, Joe</PersonNameInverted>
    </Contributor>
    <Contributor>
        <SequenceNumber>2</SequenceNumber>
        <ContributorRole>A01</ContributorRole>
        <PersonNameInverted>Jones, John</PersonNameInverted>
    </Contributor>
            <Contributor>
        <SequenceNumber>3</SequenceNumber>
        <ContributorRole>B01</ContributorRole>
        <PersonNameInverted>Other, An</PersonNameInverted>
    </Contributor>

我希望这个例子的输出是

Array
(
    [1] => 9999999999999
    [2] => Bloggs, Joe(A01)
    [3] => Jones, John(A01)
    [4] => Other, An(B01)

)

我的代码加载gzip压缩的XML文件并处理重复的产品序列没有问题,但我无法让它处理重复的贡献者序列。我的处理产品和第一个贡献者的代码如下所示,但我已经尝试了各种循环通过贡献者的方法,但似乎无法实现我所需要的。我是PHP和XML的初学者,虽然是IT专业人员多年。

  $reader = new XMLReader();

//load the selected XML file to the DOM
if(!$reader->open("compress.zlib://filename.xml.gz","r")){
  die('Failed to open file!');
  }

while ($reader->read()):

  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'Product')
        {
        $xml = simplexml_load_string($reader->readOuterXML());
        list($result) = $xml->xpath('//ProductIdentifier[IDTypeName = "EAN.UCC-13"]');
        $line[1] = (string)$result->IDValue;  
        list($result) = $xml->xpath('//Contributor');
        $contributorname = (string)$result->PersonNameInverted;
        $role = (string)$result->ContributorRole;
        $line[2] = $contributorname."(".$role.")";
        echo '<pre>'; print_r($line); echo '</pre>';
        }

endwhile;

1 个答案:

答案 0 :(得分:1)

由于你有几个贡献者,你必须将它作为数组处理并循环它们以准备你的最终变量:

<?php

$reader = new XMLReader();
//load the selected XML file to the DOM
if(!$reader->open("compress.zlib://filename.xml.gz","r")){
  die('Failed to open file!');
}

while ($reader->read()) {
  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'Product') {
    $xml = simplexml_load_string($reader->readOuterXML());
    list($result) = $xml->xpath('//ProductIdentifier[IDTypeName = "EAN.UCC-13"]');
    $line[1] = (string)$result->IDValue;

    // get all contributors in an array
    $contributors = $xml->xpath('//Contributor');

    $i = 2;
    // go through all contributors
    foreach($contributors as $contributor) {
       $contributorname = (string)$contributor->PersonNameInverted;
       $role = (string)$contributor->ContributorRole;
       $line[$i] = $contributorname."(".$role.")";
       $i++;
    }
    echo '<pre>'; print_r($line); echo '</pre>';

  }
}

这将为您提供以下输出:

Array
(
  [1] => 9999999999999
  [2] => Bloggs, Joe(A01)
  [3] => Jones, John(A01)
  [4] => Other, An(B01)
)

编辑:这里有一些关于你的代码有什么问题的解释。您只需使用list()

取第一个,而不是占用所有贡献者

http://php.net/manual/en/function.list.php(将数组的所有值分配给变量)。既然你不知道你有多少贡献者(我猜......),你就不能用它了。

然后你将第一个分配到$line,所以你总是只有第一个。