3

In the effiliation pluggin for prestashop, i've found this code:

$values->addChild('marque', '<![CDATA['.$product['manufacturer_name'].']]>');

when in $product['manufacturer_name'], i have Cyril & Nathalie Daniel, the output is <![CDATA[Cyril, as opposed to the normal case: <![CDATA[Foo Bar]]>

Can the 2nd argument of SimpleXMLElement::addChild can contain & ? Do i have to use some htmlentities on the manufacturer name ?

hakre
  • 193,403
  • 52
  • 435
  • 836
Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236
  • 2
    See http://stackoverflow.com/questions/6260224/how-to-write-cdata-using-simplexmlelement – salathe Aug 22 '11 at 11:02
  • @salathe This is indeed the right thing to do. But i am not supposed to modify a paid module, so i'd prever a quick dirty fix. – Benjamin Crouzier Aug 22 '11 at 12:45
  • Surely a quick, dirty fix is still modifying the code. Either way, you know how this should be done. – salathe Aug 22 '11 at 12:51
  • if you first only ``$foo = $xml->addChild('foo')`` and set the value after adding the child ``$foo[0] = 'value & txt'`` then simpleXML does escape the ampersand ¯\\_(ツ)_/¯ – GDmac Dec 07 '22 at 10:01

3 Answers3

9

My problem is described here:

Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&".


The solution proposed php.net (htmlentities or htmlcspecialchars) is not a good one, so i came up with what salathe suggested:

<?php
class SimpleXMLExtended extends SimpleXMLElement // http://coffeerings.posterous.com/php-simplexml-and-cdata
{
  public function addCData($cdata_text)
  {
    $node= dom_import_simplexml($this); 
    $no = $node->ownerDocument; 
    $node->appendChild($no->createCDATASection($cdata_text)); 
  } 
}

and instead of

$values->addChild('marque', '<![CDATA['.$product['manufacturer_name'].']]>');

use :

$values->addChild('marque')->addCData($product['manufacturer_name']);

Output is now <![CDATA[Cyril & Nathalie Daniel]]>

Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236
1

Another possibility is to remember that SimpleXMLElement is doing a double-decode -- instead of mapping & to &amp; (single-decode), it seems to work to just map & to &amp;amp; to start with. Your child ends up with &amp; in the XML like it should.

Mark Leighton Fisher
  • 5,609
  • 2
  • 18
  • 29
-1

You may need to encode your manufacturer name with htmlentities by the looks of it. This should be ok within the CDATA tags I'd have thought though.

Try this:

$values->addChild('marque', '<![CDATA['.htmlentities($product['manufacturer_name']).']]>');