413 if (file_exists($file))
415 $content = file_get_contents($file);
417 if (defined(
'SITE_CHARSET'))
419 $charset = (defined(
"BX_DEFAULT_CHARSET")? BX_DEFAULT_CHARSET :
"windows-1251");
420 if (preg_match(
"/<".
"\\?XML[^>]+encoding=[\"']([^>\"']+)[\"'][^>]*\\?".
">/i",
$content,
$matches))
426 $this->tree = $this->__parse(
$content);
427 return $this->tree !==
false;
439 $this->tree = $this->__parse(
$text);
440 return ($this->tree !==
false);
453 if (!is_object($this->tree))
457 return $this->tree->__toArray();
462 if (!is_object($this->tree))
466 return $this->tree->__toString();
474 if (!is_object($this->tree))
481 $tmp = explode(
"/", $strNode);
483 for (
$i = 1;
$i < $tmpCount;
$i++)
487 if (!is_array(
$result->children))
491 for ($j = 0, $c =
count(
$result->children); $j < $c; $j++)
513 static $search =
array(
"&",
"<",
">",
"\"",
"'");
514 static $replace =
array(
"&",
"<",
">",
""",
"'");
515 return str_replace($search, $replace,
$str);
520 static $search =
array(
"<",
">",
""",
"'",
"&");
521 static $replace =
array(
"<",
">",
"\"",
"'",
"&");
522 return str_replace($search, $replace,
$str);
531 protected function __parse(&$strXMLText)
533 static $search =
array(
">",
"<",
"'",
""",
"&");
534 static $replace =
array(
">",
"<",
"'",
'"',
"&");
544 $strXMLText = preg_replace(
"%<!DOCTYPE[^\\[>]*\\[.*?]>%is",
"", $strXMLText, -1, $cnt);
547 $strXMLText = preg_replace(
"%<!DOCTYPE[^>]*>%i",
"", $strXMLText);
551 preg_match_all(
"#<\\?(.*?)\\?>#i", $strXMLText, $arXMLHeader_tmp);
552 foreach ($arXMLHeader_tmp[0] as $strXMLHeader_tmp)
554 preg_match_all(
"/([a-zA-Z:]+=\".*?\")/i", $strXMLHeader_tmp, $arXMLParam_tmp);
555 foreach ($arXMLParam_tmp[0] as $strXMLParam_tmp)
557 if ($strXMLParam_tmp <>
'')
559 $arXMLAttribute_tmp = explode(
"=\"", $strXMLParam_tmp);
560 if ($arXMLAttribute_tmp[0] ==
"version")
561 $oXMLDocument->version = mb_substr($arXMLAttribute_tmp[1], 0, mb_strlen($arXMLAttribute_tmp[1]) - 1);
562 elseif ($arXMLAttribute_tmp[0] ==
"encoding")
563 $oXMLDocument->encoding = mb_substr($arXMLAttribute_tmp[1], 0, mb_strlen($arXMLAttribute_tmp[1]) - 1);
569 $strXMLText = preg_replace(
"#<\\?.*?\\?>#",
"", $strXMLText);
571 $oXMLDocument->root = &$oXMLDocument->children;
574 $currentNode = &$oXMLDocument;
576 $tok = strtok($strXMLText,
"<");
577 $arTag = explode(
">", $tok);
582 $arTag = explode(
">", $tok);
583 if (
count($arTag) < 2)
590 while ($tok !==
false)
592 $tagName = $arTag[0];
593 $tagContent = $arTag[1];
597 if ($tagName[0] ==
"/")
599 $tagName = mb_substr($tagName, 1);
601 if ($this->delete_ns)
603 $colonPos = mb_strpos($tagName,
":");
606 $tagName = mb_substr($tagName, $colonPos + 1);
609 if ($currentNode->name != $tagName)
615 $currentNode = $currentNode->_parent;
618 if ((!$this->TrimWhiteSpace) || (trim($tagContent) !=
""))
619 $currentNode->content = str_replace($search, $replace, $tagContent);
621 elseif (strncmp($tagName,
"![CDATA[", 8) === 0)
628 $cdata .= $arTag[
$i].
">";
629 if (str_ends_with($cdata,
"]]>"))
631 $tagContent = $arTag[
$i+1];
636 if (!str_ends_with($cdata,
"]]>"))
638 $cdata = mb_substr($cdata, 0, -1).
"<";
645 while ($tok !==
false && !str_ends_with($tok,
"]]"));
649 $cdataSection = mb_substr($cdata, 8, -3);
652 $subNode =
new CDataXMLNode();
653 $subNode->name =
"cdata-section";
654 $subNode->content = $cdataSection;
656 $currentNode->children[] = $subNode;
657 $currentNode->content .= $subNode->content;
660 if ((!$this->TrimWhiteSpace) || (trim($tagContent) !=
""))
661 $currentNode->content = str_replace($search, $replace, $tagContent);
666 if (preg_match(
'/^(\S+)(.*)$/s', $tagName, $match))
668 $justName = $match[1];
669 $attributePart = $match[2];
673 $justName = $tagName;
678 if ($this->delete_ns)
680 $colonPos = mb_strpos($justName,
":");
683 $justName = mb_substr($justName, $colonPos + 1);
687 $justName = rtrim($justName,
"/");
689 $subNode =
new CDataXMLNode();
690 $subNode->_parent = $currentNode;
691 $subNode->name = $justName;
701 $subNode->attributes = $attr;
706 if ((!$this->TrimWhiteSpace) || (trim($tagContent) !=
""))
708 $subNode->content = str_replace($search, $replace, $tagContent);
711 $currentNode->children[] = $subNode;
713 if (!str_ends_with($tagName,
"/"))
715 $currentNode = $subNode;
721 $arTag = explode(
">", $tok);
723 if (
count($arTag) < 2 && (strncmp($tagName,
"![CDATA[", 8) === 0))
725 $currentNode->content .= $arTag[0];
728 if ((!$this->TrimWhiteSpace) || (trim($tagContent) !=
""))
729 $currentNode->content = str_replace($search, $replace, $tagContent);
732 $arTag = explode(
">", $tok);
735 return $oXMLDocument;
740 $str = preg_replace(
"#<!--.*?-->#s",
"",
$str);
749 preg_match_all(
"/(\\S+)\\s*=\\s*([\"'])(.*?)\\2/su", $attributeString, $attributeArray);
751 foreach ($attributeArray[0] as
$i => $attributePart)
753 $attributePart = trim($attributePart);
754 if ($attributePart !=
"" && $attributePart !=
"/")
756 $attributeName = $attributeArray[1][
$i];
759 if ($this->delete_ns)
761 $colonPos = mb_strpos($attributeName,
":");
766 if ($colonPos == 5 && (mb_substr($attributeName, 0, $colonPos) ==
'xmlns'))
768 $attributeName =
'xmlns';
772 $attributeName = mb_substr($attributeName, $colonPos + 1);
776 $attributeValue = $attributeArray[3][
$i];
779 $attrNode->name = $attributeName;
837 private $fileCharset =
false;
838 private $filePosition = 0;
839 private $xmlPosition =
"";
840 private $nodeHandlers =
array();
841 private $elementHandlers =
array();
842 private $endNodes =
array();
843 private $fileHandler =
null;
845 private $eof =
false;
846 private $readSize = 1024;
848 private $bufPosition = 0;
850 private $positionStack =
array();
851 private $elementStack =
array();
862 if (is_callable($callableHandler))
864 if (!isset($this->nodeHandlers[$nodePath]))
865 $this->nodeHandlers[$nodePath] =
array();
866 $this->nodeHandlers[$nodePath][] = $callableHandler;
868 $pathComponents = explode(
"/", $nodePath);
869 $this->endNodes[end($pathComponents)] =
true;
882 if (is_callable($callableHandler))
884 if (!isset($this->elementHandlers[$nodePath]))
885 $this->elementHandlers[$nodePath] =
array();
886 $this->elementHandlers[$nodePath][] = $callableHandler;
888 $pathComponents = explode(
"/", $nodePath);
889 $this->endNodes[end($pathComponents)] =
true;
901 $this->fileHandler =
null;
903 $io = CBXVirtualIo::getInstance();
904 $file =
$io->getFile($filePath);
905 $this->fileHandler = $file->open(
"rb");
906 if (is_resource($this->fileHandler))
908 if ($this->filePosition > 0)
909 fseek($this->fileHandler, $this->filePosition);
911 $this->elementStack =
array();
912 $this->positionStack =
array();
913 foreach (explode(
"/", $this->xmlPosition) as $pathPart)
915 @list($elementPosition, $elementName) = explode(
"@", $pathPart, 2);
916 $this->elementStack[] = $elementName;
917 $this->positionStack[] = $elementPosition;
935 if ($this->fileHandler ===
null)
948 $this->xmlPosition =
array();
949 foreach ($this->elementStack as
$i => $elementName)
951 $this->xmlPosition[] = $this->positionStack[
$i].
"@".$elementName;
953 $this->xmlPosition = implode(
"/", $this->xmlPosition);
970 if (is_array($position))
972 if (isset($position[0]))
973 $this->fileCharset = $position[0];
974 if (isset($position[1]))
975 $this->filePosition = $position[1];
976 if (isset($position[2]))
977 $this->xmlPosition = $position[2];
988 $cs = $this->fileCharset;
990 if ($this->fileHandler ===
null)
994 while (($xmlChunk = $this->getXmlChunk()) !==
false)
996 $origChunk = $xmlChunk;
999 $xmlChunk = Encoding::convertEncoding($origChunk, $cs,
LANG_CHARSET);
1002 if ($xmlChunk[0] ==
"/")
1004 $this->endElement();
1007 elseif ($xmlChunk[0] ==
"!" || $xmlChunk[0] ==
"?")
1009 if (str_starts_with($xmlChunk,
"?xml"))
1011 if (preg_match(
'#encoding\s*=\s*"(.*?)"#i', $xmlChunk, $arMatch))
1013 $this->fileCharset = $arMatch[1];
1014 if (mb_strtoupper($this->fileCharset) === mb_strtoupper(
LANG_CHARSET))
1016 $this->fileCharset =
false;
1018 $cs = $this->fileCharset;
1021 elseif (str_starts_with($xmlChunk,
'![CDATA['))
1023 while (!str_ends_with($xmlChunk,
']]>'))
1025 $xmlChunk = $this->getXmlChunk();
1026 if ($xmlChunk ===
false)
1035 $this->startElement($xmlChunk, $origChunk);
1037 $p = mb_strpos($xmlChunk,
">");
1038 if ((
$p !==
false) && (mb_substr($xmlChunk,
$p - 1, 1) ==
"/"))
1040 $this->endElement();
1055 private function getXmlChunk()
1057 if ($this->bufPosition >= $this->bufLen)
1059 if (is_resource($this->fileHandler) && !feof($this->fileHandler))
1061 $this->buf = fread($this->fileHandler, $this->readSize);
1062 $this->bufPosition = 0;
1063 $this->bufLen = strlen($this->buf);
1072 $xml_position = strpos($this->buf,
"<", $this->bufPosition);
1073 while ($xml_position === $this->bufPosition)
1075 $this->bufPosition++;
1076 $this->filePosition++;
1078 if ($this->bufPosition >= $this->bufLen)
1080 if (!feof($this->fileHandler))
1082 $this->buf = fread($this->fileHandler, $this->readSize);
1083 $this->bufPosition = 0;
1084 $this->bufLen = strlen($this->buf);
1091 $xml_position = strpos($this->buf,
"<", $this->bufPosition);
1095 while ($xml_position===
false)
1097 $next_search = $this->bufLen;
1099 if (!feof($this->fileHandler))
1101 $this->buf .= fread($this->fileHandler, $this->readSize);
1102 $this->bufLen = strlen($this->buf);
1110 $xml_position = strpos($this->buf,
"<", $next_search);
1112 if ($xml_position===
false)
1114 $xml_position = $this->bufLen+1;
1117 $len = $xml_position-$this->bufPosition;
1118 $this->filePosition += $len;
1119 $result = substr($this->buf, $this->bufPosition, $len);
1120 $this->bufPosition = $xml_position;
1132 private function startElement($xmlChunk, $origChunk)
1134 static $search =
array(
1141 static $replace =
array(
1148 $p = mb_strpos($xmlChunk,
">");
1151 if (mb_substr($xmlChunk,
$p - 1, 1) ==
"/")
1153 $elementName = mb_substr($xmlChunk, 0,
$p - 1);
1157 $elementName = mb_substr($xmlChunk, 0,
$p);
1160 if (($ps = mb_strpos($elementName,
" "))!==
false)
1162 $elementAttrs = mb_substr($elementName, $ps + 1);
1163 $elementName = mb_substr($elementName, 0, $ps);
1170 $this->elementStack[] = $elementName;
1171 $this->positionStack[] = $this->filePosition - strlen($origChunk) - 1;
1173 if (isset($this->endNodes[$elementName]))
1175 $xmlPath = implode(
"/", $this->elementStack);
1176 if (isset($this->elementHandlers[$xmlPath]))
1178 $attributes =
array();
1179 if ($elementAttrs !==
"")
1181 preg_match_all(
"/(\\S+)\\s*=\\s*\"(.*?)\"/s", $elementAttrs, $attrs_tmp);
1182 if (!str_contains($elementAttrs,
"&"))
1184 foreach ($attrs_tmp[1] as
$i=>$attrs_tmp_1)
1186 $attributes[$attrs_tmp_1] = $attrs_tmp[2][
$i];
1191 foreach ($attrs_tmp[1] as
$i=>$attrs_tmp_1)
1193 $attributes[$attrs_tmp_1] = preg_replace($search, $replace, $attrs_tmp[2][
$i]);
1198 foreach ($this->elementHandlers[$xmlPath] as $callableHandler)
1200 call_user_func_array($callableHandler,
array(
1215 private function endElement()
1217 $elementName = array_pop($this->elementStack);
1218 $elementPosition = array_pop($this->positionStack);
1220 if (isset($this->endNodes[$elementName]))
1222 $xmlPath = implode(
"/", $this->elementStack).
"/".$elementName;
1223 if (isset($this->nodeHandlers[$xmlPath]))
1225 $xmlObject = $this->readXml($elementPosition, $this->filePosition);
1226 if (is_object($xmlObject))
1228 foreach ($this->nodeHandlers[$xmlPath] as $callableHandler)
1230 call_user_func_array($callableHandler,
array(
1245 private function readXml($startPosition, $endPosition)
1247 $xmlChunk = $this->readFilePart($startPosition, $endPosition);
1248 if ($xmlChunk && $this->fileCharset)
1250 $xmlChunk = Encoding::convertEncoding($xmlChunk, $this->fileCharset,
LANG_CHARSET);
1253 $xmlObject =
new CDataXML;
1254 if ($xmlObject->loadString($xmlChunk))
1270 if (is_resource($this->fileHandler))
1272 $savedPosition = ftell($this->fileHandler);
1273 fseek($this->fileHandler, $startPosition);
1274 $xmlChunk = fread($this->fileHandler, $endPosition - $startPosition);
1275 fseek($this->fileHandler, $savedPosition);
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)