As long as each value is inside an element of its own (in SimpleXML you can not process text-nodes on its own, compare with the table in Which DOMNodes can be represented by SimpleXMLElement?) this is possible.
As others have outlined, this works by applying the urldecode
function on each of these elements.
To do that, you need to change and add some lines of code:
$xml = simplexml_load_string($xmlstring, 'SimpleXMLIterator');
if (!$xml->children()->count()) {
$nodes = [$xml];
} else {
$nodes = new RecursiveIteratorIterator($xml, RecursiveIteratorIterator::LEAVES_ONLY);
}
foreach($nodes as $node) {
$node[0] = urldecode($node);
}
This code-example takes care that each leave is processed and in case, it's only the root element, that that one is processed. Afterwards, the whole document is changed so that you can access it as known. Demo:
<?php
/**
* URL decode all values in XML document in PHP
* @link https://stackoverflow.com/q/17805643/367456
*/
$xmlstring = "<root><my_element>2013-06-19+07%3A20%3A51</my_element></root>";
$xml = simplexml_load_string($xmlstring, 'SimpleXMLIterator');
$nodes = $xml->children()->count()
? new RecursiveIteratorIterator(
$xml, RecursiveIteratorIterator::LEAVES_ONLY
)
: [$xml];
foreach ($nodes as $node) {
$node[0] = urldecode($node);
}
echo $value = $xml->my_element; # prints "2013-06-19 07:20:51"