I am afraid this is inherentley flawed( not really your fault as a lot of a lot of guides are pretty clueless when it comes to this).
Concatenation/straight output is far less than ideal for XML, it is very strict in nature. Much more so than your database( that does not care) and all decent XML processors will halt at the first invalid char. Any example showing anything going straight from the database into an XML string or echoed is wrong, shows very little understaning of character encodings and what happens when they are not dealt with properly. XML is a data exchange format and the reason it is by nature strict is to stop contamination from a source that has not been dealt with properly. Junk data spreads and is very hard to get rid of when it contaminates. Cleaning up large databases is not fun.
I wrote this example for you, one way uses the DOM( which takes care of a lot of it for you as it will escape characters when it can ). Eg the &< i have added to the test rows. It looks bulky but can be refactored over time so he bulk is reused every time a feed is done.
The second way uses direct echo and will fail if $useBuilder = false;
Firefox will halt with
XML Parsing Error: not well-formed
Location: rpc_test.php
Line Number 1, Column 130:<?xml version="1.0" encoding="ISO-8859-1" ?><rss version="2.0"><feed><channel><title>Title</title><link>Link</link><description>&<description1</description><item><title>ItemTitle1</title>
-----------------------------------------------------------------------------------------------------------------------------------------------------------^ ( had to add extra dashes ad firefox is doing something with fonts )
<?php
header('Content-Type: text/xml');
function GenerateTestRow( $title
, $link
, $description
, $item_title
, $item_link
, $item_description
, $published_date ){
return array( 'title' => $title
, 'link' => $link
, 'description' => $description
, 'item_title' => $item_title
, 'item_link' => $item_link
, 'item_description' => $item_description
, 'author' => $item_title . ' author'
, 'published_date' => $published_date
);
}
class RssXmlBuilder{
/**
* @var DomDocument
*/
private $DomDocument;
/**
* @var DOMElement
*/
private $RootElement;
/**
* @var DOMElement
*/
private $CurrentChannelElement;
public function __construct(){
$this->DomDocument = new DOMDocument('1.0', 'iso-8859-1');
$this->RootElement = $this->createElement('rss');
$this->RootElement->setAttribute( 'version', '2.0' );
$this->DomDocument->appendChild( $this->RootElement );
}
public function addChannelElement( $title, $link, $description ){
$this->CurrentChannelElement = $this->createChannelElement( $title, $link, $description );
$this->RootElement->appendChild( $this->CurrentChannelElement );
}
public function addItemToCurrentChannelElement( $title, $link, $description, $author, $publishedDate ){
$itemElement = $this->createItemElement( $title, $link, $description, $author, $publishedDate );
$this->CurrentChannelElement->appendChild( $itemElement );
}
private function createItemElement( $title, $link, $description, $author, $publishedDate ){
$itemElement = $this->createElement( 'item' );
$this->appendElementToParent( $itemElement, 'item_title' , $title);
$this->appendElementToParent( $itemElement, 'item_link' , $link);
$this->appendElementToParent( $itemElement, 'item_description' , $description);
$this->appendElementToParent( $itemElement, 'author' , $author);
$this->appendElementToParent( $itemElement, 'published_date' , $publishedDate);
return $itemElement;
}
private function appendElementToParent( DOMElement $parentElement, $name, $value ){
$parentElement->appendChild( $this->createElement( $name, $value ) );
}
private function createChannelElement( $title, $link, $description){
$channelElement = $this->createElement('channel');
$this->appendElementToParent( $channelElement, 'title' , $title );
$this->appendElementToParent( $channelElement, 'link' , $link );
$this->appendElementToParent( $channelElement, 'description' , $description );
return $channelElement;
}
private function createElement( $elementName, $elementValue = null ){
$trans = get_html_translation_table(HTML_ENTITIES);
$encoded = strtr($elementValue, $trans);
return $this->DomDocument->createElement($elementName, $encoded );
}
public function build(){
return $this->DomDocument->saveXML( );
}
}
$useBuilder = true;
$data = array();
$data[] = GenerateTestRow( 'Title','Link', '&<description1','ItemTitle1', 'ItemLink1', 'Description1', 'PublishedDate1' );
$data[] = GenerateTestRow( 'Title','Link', 'description2' ,'ItemTitle2', 'ItemLink2', '&', 'PublishedDate2' );
if( $useBuilder ){
$RssBuilder = new RssXmlBuilder();
$RssBuilder->addChannelElement( $data[0]['title']
, $data[0]['link']
, $data[0]['description']);
foreach( $data as $row )
{
$RssBuilder->addItemToCurrentChannelElement( $row['item_title']
, $row['item_link']
, $row['item_description']
, $row['author']
, $row['published_date']);
}
echo $RssBuilder->build();
return;
}
echo '<?xml version="1.0" encoding="ISO-8859-1" ?>';
echo '<rss version="2.0">';
echo'<channel>';
echo'<title>' . $data[0]['title'] .'</title>';
echo'<link>' . $data[0]['link'] .'</link>';
echo'<description>'. $data[0]['description'] .'</description>';
foreach( $data as $row )
{
echo'<item>';
echo'<title>' . $row['item_title'] . '</title>';
echo'<link>' . $row['item_link'] . '</link>';
echo'<description>'. $row['item_description'] . '</description>';
echo'<author>' . $row['author'] . '</author>';
echo'<pubDate>' . $row['published_date'] . '</pubDate>';
echo'</item>';
}
echo'</channel>';
echo '</rss>';
?>
The reason I bring this up is I have had to deal with a lot of problems with bad feeds due to bad guides in doing this( there was one on this site a few years ago ), they do far more damage than good. It is even better if the database is converted to UTF-8 as Latin-1 has issues as things like the Euro symbol are not accepted( we work on Oracle databases which are stuck on Latin 1( Oracle, unlike MySQL can be a pig when it comes to UTF-8 and the DBAs just kick up a fuss), the business I work for has real problems waiting as we are going into foreign markets like Russia as cyrillic is definately not supported ). Put it this way, character encodings if not handled right will make you hate them. The browser does a lot of magic stuff when it comes to HTML, not XML.
If you learn how to deal with them properly you will be far ahead of most people who will just hack utf8_encode, string replaces etc all over the place. Lazyness will make someone pay. Find an error, hack a fix everywhere. Switch encodings possibly do a whole bunch of other hacks. Sometimes people entify stuff going into the database only half the time creating more problems. Using a built in library will cause the halt on your end if not happy and will log an error.
Character encodings have cause more people I know problems than anything else as the operating system/editors/browsers all play a very clever guessing game and all sorts of stuff is happening that most people are not aware of and good XML parsers do none of that. It gets fugly.
If this is for professional use, it will also stop people getting chased when it goes down which it will do.
Any help just ask because this is a topic that must be dealt with properly. I am using 5.1 by the way as I haven't upgraded my home machine for a while. It is a very big topic and I have barely touched it, very very murky world.
I am going blind looking at this now ð