diff --git a/niucloud/vendor/w7corp/easywechat/src/Kernel/Support/Xml.php b/niucloud/vendor/w7corp/easywechat/src/Kernel/Support/Xml.php new file mode 100644 index 000000000..97a8b78d0 --- /dev/null +++ b/niucloud/vendor/w7corp/easywechat/src/Kernel/Support/Xml.php @@ -0,0 +1,158 @@ +|null + */ + public static function parse(string $xml): array|null + { + if (empty($xml)) { + return null; + } + + $xml = simplexml_load_string( + self::sanitize($xml), + 'SimpleXMLElement', + LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS + ); + + if (!$xml) { + throw new InvalidArgumentException('Invalid XML'); + } + + return self::normalize($xml); + } + + /** + * @param array $data + * @param string $root + * @param string $item + * @param string|array $attr + * @param string $id + * + * @return string + */ + public static function build( + array $data, + string $root = 'xml', + string $item = 'item', + string|array $attr = '', + string $id = 'id' + ): string { + if (is_array($attr)) { + $segments = []; + + foreach ($attr as $key => $value) { + /** @phpstan-ignore-next-line */ + $segments[] = "{$key}=\"{$value}\""; + } + + $attr = implode(' ', $segments); + } + + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = "<{$root}{$attr}>"; + $xml .= self::data2Xml($data, $item, $id); + $xml .= ""; + + return $xml; + } + + public static function cdata(?string $string): string + { + return sprintf('', $string ?? ''); + } + + /** + * @psalm-suppress RedundantCondition + * @param array|SimpleXMLElement $object + * @return array|null + */ + protected static function normalize(SimpleXMLElement|array $object): array|null + { + $result = null; + + if (is_object($object)) { + $object = (array) $object; + } + + if (is_array($object)) { + foreach ($object as $key => $value) { + $value = $value instanceof SimpleXMLElement ? self::normalize($value) : $value; + + if ('@attributes' === $key) { + $result = $value; // @codeCoverageIgnore + } else { + $result[$key] = $value; + } + } + } + + return $result; + } + + /** + * @param array $data + * @param string $item + * @param string $id + * + * @return string + */ + protected static function data2Xml(array $data, string $item = 'item', string $id = 'id'): string + { + $xml = $attr = ''; + + foreach ($data as $key => $val) { + if (is_numeric($key)) { + $attr = " {$id}=\"{$key}\""; + $key = $item; + } + + $xml .= "<{$key}{$attr}>"; + + if ((is_array($val) || is_object($val))) { + $xml .= self::data2Xml((array) $val, $item, $id); + } else { + /** @phpstan-ignore-next-line */ + $xml .= is_numeric($val) ? $val : self::cdata($val); + } + + $xml .= ""; + } + + return $xml; + } + + /** + * Delete invalid characters in XML. + * + * @see https://www.w3.org/TR/2008/REC-xml-20081126/#charsets - XML charset range + * @see http://php.net/manual/en/regexp.reference.escape.php - escape in UTF-8 mode + * + * @param ?string $xml + * + * @return string + */ + public static function sanitize(?string $xml): string + { + if (empty($xml)) { + return ''; + } + + return preg_replace( + '/[^\x{9}\x{A}\x{D}\x{20}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]+/u', + '', + $xml + ) ?? ''; + } +} \ No newline at end of file