86 votes

Comment utiliser XMLReader en PHP?

J'ai le fichier XML suivant, le fichier est plutôt volumineux et je n'ai pas réussi à obtenir le fichier simplexml pour l'ouvrir et le lire; j'essaie donc XMLReader sans succès en php

 <?xml version="1.0" encoding="ISO-8859-1"?>
<products>
    <last_updated>2009-11-30 13:52:40</last_updated>
    <product>
        <element_1>foo</element_1>
        <element_2>foo</element_2>
        <element_3>foo</element_3>
        <element_4>foo</element_4>
    </product>
    <product>
        <element_1>bar</element_1>
        <element_2>bar</element_2>
        <element_3>bar</element_3>
        <element_4>bar</element_4>
    </product>
</products>
 

Malheureusement, je n'ai pas trouvé de bon tutoriel à ce sujet pour PHP et j'aimerais voir comment je peux obtenir le contenu de chaque élément à stocker dans une base de données.

À votre santé!

232voto

Josh Davis Points 12974

Tout dépend de l'unité de travail, mais je suppose que vous êtes à essayer de traiter chaque <product/> des nœuds dans la succession.

Pour cela, le moyen le plus simple serait d'utiliser XMLReader d'obtenir à chaque nœud, puis utiliser SimpleXML pour y accéder. De cette façon, vous gardez l'utilisation de la mémoire faible parce que vous êtes le traitement d'un nœud à un moment et vous avez encore l'effet de levier SimpleXML est la facilité d'utilisation. Par exemple:

$z = new XMLReader;
$z->open('data.xml');

$doc = new DOMDocument;

// move to the first <product /> node
while ($z->read() && $z->name !== 'product');

// now that we're at the right depth, hop to the next <product/> until the end of the tree
while ($z->name === 'product')
{
    // either one should work
    //$node = new SimpleXMLElement($z->readOuterXML());
    $node = simplexml_import_dom($doc->importNode($z->expand(), true));

    // now you can use $node without going insane about parsing
    var_dump($node->element_1);

    // go to next <product />
    $z->next('product');
}

Rapide aperçu des avantages et inconvénients des différentes approches:

XMLReader seulement

  • Avantages: rapide, utilise peu de mémoire

  • Inconvénients: trop dur à écrire et déboguer, nécessite beaucoup de l'espace utilisateur code pour faire quelque chose d'utile. Userland code est lente et sujette à l'erreur. De Plus, il vous laisse avec plus de lignes de code à maintenir

XMLReader + SimpleXML

  • Pour: n'utilise pas beaucoup de mémoire (seulement la mémoire nécessaire pour traiter un nœud) et SimpleXML est, comme son nom l'indique, vraiment facile à utiliser.

  • Inconvénients: la création d'un objet SimpleXMLElement pour chaque nœud n'est pas très rapide. Vous avez vraiment à l'indice de référence pour comprendre si c'est un problème pour vous. Même une modeste machine serait capable de traiter un millier de nœuds par seconde, cependant.

XMLReader + DOM

  • Avantages: consomme autant de mémoire que SimpleXML, et XMLReader::expand() est plus rapide que de créer un nouveau SimpleXMLElement. Je voudrais qu'il était possible d'utiliser simplexml_import_dom() , mais il ne semble pas fonctionner dans ce cas

  • Inconvénients: DOM est gênant de travailler avec. C'est à mi-chemin entre XMLReader et SimpleXML. Pas aussi compliqué et bizarre comme XMLReader, mais à des années-lumière de travail avec SimpleXML.

Mon conseil: écrire un prototype avec SimpleXML, voir si cela fonctionne pour vous. Si le rendement est primordial, essayez DOM. Rester aussi loin de XMLReader que possible. N'oubliez pas que plus le code que vous écrivez, plus la possibilité de vous introduire des bogues ou de l'introduction de la performance des régressions.

12voto

try5tan3 Points 38

Pour XML formaté avec des attributs ...

data.xml:

 <building_data>
<building address="some address" lat="28.902914" lng="-71.007235" />
<building address="some address" lat="48.892342" lng="-75.0423423" />
<building address="some address" lat="58.929753" lng="-79.1236987" />
</building_data>
 

code php:

 $reader = new XMLReader();

if (!$reader->open("data.xml")) {
    die("Failed to open 'data.xml'");
}

while($reader->read()) {
  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'building') {
    $address = $reader->getAttribute('address');
    $lattitude = $reader->getAttribute('lat');
    $longitude = $reader->getAttribute('lng');
}

$reader->close();
 

7voto

Francis Lewis Points 3379

La réponse acceptée m'a donné un bon départ, mais elle a introduit plus de cours et plus de traitement que je l'aurais souhaité. c'est donc mon interprétation:

 $xml_reader = new XMLReader;
$xml_reader->open($feed_url);

// move the pointer to the first product
while ($xml_reader->read() && $xml_reader->name != 'product');

// loop through the products
while ($xml_reader->name == 'product')
{
    // load the current xml element into simplexml and we're off and running!
    $xml = simplexml_load_string($xml_reader->readOuterXML());

    // now you can use your simpleXML object ($xml).
    echo $xml->element_1;

    // move the pointer to the next product
    $xml_reader->next('product');
}

// don't forget to close the file
$xml_reader->close();
 

2voto

JP. Points 858

XMLReader est bien documenté sur le PHP du site. C'est un XML Tirer de l'Analyseur, ce qui signifie qu'il est utilisé pour itérer sur les nœuds (ou Nœuds) du document XML donné. Par exemple, vous pouvez aller à travers l'ensemble du document que vous avez donné comme ceci:

<?php
$reader = new XMLReader();
if (!$reader->open("data.xml"))
{
    die("Failed to open 'data.xml'");
}
while($reader->read())
{
    $node = $reader->expand();
    // process $node...
}
$reader->close();
?>

C'est ensuite à vous de décider comment traiter avec le nœud retourné par XMLReader::expand().

2voto

sebob Points 50
Simple example:

public function productsAction()
{
    $saveFileName = 'ceneo.xml';
    $filename = $this->path . $saveFileName;
    if(file_exists($filename)) {

    $reader = new XMLReader();
    $reader->open($filename);

    $countElements = 0;

    while($reader->read()) {
        if($reader->nodeType == XMLReader::ELEMENT) {
            $nodeName = $reader->name;
        }

        if($reader->nodeType == XMLReader::TEXT && !empty($nodeName)) {
            switch ($nodeName) {
                case 'id':
                    var_dump($reader->value);
                    break;
            }
        }

        if($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == 'offer') {
            $countElements++;
        }
    }
    $reader->close();
    exit(print('<pre>') . var_dump($countElements));
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X