PHP的XMLReader解析器会对每一行进行两次解析

3
我是一个XML文件解析器。例如,当我输出一个属性时,总是会得到两次结果。
以下是我所做的一些简化代码:
    $xml = new XMLReader();

    $xml->open($file);

    while ($xml->read()) {
        if ($xml->name == 'file')
            echo $xml->getAttribute ('Product_ID') . '<br />';
    }

    // close stream
    $xml->close();

这是我得到的内容:

1980 1980 37444 37444 45287 45287 65438 65438 76916 76916 101158 101158 271287 271287

XML结构如下:

<file path="export/freexml.int/DE/15986140.xml" Product_ID="15986140" Updated="20121114141132" Quality="ICECAT" Supplier_id="728" Prod_ID="RBBD2MZ" Catid="2282" On_Market="0" Model_Name="ThinkCentre Edge 92z" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15916192-2729.jpg" HighPicSize="12635" HighPicWidth="337" HighPicHeight="294" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986142.xml" Product_ID="15986142" Updated="20121114143018" Quality="ICECAT" Supplier_id="24" Prod_ID="NX.C0ZEB.002" Catid="151" On_Market="0" Model_Name="TE11HC-32376G50Mnks" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986142-574.jpg" HighPicSize="179174" HighPicWidth="786" HighPicHeight="621" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986149.xml" Product_ID="15986149" Updated="20121114144736" Quality="ICECAT" Supplier_id="24" Prod_ID="NX.C1UEB.001" Catid="151" On_Market="0" Model_Name="LE11-BZ-E1124G50Mn" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986149-2702.jpg" HighPicSize="205805" HighPicWidth="786" HighPicHeight="621" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986153.xml" Product_ID="15986153" Updated="20121114200420" Quality="ICECAT" Supplier_id="1935" Prod_ID="50203" Catid="194" On_Market="0" Model_Name="Arma" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986153-3865.jpg" HighPicSize="1928713" HighPicWidth="2751" HighPicHeight="1897" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986154.xml" Product_ID="15986154" Updated="20121114200048" Quality="ICECAT" Supplier_id="1935" Prod_ID="ARMAKB" Catid="194" On_Market="0" Model_Name="Arma" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986154-7619.jpg" HighPicSize="1928713" HighPicWidth="2751" HighPicHeight="1897" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986155.xml" Product_ID="15986155" Updated="20121114194744" Quality="ICECAT" Supplier_id="1935" Prod_ID="ARMAM" Catid="195" On_Market="0" Model_Name="Arma" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986155-4238.jpg" HighPicSize="639005" HighPicWidth="2201" HighPicHeight="3265" Date_Added="20121114000000"></file>
<file path="export/freexml.int/DE/15986156.xml" Product_ID="15986156" Updated="20121114194735" Quality="ICECAT" Supplier_id="1935" Prod_ID="54577" Catid="195" On_Market="0" Model_Name="Arma" Product_View="0" HighPic="http://images.icecat.biz/img/norm/high/15986156-7292.jpg" HighPicSize="639005" HighPicWidth="2201" HighPicHeight="3265" Date_Added="20121114000000"></file>

正如您所看到的,每个数字都显示了两次。我不明白问题在哪里 -.-。我做错了什么吗?

非常感谢大家的帮助!

// 编辑

好的,我这样修复了:

if ($xml->name == 'file' && $xml->nodeType == XMLReader::ELEMENT)

感谢您的帮助!

1
可以展示一下XML结构吗? - Mike Brant
更新了...谢谢你的快速回答(stackoverflow初学者) - Megamind
没问题,这就是 Stack Overflow 的用处。对于一个初学者来说,你在描述问题和提供已尝试的信息方面做得非常好。大多数人最初都会失败并因此受到批评,所以要赞一下你。 - shaunhusain
1个回答

4

在文档的评论中发现了以下内容:

这可能显而易见,但并非所有人都知道;-)......当从具有子节点的节点读取属性(并从该节点创建输出)时,输出将在开始标记和结尾标记上发出两次。为了避免这种情况,您可以测试使用属性nodeType的节点的哪个部分。它将是元素的1,结束元素的15。

http://www.php.net/manual/en/xmlreader.getattribute.php

您可以应用上述提出的解决方案,或选择另一种遍历节点的算法,如此处所示:http://www.w3schools.com/php/php_xml_simplexml.asp

<?php
$xml = simplexml_load_file("test.xml");

echo $xml->getName() . "<br />";

foreach($xml->children() as $child)
  {
  echo $child->getName() . ": " . $child . "<br />";
  }
?>

更新 根据评论中提出的解决方案修改了您的代码。

$xml = new XMLReader();

$xml->open($file);

while ($xml->read()) {
    if ($xml->name == 'file' && $xml->nodeType==XMLReader::ELEMENT)
        echo $xml->getAttribute ('Product_ID') . '<br />';
}

// close stream
$xml->close();

1
simplexml无法使用,因为我正在加载超过300 MB的XML文件。我必须逐行解析它们。 - Megamind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接