diff options
Diffstat (limited to 'includes/api/ApiFormatXml.php')
-rw-r--r-- | includes/api/ApiFormatXml.php | 117 |
1 files changed, 70 insertions, 47 deletions
diff --git a/includes/api/ApiFormatXml.php b/includes/api/ApiFormatXml.php index 35b412c9..a3758a49 100644 --- a/includes/api/ApiFormatXml.php +++ b/includes/api/ApiFormatXml.php @@ -23,9 +23,9 @@ * http://www.gnu.org/copyleft/gpl.html */ -if (!defined('MEDIAWIKI')) { +if ( !defined( 'MEDIAWIKI' ) ) { // Eclipse helper - will be ignored in production - require_once ('ApiFormatBase.php'); + require_once ( 'ApiFormatBase.php' ); } /** @@ -35,9 +35,10 @@ class ApiFormatXml extends ApiFormatBase { private $mRootElemName = 'api'; private $mDoubleQuote = false; + private $mXslt = null; - public function __construct($main, $format) { - parent :: __construct($main, $format); + public function __construct( $main, $format ) { + parent :: __construct( $main, $format ); } public function getMimeType() { @@ -48,16 +49,22 @@ class ApiFormatXml extends ApiFormatBase { return true; } - public function setRootElement($rootElemName) { + public function setRootElement( $rootElemName ) { $this->mRootElemName = $rootElemName; } public function execute() { $params = $this->extractRequestParams(); $this->mDoubleQuote = $params['xmldoublequote']; - - $this->printText('<?xml version="1.0"?>'); - $this->recXmlPrint($this->mRootElemName, $this->getResultData(), $this->getIsHtml() ? -2 : null); + $this->mXslt = $params['xslt']; + + $this->printText( '<?xml version="1.0"?>' ); + if ( !is_null( $this->mXslt ) ) + $this->addXslt(); + $this->printText( self::recXmlPrint( $this->mRootElemName, + $this->getResultData(), + $this->getIsHtml() ? - 2 : null, + $this->mDoubleQuote ) ); } /** @@ -73,22 +80,23 @@ class ApiFormatXml extends ApiFormatBase { * If neither key is found, all keys become element names, and values become element content. * The method is recursive, so the same rules apply to any sub-arrays. */ - function recXmlPrint($elemName, $elemValue, $indent) { - if (!is_null($indent)) { + public static function recXmlPrint( $elemName, $elemValue, $indent, $doublequote = false ) { + $retval = ''; + if ( !is_null( $indent ) ) { $indent += 2; - $indstr = "\n" . str_repeat(" ", $indent); + $indstr = "\n" . str_repeat( " ", $indent ); } else { $indstr = ''; } - $elemName = str_replace(' ', '_', $elemName); + $elemName = str_replace( ' ', '_', $elemName ); - switch (gettype($elemValue)) { + switch ( gettype( $elemValue ) ) { case 'array' : - if (isset ($elemValue['*'])) { + if ( isset ( $elemValue['*'] ) ) { $subElemContent = $elemValue['*']; - if ($this->mDoubleQuote) - $subElemContent = $this->doubleQuote($subElemContent); - unset ($elemValue['*']); + if ( $doublequote ) + $subElemContent = Sanitizer::encodeAttribute( $subElemContent ); + unset ( $elemValue['*'] ); // Add xml:space="preserve" to the // element so XML parsers will leave @@ -98,80 +106,95 @@ class ApiFormatXml extends ApiFormatBase { $subElemContent = null; } - if (isset ($elemValue['_element'])) { + if ( isset ( $elemValue['_element'] ) ) { $subElemIndName = $elemValue['_element']; - unset ($elemValue['_element']); + unset ( $elemValue['_element'] ); } else { $subElemIndName = null; } $indElements = array (); $subElements = array (); - foreach ($elemValue as $subElemId => & $subElemValue) { - if (is_string($subElemValue) && $this->mDoubleQuote) - $subElemValue = $this->doubleQuote($subElemValue); + foreach ( $elemValue as $subElemId => & $subElemValue ) { + if ( is_string( $subElemValue ) && $doublequote ) + $subElemValue = Sanitizer::encodeAttribute( $subElemValue ); - if (gettype($subElemId) === 'integer') { + if ( gettype( $subElemId ) === 'integer' ) { $indElements[] = $subElemValue; - unset ($elemValue[$subElemId]); - } elseif (is_array($subElemValue)) { + unset ( $elemValue[$subElemId] ); + } elseif ( is_array( $subElemValue ) ) { $subElements[$subElemId] = $subElemValue; - unset ($elemValue[$subElemId]); + unset ( $elemValue[$subElemId] ); } } - if (is_null($subElemIndName) && count($indElements)) - ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName()."); + if ( is_null( $subElemIndName ) && count( $indElements ) ) + ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName()." ); - if (count($subElements) && count($indElements) && !is_null($subElemContent)) - ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has content and subelements"); + if ( count( $subElements ) && count( $indElements ) && !is_null( $subElemContent ) ) + ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has content and subelements" ); - if (!is_null($subElemContent)) { - $this->printText($indstr . Xml::element($elemName, $elemValue, $subElemContent)); - } elseif (!count($indElements) && !count($subElements)) { - $this->printText($indstr . Xml::element($elemName, $elemValue)); + if ( !is_null( $subElemContent ) ) { + $retval .= $indstr . Xml::element( $elemName, $elemValue, $subElemContent ); + } elseif ( !count( $indElements ) && !count( $subElements ) ) { + $retval .= $indstr . Xml::element( $elemName, $elemValue ); } else { - $this->printText($indstr . Xml::element($elemName, $elemValue, null)); + $retval .= $indstr . Xml::element( $elemName, $elemValue, null ); - foreach ($subElements as $subElemId => & $subElemValue) - $this->recXmlPrint($subElemId, $subElemValue, $indent); + foreach ( $subElements as $subElemId => & $subElemValue ) + $retval .= self::recXmlPrint( $subElemId, $subElemValue, $indent ); - foreach ($indElements as $subElemId => & $subElemValue) - $this->recXmlPrint($subElemIndName, $subElemValue, $indent); + foreach ( $indElements as $subElemId => & $subElemValue ) + $retval .= self::recXmlPrint( $subElemIndName, $subElemValue, $indent ); - $this->printText($indstr . Xml::closeElement($elemName)); + $retval .= $indstr . Xml::closeElement( $elemName ); } break; case 'object' : // ignore break; default : - $this->printText($indstr . Xml::element($elemName, null, $elemValue)); + $retval .= $indstr . Xml::element( $elemName, null, $elemValue ); break; } + return $retval; } - private function doubleQuote( $text ) { - return Sanitizer::encodeAttribute( $text ); + function addXslt() { + $nt = Title::newFromText( $this->mXslt ); + if ( is_null( $nt ) || !$nt->exists() ) { + $this->setWarning( 'Invalid or non-existent stylesheet specified' ); + return; + } + if ( $nt->getNamespace() != NS_MEDIAWIKI ) { + $this->setWarning( 'Stylesheet should be in the MediaWiki namespace.' ); + return; + } + if ( substr( $nt->getText(), - 4 ) !== '.xsl' ) { + $this->setWarning( 'Stylesheet should have .xsl extension.' ); + return; + } + $this->printText( '<?xml-stylesheet href="' . $nt->escapeLocalURL( 'action=raw' ) . '" type="text/xsl" ?>' ); } - + public function getAllowedParams() { return array ( - 'xmldoublequote' => false + 'xmldoublequote' => false, + 'xslt' => null, ); } public function getParamDescription() { return array ( 'xmldoublequote' => 'If specified, double quotes all attributes and content.', + 'xslt' => 'If specified, adds <xslt> as stylesheet', ); } - public function getDescription() { return 'Output data in XML format' . parent :: getDescription(); } public function getVersion() { - return __CLASS__ . ': $Id: ApiFormatXml.php 50217 2009-05-05 13:12:16Z tstarling $'; + return __CLASS__ . ': $Id: ApiFormatXml.php 62402 2010-02-13 00:09:05Z reedy $'; } } |