rhymix/classes/xml/XmlParser.class.php
Kijin Sung dfa1e93c79 Remove unnecessary header and footer from class files
- 아래에 이미 author 언급이 있으므로 중복되는 저작권 표기는 제거
- 클래스 하단에 불필요한 end of file 표시 제거 (파일 하나에 클래스 하나씩이므로
  파일이 중간에 끊겼다면 클래스가 닫히지 않아 쉽게 알 수 있음)
2023-01-30 23:52:23 +09:00

246 lines
5.7 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Xml_Node_ class
* Element node or attribute node.
* @author NAVER (developers@xpressengine.com)
* @package /classes/xml
* @version 0.1
*/
#[AllowDynamicProperties]
class Xml_Node_
{
/** In PHP5 this will silence E_STRICT warnings
* for undeclared properties.
* No effect in PHP4
*/
function __get($name)
{
return NULL;
}
}
/**
* XmlParser class
* Class parsing a given xmlrpc request and creating a data object
* @remarks <pre>{
* This class may drops unsupported xml lanuage attributes when multiple language attributes are given.
* For example, if 'xml:lang='ko, en, ch, jp..' is given in a xml file, only ko will be left ignoring all other language
* attributes when kor is only supported language. It seems to work fine now but we did not scrutinze any potential side effects,
* }</pre>
*
* @author NAVER (developers@xpressengine.com)
* @package /classes/xml
* @version 0.1
*/
class XeXmlParser
{
/**
* Xml parser
* @var resource
*/
var $oParser = NULL;
/**
* Input xml
* @var string
*/
var $input = NULL;
/**
* Output object in array
* @var array
*/
var $output = array();
/**
* The default language type
* @var string
*/
var $lang = "en";
/**
* Load a xml file specified by a filename and parse it to Return the resultant data object
* @param string $filename a file path of file
* @return object|null Returns a data object containing data extracted from a xml file or NULL if a specified file does not exist
*/
function loadXmlFile($filename)
{
if(!file_exists($filename))
{
return;
}
$buff = FileHandler::readFile($filename);
$oXmlParser = new self();
return $oXmlParser->parse($buff);
}
/**
* Parse xml data to extract values from it and construct data object
* @param string $input a data buffer containing xml data
* @param mixed $arg1 ???
* @param mixed $arg2 ???
* @return object|null Returns a resultant data object or NULL in case of error
*/
function parse($input = '', $arg1 = NULL, $arg2 = NULL)
{
// Save the compile starting time for debugging
$start = microtime(true);
$this->lang = Context::getLangType();
$this->input = $input ? $input : $GLOBALS['HTTP_RAW_POST_DATA'];
$this->input = str_replace(array('', ''), array('', ''), $this->input);
// extracts a supported language
preg_match_all("/xml:lang=\"([^\"].+)\"/i", $this->input, $matches);
// extracts the supported lanuage when xml:lang is used
if(count($matches[1]) && $supported_lang = array_unique($matches[1]))
{
$tmpLangList = array_flip($supported_lang);
// if lang of the first log-in user doesn't exist, apply en by default if exists. Otherwise apply the first lang.
if(!isset($tmpLangList[$this->lang]))
{
if(isset($tmpLangList['en']))
{
$this->lang = 'en';
}
else
{
$this->lang = array_shift($supported_lang);
}
}
// uncheck the language if no specific language is set.
}
else
{
$this->lang = '';
}
$this->oParser = xml_parser_create('UTF-8');
xml_set_object($this->oParser, $this);
xml_set_element_handler($this->oParser, "_tagOpen", "_tagClosed");
xml_set_character_data_handler($this->oParser, "_tagBody");
xml_parse($this->oParser, $this->input);
xml_parser_free($this->oParser);
if(!count($this->output))
{
return;
}
$output = array_shift($this->output);
// Save compile starting time for debugging
if (!isset($GLOBALS['__xmlparse_elapsed__']))
{
$GLOBALS['__xmlparse_elapsed__'] = 0;
}
$GLOBALS['__xmlparse_elapsed__'] += microtime(true) - $start;
return $output;
}
/**
* Start element handler.
* @param resource $parse an instance of parser
* @param string $node_name a name of node
* @param array $attrs attributes to be set
* @return array
*/
function _tagOpen($parser, $node_name, $attrs)
{
$obj = new Xml_Node_();
$obj->node_name = strtolower($node_name);
$obj->attrs = $this->_arrToAttrsObj($attrs);
$this->output[] = $obj;
}
/**
* Character data handler
* Variable in the last element of this->output
* @param resource $parse an instance of parser
* @param string $body a data to be added
* @return void
*/
function _tagBody($parser, $body)
{
//if(!trim($body)) return;
$this->output[count($this->output) - 1]->body .= $body;
}
/**
* End element handler
* @param resource $parse an instance of parser
* @param string $node_name name of xml node
* @return void
*/
function _tagClosed($parser, $node_name)
{
$node_name = strtolower($node_name);
$cur_obj = array_pop($this->output);
$parent_obj = &$this->output[count($this->output) - 1];
if($this->lang && $cur_obj->attrs->{'xml:lang'} && $cur_obj->attrs->{'xml:lang'} != $this->lang)
{
return;
}
if($this->lang && ($parent_obj->{$node_name}->attrs->{'xml:lang'} ?? null) && $parent_obj->{$node_name}->attrs->{'xml:lang'} != $this->lang)
{
return;
}
if(isset($parent_obj->{$node_name}))
{
$tmp_obj = $parent_obj->{$node_name};
if(is_array($tmp_obj))
{
$parent_obj->{$node_name}[] = $cur_obj;
}
else
{
$parent_obj->{$node_name} = array($tmp_obj, $cur_obj);
}
}
else
{
if(!is_object($parent_obj))
{
$parent_obj = (object) $parent_obj;
}
$parent_obj->{$node_name} = $cur_obj;
}
}
/**
* Method to transfer values in an array to a data object
* @param array $arr data array
* @return Xml_Node_ object
*/
function _arrToAttrsObj($arr)
{
$output = new Xml_Node_();
foreach($arr as $key => $val)
{
$key = strtolower($key);
$output->{$key} = $val;
}
return $output;
}
}
/**
* Alias to XmlParser for backward compatibility.
*/
if (!class_exists('XmlParser', false))
{
class_alias('XeXmlParser', 'XmlParser');
}