83 $this->encoding =
'UTF-8';
92 if (substr(
$data, 0, 4) ===
"\x00\x00\xFE\xFF")
97 elseif (substr(
$data, 0, 4) ===
"\xFF\xFE\x00\x00")
102 elseif (substr(
$data, 0, 2) ===
"\xFE\xFF")
107 elseif (substr(
$data, 0, 2) ===
"\xFF\xFE")
112 elseif (substr(
$data, 0, 3) ===
"\xEF\xBB\xBF")
117 if (substr(
$data, 0, 5) ===
'<?xml' && strspn(substr(
$data, 5, 1),
"\x09\x0A\x0D\x20") && ($pos = strpos(
$data,
'?>')) !==
false)
119 $declaration = $this->registry->create(
'XML_Declaration_Parser', array(substr(
$data, 5, $pos - 5)));
120 if ($declaration->parse())
123 $data =
'<?xml version="' . $declaration->version .
'" encoding="' .
$encoding .
'" standalone="' . (($declaration->standalone) ?
'yes' :
'no') .
'"?>' .
$data;
127 $this->error_string =
'SimplePie bug! Please report this!';
134 static $xml_is_sane = null;
135 if ($xml_is_sane === null)
137 $parser_check = xml_parser_create();
138 xml_parse_into_struct($parser_check,
'<foo>&</foo>', $values);
139 xml_parser_free($parser_check);
140 $xml_is_sane = isset($values[0][
'value']);
146 $xml = xml_parser_create_ns($this->encoding, $this->separator);
147 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
148 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
149 xml_set_object($xml, $this);
150 xml_set_character_data_handler($xml,
'cdata');
151 xml_set_element_handler($xml,
'tag_open',
'tag_close');
154 if (!xml_parse($xml,
$data,
true))
156 $this->error_code = xml_get_error_code($xml);
157 $this->error_string = xml_error_string($this->error_code);
160 $this->current_line = xml_get_current_line_number($xml);
161 $this->current_column = xml_get_current_column_number($xml);
162 $this->current_byte = xml_get_current_byte_index($xml);
163 xml_parser_free($xml);
168 libxml_clear_errors();
169 $xml =
new XMLReader();
171 while (@$xml->read())
173 switch ($xml->nodeType)
176 case constant(
'XMLReader::END_ELEMENT'):
177 if ($xml->namespaceURI !==
'')
179 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
183 $tagName = $xml->localName;
187 case constant(
'XMLReader::ELEMENT'):
188 $empty = $xml->isEmptyElement;
189 if ($xml->namespaceURI !==
'')
191 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
195 $tagName = $xml->localName;
197 $attributes = array();
198 while ($xml->moveToNextAttribute())
200 if ($xml->namespaceURI !==
'')
202 $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
206 $attrName = $xml->localName;
208 $attributes[$attrName] = $xml->value;
210 $this->
tag_open(null, $tagName, $attributes);
216 case constant(
'XMLReader::TEXT'):
218 case constant(
'XMLReader::CDATA'):
219 $this->
cdata(null, $xml->value);
223 if ($error = libxml_get_last_error())
225 $this->error_code = $error->code;
226 $this->error_string = $error->message;
227 $this->current_line = $error->line;
228 $this->current_column = $error->column;
268 public function tag_open($parser, $tag, $attributes)
270 list($this->
namespace[], $this->element[]) = $this->
split_ns($tag);
273 foreach ($attributes as $name => $value)
275 list($attrib_namespace, $attribute) = $this->
split_ns($name);
276 $attribs[$attrib_namespace][$attribute] = $value;
281 $base = $this->registry->call(
'Misc',
'absolutize_url', array($attribs[SIMPLEPIE_NAMESPACE_XML][
'base'], end($this->xml_base)));
284 $this->xml_base[] = $base;
285 $this->xml_base_explicit[] =
true;
290 $this->xml_base[] = end($this->xml_base);
291 $this->xml_base_explicit[] = end($this->xml_base_explicit);
294 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML][
'lang']))
300 $this->xml_lang[] = end($this->xml_lang);
303 if ($this->current_xhtml_construct >= 0)
305 $this->current_xhtml_construct++;
308 $this->data[
'data'] .=
'<' . end($this->element);
309 if (isset($attribs[
'']))
311 foreach ($attribs[
''] as $name => $value)
313 $this->data[
'data'] .=
' ' . $name .
'="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) .
'"';
316 $this->data[
'data'] .=
'>';
322 $this->data =& $this->data[
'child'][end($this->
namespace)][end($this->element)][];
323 $this->data = array(
'data' =>
'',
'attribs' => $attribs,
'xml_base' => end($this->xml_base),
'xml_base_explicit' => end($this->xml_base_explicit),
'xml_lang' => end($this->xml_lang));
324 if ((end($this->
namespace) ===
SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array(
'title',
'tagline',
'copyright',
'info',
'summary',
'content')) && isset($attribs[
''][
'mode']) && $attribs[
''][
'mode'] ===
'xml')
325 || (end($this->
namespace) ===
SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array(
'rights',
'subtitle',
'summary',
'info',
'title',
'content')) && isset($attribs[
''][
'type']) && $attribs[
''][
'type'] ===
'xhtml')
330 $this->current_xhtml_construct = 0;
335 public function cdata($parser, $cdata)
337 if ($this->current_xhtml_construct >= 0)
339 $this->data[
'data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
343 $this->data[
'data'] .= $cdata;
349 if ($this->current_xhtml_construct >= 0)
351 $this->current_xhtml_construct--;
352 if (end($this->
namespace) ===
SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array(
'area',
'base',
'basefont',
'br',
'col',
'frame',
'hr',
'img',
'input',
'isindex',
'link',
'meta',
'param')))
354 $this->data[
'data'] .=
'</' . end($this->element) .
'>';
357 if ($this->current_xhtml_construct === -1)
359 $this->data =& $this->datas[count($this->datas) - 1];
360 array_pop($this->datas);
363 array_pop($this->element);
364 array_pop($this->
namespace);
365 array_pop($this->xml_base);
366 array_pop($this->xml_base_explicit);
367 array_pop($this->xml_lang);
372 static $cache = array();
373 if (!isset($cache[$string]))
375 if ($pos = strpos($string, $this->separator))
377 static $separator_length;
378 if (!$separator_length)
380 $separator_length = strlen($this->separator);
383 $local_name = substr($string, $pos + $separator_length);
398 $cache[$string] = array(
$namespace, $local_name);
402 $cache[$string] = array(
'', $string);
405 return $cache[$string];