Getting key / value pairs from xml plist style using simplexml in php

Here is an example bit from the xml file:

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

I have two separate goals. The first is to extract the array from dictnode, which will look like this:

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

It doesn't matter if the boolean is turned on, so if that adds too much complexity, I would probably know how to deal with the rest at the moment.

The second goal is to select the value of node ( <string>, <integer>etc.) so that I can change the value. I know that I will need to select it based on the text value of the previous key element.

I think the following XPath should work:

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

But I'm not sure.

, , Apple, , , XML. , XML :

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

, , .

+3
2

xpath . , , , , ( ) .

, - ...

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

... , , , .

+2

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

- node " " .

PHP- XML XPath :

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

Source: https://habr.com/ru/post/1746138/


All Articles