Php SimpleXML kullanarak Plist-style xml anahtar / değer çiftleri Başlarken

2 Cevap php

İşte xml dosyasından bir örnek biraz:

<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>

Ben iki ayrı hedefleri var. İlk gibi görünecektir dict düğümden bir dizi ayıklamak için:

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

Bu boolean dahil olması çok önemli değil, böylece çok fazla karmaşıklık ekler eğer, ben değil sadece şimdi için başkalarıyla uğraşmak nasıl bilirdiniz.

Ikinci golü ben değerini değiştirmek böylece (<string>, <integer>, vb) değer düğümü seçmek mümkün değildir. Ben önceki anahtar öğesinin metin değerine göre seçmek gerekir biliyorum.

Ben şu XPath çalışması gerektiğini düşünüyorum:

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

Ama emin değilim.

Temelde, Apple kullanan bütün bu sistem XML çalışmak gerekiyordu nasıl benim anlayış mantıklı, ama tamamen aykırı görünüyor. Ben dünya koştu eğer, orijinal XML daha fazla gibi görünecektir:

<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>

Bu oldukça mantıklı beri bunu işleme bazı bariz bir şekilde eksik yaşıyorum ama, ben merak ediyorum.

2 Cevap

Bu xpath seçici bana bu amaç için iyi görünüyor. Muhtemelen, almak kardeş değerini denetlemek için bu gerçekten elemanın değerini (boolean durumda) değiştirme ya da istediğiniz etiket olmadığını görmek isterdim.

Bir dizinin, çizgisinde bir şey içine veri çekme açısından ...

$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);

... Sen ne anlamak için aradığınızı yapmalıdır.

James

Sen kullanabilirsiniz

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

dize düğümü "Joe Smith" seçin ve buna göre güncellemek için.

XPath kullanarak XML dosyalarını güncelleyerek My PHP kod şöyle görünür:

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;
}