2010-05-19 7 views
3

Voici un bit par exemple à partir du fichier xml:paires clé/valeur de xml-style plist simplexml en php

<array> 
    <dict> 
     <key>Name</key> 
     <string>Joe Smith</string> 
     <key>Type</key> 
     <string>Profile</string> 
     <key>Role</key> 
     <string>User</string> 
     <key>Some Number</key> 
     <integer>1</integer> 
     <key>Some Boolean</key> 
     <true/> 
    </dict> 
</array> 

J'ai deux objectifs distincts. La première consiste à extraire un tableau à partir du noeud dict qui ressemblerait à ceci:

[Name] => Joe Smith 
[Type] => Profile 
[Role] => User 
[Some Number] => 1 
[Some Boolean] => true 

Ce n'est pas essentiel que le booléen inclus, donc si cela ajoute à la complexité trop, je préfère simplement savoir comment faire face à les autres pour le moment.

Le deuxième objectif est de pouvoir sélectionner le nœud de valeur (<string>, <integer>, etc.) afin que je puisse changer la valeur. Je sais que je devrais le sélectionner en fonction de la valeur de texte de l'élément clé précédent.

Je pense que le XPath devrait fonctionner:

//key[.=$keyname]/following-sibling[1] 

Mais je ne suis pas sûr. Fondamentalement, tout ce système que Apple utilise semble logique, mais totalement contraire à ma compréhension de la façon dont le langage XML est censé fonctionner. Si je courais le monde, le XML original ressemblerait plus:

<dict type="array"> 
    <value key="Name" type="string">Joe Smith</value> 
    <value key="Type" type="string">Profile</value> 
    <value key="Role type="string">User</value> 
    <value key="Some Number" type="integer">1</value> 
    <value key="Some Boolean" type="boolean">true</value> 
</dict> 

Mais comme il est assez logique, je me demande si je manque une certaine façon évidente de la manipuler.

Répondre

2

Ce sélecteur xpath me semble aller dans ce sens. Vous voudrez probablement vérifier la valeur du frère que vous récupérez, pour voir si c'est la balise que vous voulez changer (dans le cas booléen) ou bien la valeur de l'élément.

En ce qui concerne l'extraction des données dans un tableau, quelque chose le long des lignes de ...

$xml = new SimpleXMLElement($data); 

$output = array(); 
$key = null; 
$value = null; 
foreach ($xml->dict->children() as $child) { 
    if ($child->getName() == 'key') { 
    $key = (string)$child; 
    } elseif (!is_null($key)) { 
    $childStr = (string)$child; 
    $value = (empty($childStr) ? $child->getName() : $childStr); 
    } 

    if (!is_null($key) && !is_null($value)) { 
    $output[$key] = $value; 

    $key = null; 
    $value = null; 
    } 
} 

var_dump($output); 

... devrait faire ce que vous cherchez ce que je comprends.

James

1

Vous pouvez utiliser

/plist/dict/key[.='Name']/following-sibling::*[1] 

pour sélectionner la chaîne-noeud "Joe Smith" et le mettre à jour en conséquence.

Mon code PHP pour la mise à jour des fichiers XML en utilisant XPath ressemble à ceci:

function updateNodesByXPath($xmlin, $expression, $value) { 
    $dom = new DOMDocument(); 
    $dom->preserveWhiteSpace = true; 
    $dom->formatOutput = false; 
    $dom->loadXML($xmlin); 
    $xpath = new DOMXPath($dom); 
    $elements = $xpath->query($expression); 
    foreach ($elements as $element) { 
     $element->nodeValue = $value; 
    } 
    $xmlout = $dom->saveXML($dom, LIBXML_NOEMPTYTAG); 

    // Add XML header when present before (DOMDocument::saveXML will remove it) 
    if (strncasecmp($xmlin, '<?xml', 5)) { 
     $xmlout = preg_replace('~<\?xml[^>]*>\s*~sm', '', $xmlout); 
    } 

    return $xmlout; 
}