9
votes

XML dans une matrice associative à l'aide de PHP

Quelqu'un peut-il aider à convertir des données d'un document XML en une matrice associative? Je rencontre des problèmes étant donné que la structure XML est en quelque sorte 3D et que la matrice est plus d'une structure 2D (veuillez pardonner mon manque de terminologie correcte dans l'ensemble). Les éléments XML ont des attributs, des enfants et des grands-enfants (mais je ne connaissais jamais leurs noms), je pensais donc que j'essayais d'essayer de faire la clé dans la matrice une concaténation de chaque nom enfant / attribute et la valeur égale à, eh bien, la valeur. Problème est que j'ai besoin du nom d'attribut et de la valeur dans le cadre de la clé de matrice concaténée pour le rendre unique ...

Par exemple: p>

function flattenArray ($array, $baseName = NULL)
{
    reset($array);
    while (list ($key, $value) = each($array)) {
        $outKey = $key . "-";
        if (is_array($value)) {
            flattenArray($value, $baseName . $outKey);
        } else {
            $finalKey = $baseName . rtrim($outKey, '-');
            $finalValue = $value;
            echo "$finalKey = $finalValue\n";
        }
    }
}


3 commentaires

Pouvez-vous publier le code qui donne la sortie incorrecte?


L'utilisation d'un XML lib pourrait aider. php.net/manual/fr/refs.xml.php


Pouvez-vous s'il vous plaît expliquer pourquoi vous voulez faire cela? Pourquoi ne pouvez-vous pas utiliser une arborescence comme offert par DOM ou SIMPLEXML?


6 Réponses :


3
votes

Lire le XML dans un objet DOM, en boucle, enregistrer les résultats dans un tableau. Est-ce simple.


1 commentaires

Ceci est une valeur de faible valeur par rapport à d'autres messages sur cette page. Ressemble plus à un commentaire / comme un indice qu'une réponse.



5
votes

Un exemple pourrait être: xxx

sortie: xxx

ce n'est pas exactement ce que vous cherchez, mais c'est un début et peut facilement être modifié pour donner des résultats différents.


0 commentaires

1
votes

Les tableaux simples peuvent être 2D mais des tableaux multidimensionnels peuvent reproduire une structure hiérarchique comme XML très facilement.

Google 'Associative multi-dimensionnel multi-dimensionnel PHP' pour plus d'informations.

Cependant, comme cela Déjà été indiqué, PHP dispose d'un analyseur XML intégré, il ne devrait donc pas y avoir de besoin de recréer le XML dans une matrice de toute façon, laissez-la simplement l'aplatiser à un tableau simple.

dans PHP Votre structure de matrice devrait ressembler à ceci: xxx

etc ...


0 commentaires

45
votes

Cela a fonctionné super pour moi, et c'était simple. XXX


1 commentaires

Cela fonctionne bien, mais échoue avec CDATA. Afin de prendre en charge CDATA, consultez ce filtre: PHP.net/ Manuel / FR / FONCTION.SIMPLEXML-CHARGE-STREND.PHP # 82686



5
votes

Voici ma fonction pour générer une matrice associée, dérivée de

Cast reconsive de SimplexMlObject au tableau xxx

matrice générée: xxx


0 commentaires

0
votes

J'ai modifié la réponse d'User655000 pour être plus proche de la manière dont JSON_Decode (JSON_ENCODE ($ DOM)) formater / renvoyer les données. J'ai également fait le paramètre de tableau initial en option, car il va simplement être vide de toute façon.

Je ne pouvais pas utiliser la méthode de décodage (encoder) car il semble y avoir des bogues dans la fonction de codage de PHP, ce qui a abouti au décodage () retourner null sur certains échantillons de données. J'ai essayé une version plus sûre de la fonction de codage, mais elle a manqué de mémoire. P>

Il y a une différence de comportement mineure. La méthode de décodage (encoder) jettera tous les attributs (éventuellement des enfants aussi) s'il y a un numéroText. Ma méthode ne le fait pas. P>

function readxml($xmlfile, $recursive = false){
    $ob = simplexml_load_file($xmlfile);
    //primary method
    $json = json_encode($ob);
    $array = json_decode($json, true);
    if(is_null($array)){//backup method
        $array = xml2assoc($ob);
    }
    return $array;
}

function xml2assoc($obj, &$arr = null) {
    $children = $obj->children();//->count(); 
    $nodes = [];
    foreach ( $children as $elementName => $node ) {
        if(!isset($nodes[$elementName])){
            $nodes[$elementName] = 0;
        }
        $nodes[$elementName]++;
    }
    $indexes = [];

    if($arr === null){
        $arr = [];
    }
    foreach ( $children as $elementName => $node ) {
        $temp = array();
        $grandchildren = $node->children()->count();
        
        //attributes        
        $attributes = $node->attributes();
        foreach ( $attributes as $attributeName => $attributeValue ) {
            $attribName = trim((string) $attributeName);
            $attribVal = trim((string) $attributeValue);
            $temp["@attributes"][$attribName] = $attribVal;
        }
        
        //text      
        $text = (string) $node;
        $text = trim($text);
        if (strlen($text) > 0) {
            if(count($temp) == 0 && $grandchildren == 0){
                $temp = $text;//discard the children/attribute data since there aren't any
            } else {
                $temp["NodeText"] = $text;//retain the children/attributes
            }
        }       
        
        //grandchildren
        if($temp || is_string($temp) || $grandchildren > 0 ){
            if( $nodes[$elementName] == 1 ){//only one of it's kind
                $arr[$elementName] = $temp;
                xml2assoc($node, $arr[$elementName]);
            } else {//has multiple nodes of the same kind
                if(isset($indexes[$elementName])){
                    $indexes[$elementName]++;
                } else {
                    $indexes[$elementName] = 0;
                }
                $index = $indexes[$elementName];
                $arr[$elementName][$index] = $temp;
                xml2assoc($node, $arr[$elementName][$index]);
            }
        }
    }
    return $arr;
}


0 commentaires