it-swarm.dev

Melhor analisador de XML para PHP

Eu usei o XML Parser antes, e mesmo que funcionasse bem, eu não estava feliz com isso em geral, parecia que eu estava usando soluções alternativas para coisas que deveriam ser funcionalidades básicas.

Recentemente, vi o SimpleXML, mas ainda não experimentei. É mais simples? Quais são as vantagens e desvantagens de ambos? Algum outro parsers que você usou?

140
Murat Ayfer

Eu teria que dizer SimpleXML leva o bolo porque é primeiramente uma extensão, escrito em C, e é muito rápido. Mas segundo, o documento analisado assume a forma de um objeto PHP. Então você pode "consultar" como $root->myElement.

102
Robert K

Dê uma olhada no PHP extensões XML disponíveis e veja http://devzone.zend.com/243/ e http://devzone.zend.com/1035 / para uma discussão desses.

A principal diferença entre o XML Parser e o SimpleXML é que este último não é um analisador de pull. O SimpleXML é construído sobre as extensões DOM e carregará todo o arquivo XML na memória. O XML Parser, como o XMLReader, carregará apenas o nó atual na memória. Você define manipuladores para nós específicos que serão acionados quando o Analisador os encontrar. Isso é mais rápido e economiza memória. Você paga por isso sem poder usar o XPath.

Pessoalmente, acho SimpleXml bastante limitante (portanto, simples) no que oferece sobre DOM. Você pode alternar facilmente entre DOM e SimpleXml, mas eu normalmente não me preocupo e vou direto para a rota DOM. DOM é uma implementação da API DOM do W3C, portanto, você pode estar familiarizado com isso de outros idiomas, por exemplo, JavaScript.

41
Gordon

Esta é uma função útil para análise rápida e fácil de xml quando uma extensão não está disponível:

<?php
/**
 * Convert XML to an Array
 *
 * @param string  $XML
 * @return array
 */
function XMLtoArray($XML)
{
    $xml_parser = xml_parser_create();
    xml_parse_into_struct($xml_parser, $XML, $vals);
    xml_parser_free($xml_parser);
    // wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie
    $_tmp='';
    foreach ($vals as $xml_elem) {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_level!=1 && $x_type == 'close') {
            if (isset($multi_key[$x_tag][$x_level]))
                $multi_key[$x_tag][$x_level]=1;
            else
                $multi_key[$x_tag][$x_level]=0;
        }
        if ($x_level!=1 && $x_type == 'complete') {
            if ($_tmp==$x_tag)
                $multi_key[$x_tag][$x_level]=1;
            $_tmp=$x_tag;
        }
    }
    // jedziemy po tablicy
    foreach ($vals as $xml_elem) {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_type == 'open')
            $level[$x_level] = $x_tag;
        $start_level = 1;
        $php_stmt = '$xml_array';
        if ($x_type=='close' && $x_level!=1)
            $multi_key[$x_tag][$x_level]++;
        while ($start_level < $x_level) {
            $php_stmt .= '[$level['.$start_level.']]';
            if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level])
                $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']';
            $start_level++;
        }
        $add='';
        if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) {
            if (!isset($multi_key2[$x_tag][$x_level]))
                $multi_key2[$x_tag][$x_level]=0;
            else
                $multi_key2[$x_tag][$x_level]++;
            $add='['.$multi_key2[$x_tag][$x_level].']';
        }
        if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) {
            if ($x_type == 'open')
                $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
            else
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];';
            eval($php_stmt_main);
        }
        if (array_key_exists('attributes', $xml_elem)) {
            if (isset($xml_elem['value'])) {
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
                eval($php_stmt_main);
            }
            foreach ($xml_elem['attributes'] as $key=>$value) {
                $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;';
                eval($php_stmt_att);
            }
        }
    }
    return $xml_array;
}
?>
24
NexusRex

Oi eu acho que o SimpleXml é muito útil. E com isso eu estou usando xpath ;

$xml = simplexml_load_file("som_xml.xml");

$blocks  = $xml->xpath('//block'); //gets all <block/> tags
$blocks2 = $xml->xpath('//layout/block'); //gets all <block/> which parent are   <layout/>  tags

Eu uso muitas configurações xml e isso me ajuda a analisá-las muito rápido. SimpleXml está escrito em C, por isso é muito rápido.

14
Vahan

Depende do que você está tentando fazer com os arquivos XML. Se você está apenas tentando ler o arquivo XML (como um arquivo de configuração), o The Wicked Flea está correto ao sugerir o SimpleXML, pois cria o que equivale a ArrayObjects aninhados. por exemplo. O valor será acessível por $ xml-> root-> child.

Se você está procurando manipular os arquivos XML, provavelmente é melhor usar DOM XML

11
dcousineau

o analisador crxml é realmente fácil de analisar.

Esta classe tem uma função de pesquisa, que usa um nome de nó com qualquer namespace como argumento. Ele procura o xml pelo nó e imprime a declaração de acesso para acessar esse nó usando essa classe. Essa classe também torna a geração de XML muito fácil.

você pode baixar esta classe em

http://freshmeat.net/projects/crxml

ou de phpclasses.org

http://www.phpclasses.org/package/6769-PHP-Manipulate-XML-documents-as-array.html

0
Sandeep.C.R