Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Because your input data is nicely formatted you can create a very simple recursive descendant parser - even not that much recursion involved. Or just with a simple stack:</p> <pre><code>$props = array_filter(array_map('trim', explode("\n", $prop))); $stack = [$node = $xml = new SimpleXMLElement('&lt;root/&gt;')]; foreach ($props as $str) { if ($str === '}') { array_pop($stack); $node = end($stack); continue; } if (preg_match('~^(\w+) {$~', $str, $matches)) { $node = $stack[] = $node-&gt;addChild($matches[1]); continue; } if (preg_match('~^(\w+):\s*(.*)$~', $str, $matches)) { $node-&gt;addChild($matches[1], htmlspecialchars($matches[2])); continue; } throw new UnexpectedValueException(sprintf('Unable to parse: "%s"', $str)); } $xml-&gt;asXML('php://output'); </code></pre> <p>The output for your second example (previously missing) then is (beautified):</p> <pre><code>&lt;?xml version="1.0"?&gt; &lt;root&gt; &lt;button&gt; &lt;large&gt; &lt;bond&gt; &lt;width&gt;10px;&lt;/width&gt; &lt;height&gt;10px;&lt;/height&gt; &lt;/bond&gt; &lt;style&gt; &lt;background&gt; &lt;color&gt;#ffffff;&lt;/color&gt; &lt;image&gt;url(www.px.com/aui.png) -10px;&lt;/image&gt; &lt;another&gt; &lt;width&gt;100px;&lt;/width&gt; &lt;height&gt;100px;&lt;/height&gt; &lt;/another&gt; &lt;/background&gt; &lt;/style&gt; &lt;/large&gt; &lt;small&gt; &lt;bond&gt; &lt;width&gt;10px;&lt;/width&gt; &lt;height&gt;10px;&lt;/height&gt; &lt;/bond&gt; &lt;style&gt; &lt;color&gt;#fff;&lt;/color&gt; &lt;border&gt;1px solid #000;&lt;/border&gt; &lt;/style&gt; &lt;/small&gt; &lt;/button&gt; &lt;/root&gt; </code></pre> <p>I recommend you use XML here because it can represent the structure better than an array which can not have duplicate keys.</p> <p>It would be also possible to use recursive function calls instead of the stack. But this requires to wrap the input stream in a no-rewind iterator to not break (or using <code>array_shift</code> but I do not like that much):</p> <pre><code>$parse = function($p, SimpleXMLElement $t) use (&amp;$parse) { foreach($p as $s) { if ($s === '}') { break; } if (preg_match('~^([^ ]+) {$~', $s, $m)) { $p-&gt;next(); $parse($p, $t-&gt;addChild($m[1])); continue; } if (preg_match('~^([^:]+):\s*(.*)$~', $s, $m)) { $n = $t-&gt;addChild($m[1], htmlspecialchars($m[2])); continue; } } }; $props = array_filter(array_map('trim', explode("\n", $prop))); $xml = new SimpleXMLElement('&lt;root/&gt;'); $parse(new NoRewindIterator(new ArrayIterator($props)), $xml); $xml-&gt;asXML('php://output'); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload