* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ /** * XML.php. * * @author overtrue * @copyright 2015 overtrue * * @see https://github.com/overtrue * @see http://overtrue.me */ namespace EasyWeChat\Support; use SimpleXMLElement; /** * Class XML. */ class XML { /** * XML to array. * * @param string $xml XML string * * @return array|\SimpleXMLElement */ public static function parse($xml) { $backup = libxml_disable_entity_loader(true); $result = self::normalize(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS)); libxml_disable_entity_loader($backup); return $result; } /** * XML encode. * * @param mixed $data * @param string $root * @param string $item * @param string $attr * @param string $id * * @return string */ public static function build( $data, $root = 'xml', $item = 'item', $attr = '', $id = 'id' ) { if (is_array($attr)) { $_attr = []; foreach ($attr as $key => $value) { $_attr[] = "{$key}=\"{$value}\""; } $attr = implode(' ', $_attr); } $attr = trim($attr); $attr = empty($attr) ? '' : " {$attr}"; $xml = "<{$root}{$attr}>"; $xml .= self::data2Xml($data, $item, $id); $xml .= ""; return $xml; } /** * Build CDATA. * * @param string $string * * @return string */ public static function cdata($string) { return sprintf('', $string); } /** * Object to array. * * * @param SimpleXMLElement $obj * * @return array */ protected static function normalize($obj) { $result = null; if (is_object($obj)) { $obj = (array) $obj; } if (is_array($obj)) { foreach ($obj as $key => $value) { $res = self::normalize($value); if (('@attributes' === $key) && ($key)) { $result = $res; } else { $result[$key] = $res; } } } else { $result = $obj; } return $result; } /** * Array to XML. * * @param array $data * @param string $item * @param string $id * * @return string */ protected static function data2Xml($data, $item = 'item', $id = 'id') { $xml = $attr = ''; foreach ($data as $key => $val) { if (is_numeric($key)) { $id && $attr = " {$id}=\"{$key}\""; $key = $item; } $xml .= "<{$key}{$attr}>"; if ((is_array($val) || is_object($val))) { $xml .= self::data2Xml((array) $val, $item, $id); } else { $xml .= is_numeric($val) ? $val : self::cdata($val); } $xml .= ""; } return $xml; } }