0

I'm after a way of making simplexml_load_string return a document where all the text values are urldecoded. For example:

$xmlstring = "<my_element>2013-06-19+07%3A20%3A51</my_element>";
$xml = simplexml_load_string($xmlstring);
$value = $xml->my_element;
//and value would contain: "2013-06-19 07:20:51"

Is it possible to do this? I'm not concerned about attribute values, although that would be fine if they were also decoded.

Thanks!

user1309663
  • 105
  • 7
  • 1
    Why not just apply `urldecode` to your `$xmlstring` _before_ creating a SimpleXML object from it …? – CBroe Jul 23 '13 at 09:25
  • Thanks for the comment. I thought that it might be more efficient to just decode the values, especially with larger documents. – user1309663 Jul 23 '13 at 22:12

2 Answers2

0

you can run

$value = urldecode( $value )

which will decode your string.

See: http://www.php.net/manual/en/function.urldecode.php

moscar
  • 355
  • 3
  • 11
0

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"
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836