Re: Sequential access of XML nodes.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 26 Sep 2011 14:17:43 -0400, Adam Richardson wrote:

>I believe the XMLReader allows you to pull node by node, and it's really
>easy to work with:
>http://www.php.net/manual/en/intro.xmlreader.php
>
>In terms of dealing with various forms of compression, I believe you con use
>the compression streams to handle this:
>http://stackoverflow.com/questions/1190906/php-open-gzipped-xml
>http://us3.php.net/manual/en/wrappers.compression.php

+1 here. XMLReader is easy and fast, and will do the job you want albeit
without the nice foreach(...) loop Richard spec's. You just loop over
reading the XML and checking the node type, watching the state of your
stream to see how to handle each iteration.

e.g. (assuming $xml is an open XMLReader, $db is PDO in example)

$text = '';
$haveRecord = FALSE;
$records = 0;

// prepare insert statement
$sql = '
insert into Product (ID, Product, ...)
values (:ID, :Product, ...)
';
$cmd = $db->prepare($sql);

// set list of allowable fields and their parameter type
$fields = array(
    'ID' => PDO::PARAM_INT,
    'Product' => PDO::PARAM_STR,
    ...
);

while ($xml->read()) {
    switch ($xml->nodeType) {
        case XMLReader::ELEMENT:
            if ($xml->name === 'Product') {
                // start of Product element, 
                // reset command parameters to empty
                foreach ($fields as $name => $type) {
                    $cmd->bindValue(":$name", NULL, PDO::PARAM_NULL);
                }
                $haveRecord = TRUE;
            }
            $text = '';
            break;

        case XMLReader::END_ELEMENT:
            if ($xml->name === 'Product') {
                // end of Product element, save record
                if ($haveRecord) {
                    $result = $cmd->execute();
                    $records++;
                }
                $haveRecord = FALSE;
            }
            elseif ($haveRecord) {
                // still inside a Product element, 
                // record field value and move on
                $name = $xml->name;
                if (array_key_exists($name, $fields)) {
                    $cmd->bindValue(":$name", $text, $fields[$name]);
                }
            }
            $text = '';
            break;

        case XMLReader::TEXT:
        case XMLReader::CDATA:
            // record value (or part value) of text or cdata node
            $text .= $xml->value;
            break;

        default:
            break;
    }
}

return $records;
-- 
Ross McKay, Toronto, NSW Australia
"Tuesday is Soylent Green day"

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux