2009-12-15 6 views
1

J'ai posé une question similaire la semaine dernière mais je n'ai pas eu de réponse qui l'a vraiment clouée. Je soupçonne que la question doit être dit plus clairement si ici va:PHP - Extraire un morceau de XML à partir d'un document XML plus volumineux

Compte tenu de cette XML:

<?xml version="1.0" encoding="utf-8"?> 
<everyone> 
    <guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 
</everyone> 

Comment puis-je retourner précisément ceci:

<guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 

Je ne veux pas simplexml objet, je ne veux pas convertir quelque chose, je ne veux pas seulement les valeurs de nœuds, je ne veux pas un nouveau document XML avec son en-tête correspondant ... juste ce morceau de XML. Impossible d'utiliser des bibliothèques externes ... rien qui ne soit livré avec une installation PHP moyenne et standard. Comment puis-je extraire l'un de l'autre?

Ma meilleure estimation? Utilisez DomDocument pour obtenir les noms et le contenu des nœuds en quelque sorte, puis reconstruisez ce que je veux en utilisant une boucle foreach et en répercutant les différents noms et valeurs des nœuds, y compris les fins de ligne, pour formater correctement tout. Cependant, cela semble être incroyablement maladroit. Je pense qu'il y a une façon plus simple de le faire, donc je veux voir si quelqu'un ici sur stackoverflow sait ce que c'est (ou peut me dire qu'il n'y a, en fait, pas un moyen plus facile). Merci d'avance.

+1

Si vous avez des garanties sur la mise en forme de votre entrée, ne vous voulez juste enlever les deux premières lignes, et enlever la dernière ligne? – catchmeifyoutry

+0

Bon point, merci! – Lothar

Répondre

2
$string = <<<XML 
<?xml version="1.0" encoding="utf-8"?> 
<everyone> 
    <guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 
</everyone> 

XML; 

$xml = new SimpleXMLElement($string); 
$nodes = $xml->xpath('/everyone/guest'); 

$result = ''; 
foreach ($nodes as $node) { 
    $result .= $node->asXML()."\n"; 
} 
echo $result; 
die; 
+0

C'était facile à faire et était aussi rapide ou plus rapide que les autres solutions. J'apprécie l'aide. – Lothar

1
preg_match('`<guest>.*</guest>`is', $xml, $matches); 
print_r($matches); 
2
$reader = new XMLReader(); 
$reader->xml($xml_str); 
$reader->read(); 
$inner = $reader->readInnerXML(); 

// $inner is your desired xml string. 

Un avantage d'utiliser XMLReader est qu'il utilise moins de mémoire que SimpleXML ou les classes DOM. Un autre est que c'est très rapide.

+0

Je pensais que ce serait aussi le plus rapide, mais quand je l'ai marqué par rapport aux autres solutions, il s'est avéré être le plus lent. En utilisant un fichier XML avec un millier de nœuds à sélectionner, les autres solutions duraient généralement environ 60% de temps (la solution simplexmlelement xpath valait en moyenne 5,8 ms alors que cette solution basée sur XMLReader durait en moyenne 10 ms). Merci quand même pour le conseil. M'a aidé à mieux comprendre le tout. – Lothar

+0

Je viens de le tester moi-même sur un très gros fichier et vous avez raison; il est plus lent que SimpleXML et DOMXPath, et à peu près le même ratio que vos tests ont montré. Cela me surprend aussi, car je l'ai trouvé généralement plus rapide lors de la récupération de toutes les données, noeud par noeud, à partir de fichiers volumineux. – GZipp

+0

Utilise-t-il toujours moins de mémoire? – shredding

2

Quelque chose comme ça (en utilisant XPath - si vous avez une autre façon d'obtenir une liste des éléments invités, vous pouvez l'utiliser) devrait faire l'affaire.

$xml = ''; 
$xpath = new DOMXPath($document); 
foreach($xpath->query('//everyone/guest') as $guestNode) { 
    $xml .= $document->saveXML($guestNode); 
} 
+0

Cela a fonctionné, mais pour une raison quelconque, j'ai continué à obtenir de l'espace supplémentaire pour les choses. Je pourrais l'enlever avec trim(), je suppose. Merci pour le conseil. – Lothar

Questions connexes