2009-10-30 10 views
1

je dois envoyer une chaîne de HTML est comme a <total> <tag>content</tag> <tag2 ref="333"> <code>somecode</code> <code>morecode</code> </tag2> <tag3> more code </tag3> </total>PHP SimpleXML Elements to Array

Cela irait dans un tableau comme:

$arra[] = "<tag>content</tag>"; 
$arra[] = "<tag2 ref="333">"; 
$arra[] = "<code ... etc 

Mais je ne suis pas à trouver comment transformer ces données dans le tableau.

Des conseils?

+0

Vous nous demandez comment utiliser un marteau pour entraîner une vis. En d'autres termes, au lieu de décrire comment vous voulez faire les choses, demandez * comment * faire les choses. Pourquoi voulez-vous avoir un tel éventail de balises incompatibles? –

+0

Oui, il semble que vous essayez d'aplatir la structure de données en quelque chose d'entièrement –

Répondre

2

Vous voulez convertir cette structure de données d'arbre:

<total> 
    <tag>content</tag> 
    <tag2 ref="333"> 
    <code>somecode</code> 
    <code>morecode</code> 
    </tag2> 
    <tag3> more code </tag3> 
</total> 

Dans une sorte de tableau associatif:

Array 
(
    [0] => "<tag>content</tag>" 
    [1] => "<tag2 ref="333"></tag2>" 
    [2] => "<code>somecode</code>" 
    [3] => "<code>morecode</code> 
    [4] => "<tag3> more code </tag3> " 
) 

serait difficile. C'est un problème CS classique qui n'a pas beaucoup de bons répondeurs. La structure arborescente fournit des informations sur les relations entre les entrées qu'un tableau plat ou une liste ne contient pas. Toute tentative d'aplatissement de l'arbre dans une liste perdra ce contexte référentiel.

Vous pouvez soit exploser la chaîne et ensuite la parcourir en gardant la trace des éléments parents ou en les ignorant (voir tag2). Si je devais faire quelque chose avec le xml que je laisserais tomber dans un SimpleXMLElement, qui produirait quelque chose comme ceci:

SimpleXMLElement Object 
(
    [tag] => content 
    [tag2] => SimpleXMLElement Object 
     (
      [@attributes] => Array 
       (
        [ref] => 333 
       ) 
      [code] => Array 
       (
        [0] => somecode 
        [1] => morecode 
       ) 
     ) 
    [tag3] => more code 
) 

Avec cela, je peux marcher avec foreach et découvrez la balise et son contenu. Je peux tester pour voir si les contenus sont des chaînes ou des éléments enfants et si c'est le cas, promenez-les. Une fonction récursive ferait un travail assez court de ce problème. Le plus gros problème est de savoir comment représenter les données une fois qu'elles sont aplaties.

Si vous l'aplatissez dans l'exemple de tableau que j'ai fourni précédemment, les balises parent et enfant perdent toute relation implicite les unes avec les autres. Si ce n'est pas un problème, génial. Ecrivez la fonction récursive et vous avez terminé. Voici quelques psudocode:

function walking($content) 
    $out is the array chunk that is returned 
    foreach $content as $tag->$data 
    if $value is an SimpleXMLElement 
     collapse $data[@attributes] into a string $attributes 
     append <$tag $attributes></$tag> to the end of $out 
     you may need to remove @attributes before recursing. 
     recurse into walking($data) and append the returned array to the end of $out 
    if $value is an Array 
     append <$tag></$tag> to the end of $out 
     recurse into walking($data) and append the returned array to the end of $out 
    if $value is a string 
     append <$tag>$value</$tag> to the end of $out 
    after looping through $content return $out. 

Toutefois, si vous devez garder en quelque sorte ceux que vous avez des relations intactes un peu d'un problème et vous devrez concevoir une sorte de système pour cette

+0

J'essaie de ce que vous avez montré, mon problème est de traiter avec les balises de fin pour le moment, le xml est construit précédemment avec php DomDocument. –

2

simplement:

$lines = explode('> ', $xml); 
foreach($lines as $line) { 
    $arra[] = $line.'> '; 
} 

Cependant, cela suppose l'échantillon donné est une représentation exacte de votre XML (à savoir que vous utilisez > et < dans les blocs de balises) et ne pas prendre en considération les blocs CDATA ou des commentaires XML. http://www.w3.org/TR/REC-xml/#syntax

Sinon, je regardais les commentaires sur la page PHP.net: http://us.php.net/manual/en/function.xml-parse.php

2

Qu'est-ce que vous essayez de le faire? Si vous donnez une image plus large du problème que vous tentez de résoudre, nous pourrions peut-être vous donner une meilleure solution.

0

Si vous obtenez les données de un fichier, puis la fonction file() vous donnera un tableau d'une ligne par rangée. Pourrait être le moyen le plus facile!

0
$xml = file_get_contents("../../xml/LL1234.xml"); 

$x = simplexml_load_string($xml); 

function viewElements($x){ 
    $Arr = $GLOBALS['Arr']; 
    if (count($x->attributes()) > 0){ 
     $attr=''; 
     foreach ($x->attributes() as $k => $v){ 
       $attr .= " $k='".$v."'"; 
     } 
    } 

    $Arr[] = "<".$x->getName()." $attr>\n"; 
    if (count($x->children()) > 0){ 
     foreach ($x->children() as $k){ 
      $GLOBALS['Arr'] = $Arr; 
      viewElements($k); 
      $Arr = $GLOBALS['Arr']; 
     } 
    }else{ 
     $Arr[] = $x[0]; 
    } 

    $Arr[] = "</".$x->getName().">"; 
    $GLOBALS['Arr'] = $Arr; 
} 

foreach ($x->children() as $k){ 
    viewElements($k); 
} 

foreach ($GLOBALS['Arr'] as $k){ 
    print $k."\n"; 
} 
?> 

Désolé pour la peine merci à tvanover Je comprends un meilleur moyen de faire cela, la solution est ci-dessous.