68

Here is my code:

<?php
// 27/01/2016 Edit:
$result = mysql_query("A Long mysql query");
$rss = new SimpleXMLElement('<rss version="2.0" />');
$products = $rss->addChild('products');
///
while($row = mysql_fetch_array($result)){
$product = $products->addChild('category');
$product->addChild('product_id',"$row[product_id]");
$product->addChild('cat_id',"$row[cat_id]");
$product->addChild('cat_name',"$row[cat_name]");
$product->addchild('product_code',"$row[product_code]");
$product->addchild('product_name',"$row[product_name]");
$product->addChild('description','$row[description]');
$product->addchild('rating',"$row[rating]");
$product->addchild('image_url','$row[imag_url]');
$product->addchild('price',"$row[price]");
$product->addchild('discount',"$row[discount]");
$product->addchild('stock_status',"$row[stock_status]");
$product->addchild('stock_quantity',"$row[stock_quantity]");
$product->addchild('weight',"$row[weight]");
$product->addchild('length',"$row[length]");
$product->addchild('width',"$row[width]");
$product->addchild('height',"$row[height]");
$product->addchild('colour',"$row[colour]");
$product->addchild('size',"$row[size]");
$product->addchild('material',"$row[material]");
$product->addchild('pattern',"$row[pattern]");
};

Header('Content-type: text/xml');
print($rss->asXML());
?>

and here is the error:

Warning: SimpleXMLElement::addChild() [simplexmlelement.addchild]: unterminated entity reference _Coke.jpg in C:\wamp\www\rabwah\core.php on line 40

The error is in the line with '$row[imag_url]'.

Blackbam
  • 17,496
  • 26
  • 97
  • 150
mega6382
  • 9,211
  • 17
  • 48
  • 69
  • 4
    *Obligatory:* The `mysql_*` functions will be [deprecated in PHP 5.5](http://php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated). It is not recommended for writing new code as it will be removed in the future. Instead, either the [MySQLi](http://php.net/manual/en/book.mysqli.php) or [PDO](http://php.net/manual/en/book.pdo.php) and [be a better PHP Developer](http://jason.pureconcepts.net/2012/08/better-php-developer/). – Jason McCreary Jun 10 '13 at 15:10
  • `'$row[imag_url]'` should be `"$row[imag_url]"`. Change single quotes to double quotes. Also you forgot the `/>` in `$rss->addChild(' – gen_Eric Jun 10 '13 at 15:10
  • Don't know if its relevant here or not but `addChild` is the method not `addchild` also this line `$products = $rss->addChild(' – Orangepill Jun 10 '13 at 15:14
  • 3
    @RocketHazmat and @jason McCreary and @Orangepill the problem with ` $rss->addChild('addChild('products'); but the issue is still there – mega6382 Jun 10 '13 at 15:29

7 Answers7

158

This correctly encodes the & < > and "" ''

$parent->addChild($name, htmlspecialchars($value));
mega6382
  • 9,211
  • 17
  • 48
  • 69
Joel Davey
  • 2,363
  • 1
  • 21
  • 20
46

SimpleXMLElement is actually a system resource which behaves like an object. Which makes working with loops tricky. So when trying to add new child elements instead of this:

$product->addchild('element', $value);

do this:

$product->element = $value;

or you can use htmlspecialchars(), to escape html characters.

Note:

mysql_* is deprecated as of and removed as of . So instead use mysqli_* or PDO.
Why shouldn't I use mysql_* functions in PHP?

mega6382
  • 9,211
  • 17
  • 48
  • 69
9

My solution to this is specifically creating a text node, which makes sure absolutely everything is escaped properly:

$cell = $dom->createElement('td');
$cell->appendChild($dom->createTextNode($value));
mega6382
  • 9,211
  • 17
  • 48
  • 69
Kavi Siegel
  • 2,964
  • 2
  • 24
  • 33
3

If you use the new created node you can set the value by accessing {0} property. This should escape any special characters.

$childNode = $parent->addChild($name);
$childNode{0} = $value;
1

Sorry for reviving an old question, but there is another solution to this.. Assuming the following code causes the "unterminated entity reference" error:

$xml->addChild($key,$value); 

@Joel-Davey's solution works very well:

$xml->addChild($key,htmlspecialchars($value)); 

But you can also do the following if, for some reason, you don't want to use the above htmlspecialchars function (basically, you split the one step into two steps):

$xml->addChild($key); 
$xml->$key=$value; 

i have no idea which one will execute faster; i doubt it'd make much of a difference, but, this works, and i thought it should be mentioned

PS: i know it works because i'm using it on a personal project

mega6382
  • 9,211
  • 17
  • 48
  • 69
Peter
  • 1,236
  • 10
  • 10
  • Absolutely! in my (very basic) tests the second uses a **super-tiny** bit more memory than the first, but seems to execute a **super-tiny** bit faster – Peter Sep 12 '17 at 07:52
  • @mega6382: i added a link to a personal project, you can see it in action 'in the wild' – Peter Sep 12 '17 at 08:01
0

Try by changing -

$product->addchild('image_url','$row[imag_url]');

To

$product->addchild('image_url',"$row[\"imag_url\"]");

OR

$product->addchild('image_url',$row['imag_url']);

EDIT wrap quotes too round image_url, courtesy Barrmar

Community
  • 1
  • 1
swapnesh
  • 26,318
  • 22
  • 94
  • 126
0

The correct form is:

$product->addchild('image_url',htmlspecialchars($row['imag_url']));
mega6382
  • 9,211
  • 17
  • 48
  • 69
Eolia
  • 227
  • 2
  • 4