I have this weird error I don't really know how is this possible. The xmlreader reads the file, but when i am trying to iterate it, it still gives me the error "Message: XMLReader::read(): Load Data before trying to read".
Here is my code:
$what = 'title';
$reader = new XMLReader;
if (!$reader->open(base_url().'resources/thexml.xml'))
{
die("Failed to open");
}
else
{
echo 'success!';
}
while($reader->read())
{
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item')
{
$exp = $reader->expand();
if ($exp->nodeName == $what)
echo "<b>" . $exp->nodeName . " : </b>" . $exp->nodeValue . "<br />";
}
$reader->close();
}
And this is the output:
success! A PHP Error was encountered
Severity: Warning
Message: XMLReader::read(): Load Data before trying to read
Filename: controllers/welcome.php
Line Number: 102
The success shows it reads the file but still gives me the error that I need to open first. Line number 102 is "while($reader->read())" line. Please help
I found out the problem: You need to move the $reader->close();
statement outside of the loop. Otherwise the xml document gets closed after the first loop and the subsequent read operations fails.
The read loop should look like this:
while($reader->read())
{
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item')
{
$exp = $reader->expand();
if ($exp->nodeName == $what)
echo "<b>" . $exp->nodeName . " : </b>" . $exp->nodeValue . "<br />";
}
}
// Close the document after(!) the loop
$reader->close();
Having this your code works properly.
However, using XMLReader
doesn't seem the appropriate solution here. This because it requires to loop over all(!) tags in the input xml while you are only interested in the <item>
nodes. I would use DOMDocument
together with XPath
here:
// Create an load the DOM document
$doc = new DOMDocument();
$doc->load('thexml.xml');
// Create an XPath selector
$selector = new DOMXPath($doc);
// Get all <title> nodes inside <item> nodes
foreach($selector->query('//item/title') as $item) {
echo '<b>Title: ' . $item->nodeValue . '</br>';
}