Page 1 of 1

fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 2:19 pm
by UncleNinja
Simple question and hopefully a simple problem. :)
I'm trying to replace the information inside of an XML node (in an XML file, duh) with PHP5's filesystem functions and SimpleXML. However, PHP has decided to convert all the reserved HTML characters (<, >, &, etc) to their &whatever; equivalents!

Here's my XML file, named pages.xml:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<data type="pages">
	<page value="example" title="The first example">
		<![CDATA[Just an <b>example</b>...]]>
	</page>
	<page value="exampleTwo" title="The second example">
		<![CDATA[The <i>second</i> example!]]>
	</page>
</data>
So I'm using SimpleXML w/ PHP5 to change that XML like this:

Code: Select all

<?php
$xml = simplexml_load_file("pages.xml");
//This is what I'm changing the second node to:
$xml->page[1] = '<![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It\'s truly amazing & inspiring]]>';

$fileHandle = fopen("pages.xml", "w");
fwrite($fileHandle, $xml->asXML());
fclose($fileHandle);
?>
It works until I look at the XML file after I run the PHP script. It looks like this (note second page node):

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<data type="pages">
	<page value="example" title="The first example">
		<![CDATA[Just an <b>example</b>...]]>
	</page>
	<page value="exampleTwo" title="The second example">
		<![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It's truly amazing & inspiring]]>
	</page>
</data>
What the heck? I checked with some echo's and it turns out fwrite is doing that. The second page node should look like this (not the bizarre mangled version above):

Code: Select all

<page value="exampleTwo" title="The second example">
	<![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It's truly amazing & inspiring]]>
</page>
Am I doing something wrong here? :?
Thanks!

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 2:23 pm
by Jade
You just have to decode them: http://www.php.net/manual/en/function.h ... decode.php

Code: Select all

<?php
$xml = simplexml_load_file("pages.xml");
//This is what I'm changing the second node to:
$xml->page[1] = '<![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It\'s truly amazing & inspiring]]>';

$fileHandle = fopen("pages.xml", "w");
fwrite($fileHandle, html_entity_decode($xml->asXML()));
fclose($fileHandle);
?>

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 2:53 pm
by UncleNinja
Thanks! That worked! :D
I wouldn't have expected to have to do that. Thank you! :)

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 2:58 pm
by Jade
I've never tried to use fwrite for something with html in it but my guess is that it does htmlentities by default to prevent system attacks when reading the file.

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 3:45 pm
by AbraCadaver
It's actually a simplexml problem. To do much more with cdata you'll need to use domdocument instead.

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 3:54 pm
by UncleNinja
I just realized that if I really wanted to have an HTML entity in there it would be converted to the actual character. This isn't a bad thing unless the contents of that XML file is actually going into an HTML page later on. Well it is going into an HTML page, so that workaround works, but it breaks the pages.

Even if I use asXML() to save it like this (using example in original post):

Code: Select all

<?php
$xml = simplexml_load_file("pages.xml");
//This is what I'm changing the second node to:
$xml->page[1] = '<![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It\'s truly amazing & inspiring]]>';

$xml->asXML("pages.xml");
?>
It still turns out like:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<data type="pages">
        <page value="example" title="The first example">
                <![CDATA[Just an <b>example</b>...]]>
        </page>
        <page value="exampleTwo" title="The second example">
                <![CDATA[Dude, you should visit <a href="http://example.com">example.com</a>. It's truly amazing & inspiring]]>
        </page>
</data>
Doesn't that defeat the point of having it as a SimpleXML function? If this is is a 'feature' it's worse than magic quotes because I can't figure out how to turn it off! :banghead:

EDIT
Sorry, didn't see AbraCadaver's post. Thanks (no sarcasm intended) - now I know it's not just me. :)

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Tue Jul 06, 2010 7:43 pm
by AbraCadaver
So, as I said you'll probably want to use domdocument. But to keep simplexml, just extend and use a little dom mojo:

Code: Select all

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

$doc = new SimpleXMLExtended($xml);   
$element = $doc->addChild('something');   
$node = $element->addChild('child');   
$node->addCData('some text for cdata section');

Re: fwrite() running htmlentities() on 'string' parameter?

Posted: Wed Jul 07, 2010 2:16 pm
by UncleNinja
Thanks! :)