PHP XMLReader 解析行 2 次
Posted
技术标签:
【中文标题】PHP XMLReader 解析行 2 次【英文标题】:PHP XMLReader parses lines 2 times 【发布时间】:2012-11-04 15:18:21 【问题描述】:我正在解析一个 xml 文件。例如,当我输出一个属性时,我总是得到 2 次结果。
这是我所做的一些简化代码:
$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)
感谢您的帮助!
【问题讨论】:
可以帮助显示 XML 结构 已更新...感谢您的快速回答(*** 初学者) 没问题,这就是 SO 的用途,对于初学者来说,您在描述问题和提供有关已尝试内容的信息方面做得很好。大多数人一开始都失败了,然后因此而受到了磨砺,因此值得称赞。 【参考方案1】:在文档的 cmets 中找到了这个:
可能很明显,但不是每个人 ;-) ... 阅读属性时 从具有子节点的节点(并由此创建输出 节点),输出将发出两次,一次在标签和 一次在结束标签上。为避免这种情况,您可以测试哪个 您正在使用属性 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 />";
?>
更新 使用 cmets 中建议的解决方案修改了您的代码。
$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();
【讨论】:
simplexml 不起作用,因为我正在加载 > 300 MB 的 XML 文件。我必须逐行解析它们。以上是关于PHP XMLReader 解析行 2 次的主要内容,如果未能解决你的问题,请参考以下文章
XMLReader 是 SAX 解析器、DOM 解析器,还是两者都不是?