From OrganicDesign
<?php
# Extension:XmlOutput
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
# - Author: [http://www.organicdesign.co.nz/nad User:Nad]
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('XMLOUTPUT_VERSION','1.0.0, 2007-09-10');
$wgXmlOutputTitle = 'XML'; # Name of the special page used to return articles as raw XML
$wgExtensionFunctions[] = 'wfSetupXmlOutput';
$wgExtensionCredits['specialpage'][] = array(
'name' => 'Special:XmlOutput',
'author' => '[http://www.organicdesign.co.nz/nad User:Nad]',
'description' => 'Allows articles containing XML to be returned as raw XML with associated XSLT applied if required.',
'url' => 'http://www.mediawiki.org/wiki/Extension:XmlOutput',
'version' => XMLOUTPUT_VERSION
);
# Add an XML action if the content is XML
$wgHooks['ParserBeforeStrip'][] = 'wfXmlOutputAddActionTest';
function wfXmlOutputAddActionTest(&$parser,&$text) {
global $wgHooks;
if (preg_match('/<\\?xml/',$text)) $wgHooks['SkinTemplateTabs'][] = 'wfXmlOutputAddAction';
return true;
}
function wfXmlOutputAddAction(&$skin,&$actions) {
global $wgTitle,$wgXmlOutputTitle;
if (is_object($wgTitle)) {
$url = Title::makeTitle(NS_SPECIAL,$wgXmlOutputTitle);
$url = $url->getLocalUrl().'/'.$wgTitle->getPrefixedText();
$actions[$wgXmlOutputTitle] = array('text' => 'xml', 'class' => false, 'href' => $url);
}
return true;
}
# Define a new class based on the SpecialPage class
require_once "$IP/includes/SpecialPage.php";
class SpecialXmlOutput extends SpecialPage {
var $xslt = array();
# Constructor
function SpecialXmlOutput() {
global $wgXmlOutputTitle;
SpecialPage::SpecialPage($wgXmlOutputTitle,'',false,false,false,false);
}
# Override SpecialPage::execute()
# - $param is from the URL, eg Special:XmlOutput/param
function execute($param) {
global $wgParser,$wgUser;
$wgParser->disableCache();
$this->setHeaders();
# Get article content and expand any templates
$title = Title::newFromText($param);
$xml = new Article($title);
$xml = preg_replace('/\{\{.+?\}\}/s','',$xml->getContent());
# Extract all the XSLT's referred to in the XML and remove/record them
$xml = preg_replace_callback(
'/<\\?xml-stylesheet\\s+type="text\\/xsl"\\s+href="(.+?)"\\?>/s',
array($this,'extractXSLT'),
$xml
);
# Convert the XML to a DOM object
$doc = new DOMDocument();
$doc->loadXML($xml);
# Apply extracted XSLT's to the DOM object
foreach ($this->xslt as $title) {
$title = Title::newFromText($title);
if ($title->exists()) {
$xslt = new Article($title);
$xslt = preg_replace('/\{\{.+?\}\}/s','',$xslt->getContent());
$xsl = new DOMDocument();
$xsl->loadXML($xslt);
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
$doc = $proc->transformToDoc($doc);
}
}
# Return to the client as raw XML text
$xml = $doc->saveXML();
while(@ob_end_clean());
header('Content-Type: application/xml');
if (in_array('Content-Encoding: gzip',headers_list())) $xml = gzencode($xml);
echo($xml);
die;
}
# Extract XSLT's from the XML and record/remove them
function extractXSLT($match) {
$this->xslt[] = $match[1];
return '';
}
}
# Called from $wgExtensionFunctions array when initialising extensions
function wfSetupXmlOutput() {
global $wgLanguageCode,$wgMessageCache,$wgXmlOutputTitle;
# Add the messages used by the specialpage
if ($wgLanguageCode == 'en') {
$wgMessageCache->addMessages(array('xmloutput' => $wgXmlOutputTitle));
}
# Add the specialpage to the environment
SpecialPage::addPage(new SpecialXmlOutput());
}