This code has been a major part of my XML-RPC library from the beginning. It takes a PHP data structure and serializes it into XML (simple).
For example, the following PHP code:
<?php
$foo = array(
'foo'=> array(
'bar'=>array('blah','<i>blah</i>'),
),
'foo attr'=>array('att1'=>"this isn't the best song in the world", 'att2'=>'this is only a "tribute"')
);
echo XML_serialize($foo);
?>
Generates the following XML (reformatted slightly):
<?xml version="1.0" ?>
<foo att1="this isn't the best song in the world"
att2="this is only a "tribute"">
<bar>blah</bar>
<bar><i>blah</i></bar>
</foo>
I've recently revised the code as part of getting rid of my CMS. I was generating my RSS feed for my weblog with a template, when, since it's data, it should really be generated by a library from a data structure. The result was simpler, shorter, and more maintainable than what I had before.
Here's the code:
Update (Jul 24, '04): Code removed. An updated version is available at http://keithdevens.com/software/phpxml
Note that the data you send to XML_serialize had better already be in UTF-8 or you'll be generating invalid XML, and it's your responsibility to not try to generate invalid XML tag names. The $data passed to XML_serialize must be an array containing one element, which is the top-level element of the XML document. If you want to do namespaces, just do it manually by adding namespace attributes to the top-level element, and prefix your tag names with the appropriate namespace name.
For example, here's essentially how I go about generating my RSS (code altered slightly):
<?php
function weblog_rss(){
$xml = array();
$xml['rss attr'] = array('version'=>'2.0');
$xml['rss']['channel'] = array(
'title'=>"Keith's Weblog"
'link'=>'http://keithdevens.com/weblog'
'description'=>'The personal weblog of Keith Devens',
'language'=>'en-us',
'image'=>array(
'link'=>'http://keithdevens.com/weblog',
'title'=>'Keith Devens .com',
'url'=>'http://keithdevens.com/images/kbd.gif'
)
);
$rss_items = array();
$entries = &weblog_getEntries();
require_once('markup_library.php');
require_once('xml_library.php');
foreach($entries as $e){
$timestamp = convert_mysql_datetime($e['creation_datetime']);
$url = 'http://keithdevens.com'.weblog_getUrl('entry', $e);
$rss_items[] = array(
'title'=>utf8_encode($e['title']),
'link'=>$url,
'guid'=>'http://www.keithdevens.com/weblog/'.$e['id'],
'guid attr'=>array('isPermaLink'=>'false'),
'description'=>utf8_encode(markup($e['text'], array("enable_abs_links"=>true))),
'pubDate'=>date('r',$timestamp),
'comments'=>$url.'#comments'
);
}
$xml['rss']['channel']['item'] = $rss_items;
header("Content-type: text/xml");
echo xml_serialize($xml);
}
?>
All of this code should be translatable to pretty much any other scripting language. The only issue is that PHP maintains the order of keys within an associative array while most other languages don't. So, if that's important to you, the code won't be applicable in other languages as it is in PHP. However, since this is meant for data-oriented XML anyway, the order of keyed elements probably won't matter to you.
I don't look at XML as some change-the-world semantic-web savior. It's just a relatively pain-in-the-butt-to-use file format. I may release this code as well as my parser code as an open-source library separate from my XML-RPC library, though to some degree both will be obsoleted by SimpleXML in PHP 5. Anyway, consider this code public domain.
Update (May 28): I've updated this code and released it along with its corresponding XML_unserialize function as an open source library, available at http://keithdevens.com/software/phpxml.
Dude, you gotta get the Tribute lyrics right.