Reputation: 1633
I'm trying to determine why it is that I can not get the value of a node within my XML file. I'm using the following PHP code to parse my XML file...
<?php
error_reporting(E_ALL);
ini_set( 'display_errors','1');
libxml_use_internal_errors(true);
libxml_clear_errors();
// create the reader object
$reader = new XMLReader();
// reader the XML file.
$reader->open('test.xml');
// start reading the XML File.
while($reader->read()) {
// take action based on the kind of node returned
switch($reader->nodeType) {
// read more http://uk.php.net/manual/en/class.xmlreader.php#xmlreader.constants.element
case (XMLREADER::ELEMENT):
// get the name of the node.
$node_name = $reader->name;
// move the pointer to read the next item
$reader->read();
// action based on the $node_name
if ($node_name == 'PartNumber') {
$reader->read();
$data['PartNumber'] = $reader->value;
var_dump($data);
};
break;
case (XMLREADER::END_ELEMENT):
// do something based on when the element closes.
break;
}
}
?>
An example of my XML data is below...
<Items>
<Item MaintenanceType="C">
<HazardousMaterialCode>N</HazardousMaterialCode>
<ItemLevelGTIN GTINQualifier="UP">090127000380</ItemLevelGTIN>
<PartNumber>0-1848-1</PartNumber>
<BrandAAIAID>BBVL</BrandAAIAID>
<BrandLabel>Holley</BrandLabel>
<PartTerminologyID>5904</PartTerminologyID>
<Descriptions>
<Description MaintenanceType="C" DescriptionCode="DES" LanguageCode="EN">Street Carburetor</Description>
<Description MaintenanceType="C" DescriptionCode="SHO" LanguageCode="EN">Crb</Description>
</Descriptions>
<Prices>
<Pricing MaintenanceType="C" PriceType="JBR">
<PriceSheetNumber>L30779-13</PriceSheetNumber>
<CurrencyCode>USD</CurrencyCode>
<EffectiveDate>2013-01-01</EffectiveDate>
<Price UOM="PE">462.4600</Price>
</Pricing>
<Pricing MaintenanceType="C" PriceType="RET">
<PriceSheetNumber>L30779-13</PriceSheetNumber>
<CurrencyCode>USD</CurrencyCode>
<EffectiveDate>2013-01-01</EffectiveDate>
<Price UOM="PE">380.5500</Price>
</Pricing>
<Pricing MaintenanceType="C" PriceType="WD1">
<PriceSheetNumber>L30779-13</PriceSheetNumber>
<CurrencyCode>USD</CurrencyCode>
<EffectiveDate>2013-01-01</EffectiveDate>
<Price UOM="PE">314.4700</Price>
</Pricing>
</Prices>
<ExtendedInformation>
<ExtendedProductInformation MaintenanceType="C" EXPICode="CTO" LanguageCode="EN">US</ExtendedProductInformation>
<ExtendedProductInformation MaintenanceType="C" EXPICode="NPC" LanguageCode="EN">A</ExtendedProductInformation>
<ExtendedProductInformation MaintenanceType="C" EXPICode="HTS" LanguageCode="EN">8409914000</ExtendedProductInformation>
<ExtendedProductInformation MaintenanceType="C" EXPICode="NAF" LanguageCode="EN">B</ExtendedProductInformation>
</ExtendedInformation>
<ProductAttributes>
<ProductAttribute MaintenanceType="C" AttributeID="SKU" LanguageCode="EN">BBVL0-1848-1</ProductAttribute>
<ProductAttribute MaintenanceType="C" AttributeID="ModDate" LanguageCode="EN">2012-12-31</ProductAttribute>
</ProductAttributes>
<Packages>
<Package MaintenanceType="C">
<PackageLevelGTIN>00090127000380</PackageLevelGTIN>
<PackageUOM>EA</PackageUOM>
<QuantityofEaches>1</QuantityofEaches>
<Dimensions UOM="IN">
<Height>7.5000</Height>
<Width>11.0000</Width>
<Length>12.2500</Length>
</Dimensions>
<Weights UOM="PG">
<Weight>13.500</Weight>
<DimensionalWeight>6.09</DimensionalWeight>
</Weights>
</Package>
</Packages>
</Item>
</Items>
The var_dump of $data shows the following...
array(1) { ["PartNumber"]=> string(0) "" }
There are no errors being reported.
May someone point me in the direction of what I'm missing?
Upvotes: 0
Views: 449
Reputation: 197766
If you're booked to use XMLReader (e.g. because of having really large XML files) I normally suggest to use a library called XMLReaderIterator
which allows you to concentrate on parsing your data, not reading your XML. For your example code this is just really some little code:
require('xmlreader-iterators.php'); // https://github.com/hakre/XMLReaderIterator/tree/master/build/include
$xmlFile = "xmlreader-17187636.xml";
$reader = new XMLReader();
$reader->open($xmlFile);
/* @var $partNumbers XMLReaderNode[] */
$partNumbers = new XMLElementIterator($reader, 'PartNumber');
foreach($partNumbers as $partNumber) {
echo " * ", $partNumber->readString(), "\n";
}
This shows how to use an XMLElementIterator
to iterate over all elements named PartNumber
and then reading their string value. The output in this example case is:
* 0-1848-1
because you've got a single part-number element in the XML.
The example also shows that there still is the XML reader so you can do everything with it as well within the foreach and there are also other iterators that allow you to query elements, atttributes and even run shallow xpath queries.
Last time I suggested that library was in:
If you don't want to use the whole library, you find the code inside the XMLReaderNode::readString()
method which also shows how to get the value backwards-compatible which makes your code more inter-operable which is a benefit of that library. See as well XMLReader::readString().
Upvotes: 1
Reputation: 6625
use simplexml
and xpath
to retrieve the value:
$xml = simplexml_load_string($x); // assume XML in $x
$pns = $xml->xpath("//PartNumber");
now, $pns
contains an array of all <PartNumber>
values.
To retrieve only the 1st <PartNumber>
, do:
$pn = $xml->xpath("//PartNumber")[0]; // with PHP >= 5.4
See it working: http://3v4l.org/I7eKQ
Upvotes: 0
Reputation: 12985
If the XML document is not huge, why not use SimpleXMLElement
's simplexml_load_string()
or even DOMDocument
's ->loadXML()
. And use XPath
queries against them to get any node you want. The XMLReader
should be used when you are dealing with very large files that should not be preloaded but read sequentially.
Upvotes: 0
Reputation: 9646
You forgot to define $data = array();
<?php
error_reporting(E_ALL);
ini_set( 'display_errors','1');
libxml_use_internal_errors(true);
libxml_clear_errors();
$data = array(); //notice this???
// create the reader object
$reader = new XMLReader();
// reader the XML file.
$reader->open('test.xml');
// start reading the XML File.
while($reader->read()) {
// take action based on the kind of node returned
switch($reader->nodeType) {
// read more http://uk.php.net/manual/en/class.xmlreader.php#xmlreader.constants.element
case (XMLREADER::ELEMENT):
// get the name of the node.
$node_name = $reader->name;
// move the pointer to read the next item
$reader->read();
// action based on the $node_name
if ($node_name == 'PartNumber') {
$reader->read();
$data['PartNumber'] = $reader->value;
var_dump($data);
};
break;
case (XMLREADER::END_ELEMENT):
// do something based on when the element closes.
break;
}
}
?>
Upvotes: 0