Re: Sequential access of XML nodes.

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

 



On 27 September 2011 03:38, Ross McKay <rosko@xxxxxxxxxxx> wrote:
> 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;

Thanks for all of that.

It seems that the SimpleXMLIterator is perfect for me.

I need to see if the documents I'm needing to process have multiple
namespaces. If they have do, then I'm not exactly sure what to do at
this stage.

Richard.
-- 
Richard Quadling
Twitter : EE : Zend : PHPDoc
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY : bit.ly/lFnVea

-- 
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