2010-03-31 7 views
2

J'ai un script qui recueille 4 URL (XML) en utilisant CURL et retourne un tableau avec 4 éléments recevant chacun les résultats de l'URL.Tableau de sortie de XML en XML brut

Voici le tableau:

array(3) { 
    [0]=> 
    string(41772) "<?xml version="1.0" encoding="UTF-8"?> 
<statuses type="array"> 
<status> 
    <created_at>Tue Mar 30 20:58:53 +0000 2010</created_at> 
    <id>11328253513</id> 
    <text>...</text> 
    <source...</source> 
    <truncated>false</truncated> 
    <in_reply_to_status_id></in_reply_to_status_id> 
    <in_reply_to_user_id></in_reply_to_user_id> 
    <favorited>true</favorited> 
    <in_reply_to_screen_name></in_reply_to_screen_name> 
    <user> 
    <id>1...</id> 
    <name>....</name> 
</status> 
</statuses> 
" 
    [1]=> 
    string(20630) "<?xml version="1.0" encoding="UTF-8"?> 
<statuses type="array"> 
<status> 
    <created_at>Sun Feb 28 14:12:30 +0000 2010</created_at> 
    <id>...</id> 
    <text>...</text> 
    <source>&lt;a 

etc... 

Comment puis-je facilement sortie XML à partir du tableau? J'ai également besoin de combiner les 3 structures XML en une où <statuses> commence et se termine entre chaque tableau.

Répondre

1

Pour une simple fusion comme cela, vous pouvez le faire simplement:

$xml = implode('', $theArray); 
$xml = str_replace(array('<?xml version="1.0" encoding="UTF-8"?>', 
         '<statuses type="array">', 
         '</statuses>'), '', $xml); 

$xml = '<?xml version="1.0" encoding="UTF-8"?>' 
    . '<statuses type="array">' 
    . $xml 
    . '</statuses>'; 

Note: non testé, mais fondamentalement tout ce qu'il est de coller tous les documents XML en un, puis supprimer les Prologs XML et tous les nœuds racine, de sorte que seuls les nœuds d'état restent. Ceux-ci sont ensuite enveloppés dans un squelette XML valide, par ex. prolog et le noeud racine à nouveau. Terminé. Si vous voulez travailler avec les nœuds DOM par la suite, utiliser DOM serait plus fiable, puisque DOM sait quels sont les nœuds, alors que les fonctions de chaîne n'ont aucune idée à ce sujet. Si vous décidez de travailler avec DOM, considérez loading the documents with load au lieu de CURL, comme indiqué dans l'exemple de Pascal - ou utilisez d'abord le précédent, puis load that document from the string with loadXml(). Quoi que vous décidiez d'utiliser, n'utilisez pas Regex. C'est la route de la folie.

+0

méthode I get string (109960) " sur la première ligne de $ xml – CLiown

+0

@danit l'avez-vous résolu à partir de l'autre question ou est-ce toujours un problème? – Gordon

2

Une idée possible serait de:

  • Créer une nouvelle instance $destination de DOMDocument
    • lsinitialisez avec un nœud <statuses>
  • Pour chacun de vos 3 chaînes XML:
    • le charger à un autre instance de DOMDocument: $currentDocument
    • trouver le nœud <status>, avec $currentDocument->getElementsByTagName ou un équivalent
    • import le nœud <status> vous avez trouvé le document $destination, avec $destination->importNode
  • Lorsque la boucle sur chaque chaîne XML est terminé, le document $destination devrait contenir ce que vous vouliez, et vous pouvez l'enregistrer, en utilisant $destination->saveXML


Et voici un exemple rapide de code qui pourrait vous aider à comprendre ce que je voulais dire:

D'abord, voici le tableau de chaînes XML - je leur ai fait beaucoup plus courte, mais l'idée est la même que ce que vous ont:

$strings = array(
    '<?xml version="1.0" encoding="UTF-8"?> 
    <statuses type="array"><status> 
     <id>ID 1</id> 
    </status></statuses>', 
    '<?xml version="1.0" encoding="UTF-8"?> 
    <statuses type="array"><status> 
     <id>ID 2</id> 
    </status></statuses>', 
    '<?xml version="1.0" encoding="UTF-8"?> 
    <statuses type="array"><status> 
     <id>ID 3</id> 
    </status></statuses>', 
); 


Créons le document de destination, et mettre un <statuses> en elle:

$destination = new DOMDocument(); 
$destination->formatOutput = true; 
$destinationStatuses = $destination->createElement('statuses'); 
$destination->appendChild($destinationStatuses); 


Maintenant, on boucle sur les 3 chaînes XML:

foreach ($strings as $str) { 
    $current = new DOMDocument(); 
    $current->loadXML($str); 
    $currentStatuses = $current->getElementsByTagName('status'); 
    foreach ($currentStatuses as $currentStatus) { 
    $destinationStatus = $destination->importNode($currentStatus, true); 
    $destinationStatuses->appendChild($destinationStatus); 
    } 
} 


Pour chaque chaîne, nous:

  • charge à une nouvelle DOMDocument
  • Recherchez la balise <status> (s)
  • Pour chaque balise <status>, importez-la dans le document de destination
  • Et ajoutez-la à son <statuses> tag


Et, enfin, si nous affichons le contenu du nouveau document:

echo '<pre>' . htmlspecialchars($destination->saveXML()) . '</pre>'; 


Nous obtenons:

<?xml version="1.0"?> 
<statuses> 
    <status> 
     <id>ID 1</id> 
    </status> 
    <status> 
     <id>ID 2</id> 
    </status> 
    <status> 
     <id>ID 3</id> 
    </status> 
</statuses> 

savoirnos trois <status> des trois chaînes originales ont été fusionnés en un seul document XML ;-)

+0

Overkill :) mais une surpuissance propre et fiable. – Gordon

+0

Plus de plaisir que d'utiliser des manipulations de chaînes :-p ;;; et beaucoup plus fiable que les manipulations de chaînes ;;; et dans d'autres situations, ça marchera, alors que les manipulations string/regex ne le feront pas * (même si, oui, j'avoue, c'est un peu exagéré dans cette situation précise ...) * –

+0

Sans doute et +1 pour la diligence;) – Gordon