XMLReader::read
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
XMLReader::read — ドキュメント内の次のノードに移動する
パラメータ
この関数にはパラメータはありません。
参考
- XMLReader::moveToElement() - 現在の属性の親要素にカーソルを移動する
- XMLReader::moveToAttribute() - 指定した名前の属性にカーソルを移動する
- XMLReader::next() - すべてのサブツリーを飛ばして、次のノードにカーソルを移動する
+add a note
User Contributed Notes 5 notes
jirka at kosek dot cz ¶
18 years ago
libxml2 contains much more useful method readString() that will read and return whole text content of element. You can call it after receiving start tag (XMLReader::ELEMENT). You can use this PHP code to emulate this method until PHP will directly call underlying libxml2 implementation.
<?php
class XMLReader2 extends XMLReader
{
function readString()
{
$depth = 1;
$text = "";
while ($this->read() && $depth != 0)
{
if (in_array($this->nodeType, array(XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE, XMLReader::SIGNIFICANT_WHITESPACE)))
$text .= $this->value;
if ($this->nodeType == XMLReader::ELEMENT) $depth++;
if ($this->nodeType == XMLReader::END_ELEMENT) $depth--;
}
return $text;
}
}
?>
Just use XMLReader2 instead of XMLReader.
Nate ¶
13 years ago
It is interesting to note that this function will stop on closing tags as well. I have an XML document similar to the following:
<root>
<columns>
<column>columnX</column>
<column>columnY</column>
</columns>
<table>
<row>
<columnX>38</columnX>
<columnY>50</columnY>
</row>
<row>
<columnX>82</columnY>
<columnY>28</columnY>
</row>
...
</table>
</root>
I need to parse the <columns> object to know what attributes to check for from each <row> node. Therefore I was doing the following:
<?php
while ($xml->read()) {
if ($xml->name === 'column') {
//parse column node to into $columns array
}
elseif ($xml->name === 'row') {
//parse row node, using constructed $columns array
}
}
?>
This kind of worked in that I ended up with an array of all the data I wanted, but the array I constructed was twice as large as I expected and every other entry was empty. Took me a while to debug, but finally figured out that checking <?php $xml->name === 'row' ?> matches both <row> and </row>, so the check should really be something more like:
<?php
if ($xml->name === 'row' && $xml->nodeType == XMLReader::ELEMENT) {
// parse row node
}
?>
I would have liked to use the next() function instead, but as I needed to parse 2 different subtrees, I couldn't figure out how to find all the columns, reset the pointer, and then find all the rows.
peter at 3xe dot co dot uk ¶
8 years ago
Another approach to the 'also reads closing tags' gotcha:
<?php
$reader = new XMLReader();
$reader->open('users.xml');
while ($reader->read()) {
if ($reader->nodeType == XMLReader::END_ELEMENT) {
continue; //skips the rest of the code in this iteration
}
//do something with desired node type
if($reader->name == 'user') {
//...
}
}
?>
ecziegler at gmail ¶
10 years ago
If like myself you have been turning the interwebz upside down looking for a solution for this issue:
PHP Warning: XMLReader::read(): /tmp/xml_feed.xml:4183934: parser error : Input is not proper UTF-8, indicate encoding !
For some reason, this warning breaks the execution - is it a fatal error in disguise?
After days of frustration I found it!!!!
tidy -xml -o output.xml -utf8 -f error.log input.xml
You can invoque tidy using exec, It takes several seconds to convert a 250Mb feed, but it worthy the time.
In my case the issue was with latin1 charset, and for some reason I had to pass the xml through tidy 2 times - first time around creates new errors, second time it fixes everything.
I know invalid xml should be fixed by xml creators, but it works differently in the real world.
↑ and ↓ to navigate •
Enter to select •
Esc to close
Press Enter without
selection to search using Google