00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if ( !defined( 'MEDIAWIKI' ) ) {
00027
00028 require_once ( 'ApiFormatBase.php' );
00029 }
00030
00034 class ApiFormatXml extends ApiFormatBase {
00035
00036 private $mRootElemName = 'api';
00037 private $mDoubleQuote = false;
00038 private $mXslt = null;
00039
00040 public function __construct( $main, $format ) {
00041 parent :: __construct( $main, $format );
00042 }
00043
00044 public function getMimeType() {
00045 return 'text/xml';
00046 }
00047
00048 public function getNeedsRawData() {
00049 return true;
00050 }
00051
00052 public function setRootElement( $rootElemName ) {
00053 $this->mRootElemName = $rootElemName;
00054 }
00055
00056 public function execute() {
00057 $params = $this->extractRequestParams();
00058 $this->mDoubleQuote = $params['xmldoublequote'];
00059 $this->mXslt = $params['xslt'];
00060
00061 $this->printText( '<?xml version="1.0"?>' );
00062 if ( !is_null( $this->mXslt ) )
00063 $this->addXslt();
00064 $this->printText( self::recXmlPrint( $this->mRootElemName,
00065 $this->getResultData(),
00066 $this->getIsHtml() ? - 2 : null,
00067 $this->mDoubleQuote ) );
00068 }
00069
00083 public static function recXmlPrint( $elemName, $elemValue, $indent, $doublequote = false ) {
00084 $retval = '';
00085 if ( !is_null( $indent ) ) {
00086 $indent += 2;
00087 $indstr = "\n" . str_repeat( " ", $indent );
00088 } else {
00089 $indstr = '';
00090 }
00091 $elemName = str_replace( ' ', '_', $elemName );
00092
00093 switch ( gettype( $elemValue ) ) {
00094 case 'array' :
00095 if ( isset ( $elemValue['*'] ) ) {
00096 $subElemContent = $elemValue['*'];
00097 if ( $doublequote )
00098 $subElemContent = Sanitizer::encodeAttribute( $subElemContent );
00099 unset ( $elemValue['*'] );
00100
00101
00102
00103
00104 $elemValue['xml:space'] = 'preserve';
00105 } else {
00106 $subElemContent = null;
00107 }
00108
00109 if ( isset ( $elemValue['_element'] ) ) {
00110 $subElemIndName = $elemValue['_element'];
00111 unset ( $elemValue['_element'] );
00112 } else {
00113 $subElemIndName = null;
00114 }
00115
00116 $indElements = array ();
00117 $subElements = array ();
00118 foreach ( $elemValue as $subElemId => & $subElemValue ) {
00119 if ( is_string( $subElemValue ) && $doublequote )
00120 $subElemValue = Sanitizer::encodeAttribute( $subElemValue );
00121
00122 if ( gettype( $subElemId ) === 'integer' ) {
00123 $indElements[] = $subElemValue;
00124 unset ( $elemValue[$subElemId] );
00125 } elseif ( is_array( $subElemValue ) ) {
00126 $subElements[$subElemId] = $subElemValue;
00127 unset ( $elemValue[$subElemId] );
00128 }
00129 }
00130
00131 if ( is_null( $subElemIndName ) && count( $indElements ) )
00132 ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName()." );
00133
00134 if ( count( $subElements ) && count( $indElements ) && !is_null( $subElemContent ) )
00135 ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has content and subelements" );
00136
00137 if ( !is_null( $subElemContent ) ) {
00138 $retval .= $indstr . Xml::element( $elemName, $elemValue, $subElemContent );
00139 } elseif ( !count( $indElements ) && !count( $subElements ) ) {
00140 $retval .= $indstr . Xml::element( $elemName, $elemValue );
00141 } else {
00142 $retval .= $indstr . Xml::element( $elemName, $elemValue, null );
00143
00144 foreach ( $subElements as $subElemId => & $subElemValue )
00145 $retval .= self::recXmlPrint( $subElemId, $subElemValue, $indent );
00146
00147 foreach ( $indElements as $subElemId => & $subElemValue )
00148 $retval .= self::recXmlPrint( $subElemIndName, $subElemValue, $indent );
00149
00150 $retval .= $indstr . Xml::closeElement( $elemName );
00151 }
00152 break;
00153 case 'object' :
00154
00155 break;
00156 default :
00157 $retval .= $indstr . Xml::element( $elemName, null, $elemValue );
00158 break;
00159 }
00160 return $retval;
00161 }
00162 function addXslt() {
00163 $nt = Title::newFromText( $this->mXslt );
00164 if ( is_null( $nt ) || !$nt->exists() ) {
00165 $this->setWarning( 'Invalid or non-existent stylesheet specified' );
00166 return;
00167 }
00168 if ( $nt->getNamespace() != NS_MEDIAWIKI ) {
00169 $this->setWarning( 'Stylesheet should be in the MediaWiki namespace.' );
00170 return;
00171 }
00172 if ( substr( $nt->getText(), - 4 ) !== '.xsl' ) {
00173 $this->setWarning( 'Stylesheet should have .xsl extension.' );
00174 return;
00175 }
00176 $this->printText( '<?xml-stylesheet href="' . $nt->escapeLocalURL( 'action=raw' ) . '" type="text/xsl" ?>' );
00177 }
00178
00179 public function getAllowedParams() {
00180 return array (
00181 'xmldoublequote' => false,
00182 'xslt' => null,
00183 );
00184 }
00185
00186 public function getParamDescription() {
00187 return array (
00188 'xmldoublequote' => 'If specified, double quotes all attributes and content.',
00189 'xslt' => 'If specified, adds <xslt> as stylesheet',
00190 );
00191 }
00192
00193 public function getDescription() {
00194 return 'Output data in XML format' . parent :: getDescription();
00195 }
00196
00197 public function getVersion() {
00198 return __CLASS__ . ': $Id: ApiFormatXml.php 62402 2010-02-13 00:09:05Z reedy $';
00199 }
00200 }