1

How to escape & in a URL inside an XML element.

I have a URL inside a JavaScript object, I pass the object to PHP where the following code turns it into XML, then I put it in an XML file:

function array2xml($array, $xml = false){
    if($xml === false){
        $xml = new SimpleXMLElement('<items id="datasource"/>');
    }
    foreach($array as $key => $value){
        if(is_array($value)){
            array2xml($value, $newChild = $xml->addChild('item'));
            $newChild->addAttribute('id', $key);
        }
        else {
            $newChild = $xml->addChild('item', $value);
            $newChild->addAttribute('id', $key);
        }
    }
    return $xml->asXML();
}

The URL needs 2 query parameters so I need the &, but for some reason I can't escape it wihout allowing me to open the link.

I have tried replacing & with: &amp;, &#38;, %26 and <![CDATA[&]]> but none of these work.

Barskey
  • 423
  • 2
  • 5
  • 18
  • 1
    Have you tried [htmlspecialchars](http://php.net/htmlspecialchars) or possibly [htmlentities](http://php.net/manual/en/function.htmlentities.php)? – mtr.web Jan 17 '18 at 19:53
  • SimpleXML does all job for you. Show the example output. – u_mulder Jan 17 '18 at 19:54

1 Answers1

1
class SimpleXMLExtended extends SimpleXMLElement {
  public function addCData($cdata_text) {
    $node = dom_import_simplexml($this); 
    $no   = $node->ownerDocument; 
    $node->appendChild($no->createCDATASection($cdata_text)); 
  } 
}

$xml = new SimpleXMLExtended('<items id="datasource"/>');
$newChild = $xml->addChild('item');
$newChild->addCData('t&st');
$newChild->addAttribute('id', 'key');
var_dump($xml->asXml());

So, in your case, I believe you just have to replace your code to this:

class SimpleXMLExtended extends SimpleXMLElement {
  public function addCData($cdata_text) {
    $node = dom_import_simplexml($this); 
    $no   = $node->ownerDocument; 
    $node->appendChild($no->createCDATASection($cdata_text)); 
  } 
}

function array2xml($array, $xml = false){
    if($xml === false){
        $xml = new SimpleXMLExtended('<items id="datasource"/>');
    }
    foreach($array as $key => $value){
        if(is_array($value)){
            array2xml($value, $newChild = $xml->addChild('item'));
            $newChild->addAttribute('id', $key);
        }
        else {
            $newChild = $xml->addChild('item');
            $newChild->addCData($value);
            $newChild->addAttribute('id', $key);
        }
    }
    return $xml->asXML();
}

Got the answer from here:

How to write CDATA using SimpleXmlElement?

Felippe Duarte
  • 14,901
  • 2
  • 25
  • 29
  • A CDATA is a workaround, but you can ovverride `addChild()` and add the second argument as a text node to fix just the escaping problem. https://stackoverflow.com/questions/37160976/special-character-in-xml-using-php/37162005#37162005 – ThW Jan 18 '18 at 13:31