PHP cookbook, 2nd editon, Recipe 12.5

来源:互联网 发布:2015中国经济数据 编辑:程序博客网 时间:2024/05/16 13:00
Recipe 12.5. Parsing Large XML Documents:
<?php
$reader = new XMLReader();
$reader->XML($catalog);

// Perl Cookbook ISBN is 0596003137
// Use array to make it easy to add additional ISBNs

$isbns = array('0596003137' => true);

/* Loop through document to find first <book> */
while ($reader->read()) {
    
/* If you're at an element named 'book' */
    
if ($reader->nodeType == XMLREADER::ELEMENT &&
        
$reader->localName == 'book') {
        
break;
    }
}

/* Loop through <book>s to find right ISBNs */
do {
    
if ($reader->moveToAttribute('isbn'&&
        
isset($isbns[$reader->value])) {
        
while ($reader->read()) {
            
switch ($reader->nodeType) {
            
case XMLREADER::ELEMENT:
                
print $reader->localName . "";
                
break;
            
case XMLREADER::TEXT:
                
print $reader->value . " ";
                
break;
            
case XMLREADER::END_ELEMENT;
                
if ($reader->localName == 'book') {
                    
break 2;
                }
            }
        }
    }
while ($reader->next());
?>
 

The first while( ) iterates sequentially until it finds the first <book> element.

Having lined yourself up correctly, you then break out of the loop and start checking ISBN numbers. That's handled inside a do... while( ) loop that uses $reader->next( ) to move down the <book> list. You cannot use a regular while( ) here or you'll skip over the first <book>. Also, this is a perfect example of when to use $reader->next( ) instead of $reader->read( ).

If the ISBN matches a value in $isbns, then you want to process the data inside the current <book>. This is handled using yet another while( ) and a switch( ).

There are three different switch( ) cases: an opening element, element text, and a closing element. If you're opening an element, you print out the element's name and a colon. If you're text, you print out the textual data. And if you're closing an element, you check to see whether you're closing the <book>. If so, then you've reached the end of the data for that particular book, and you need to return to the do... while( ) loop. This is handled using a break 2;; while jumps back two levels, instead of the usual one level.