XML.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /*
  3. * This file is part of the overtrue/wechat.
  4. *
  5. * (c) overtrue <i@overtrue.me>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. /**
  11. * XML.php.
  12. *
  13. * @author overtrue <i@overtrue.me>
  14. * @copyright 2015 overtrue <i@overtrue.me>
  15. *
  16. * @see https://github.com/overtrue
  17. * @see http://overtrue.me
  18. */
  19. namespace EasyWeChat\Support;
  20. use SimpleXMLElement;
  21. /**
  22. * Class XML.
  23. */
  24. class XML
  25. {
  26. /**
  27. * XML to array.
  28. *
  29. * @param string $xml XML string
  30. *
  31. * @return array|\SimpleXMLElement
  32. */
  33. public static function parse($xml)
  34. {
  35. $backup = libxml_disable_entity_loader(true);
  36. $result = self::normalize(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS));
  37. libxml_disable_entity_loader($backup);
  38. return $result;
  39. }
  40. /**
  41. * XML encode.
  42. *
  43. * @param mixed $data
  44. * @param string $root
  45. * @param string $item
  46. * @param string $attr
  47. * @param string $id
  48. *
  49. * @return string
  50. */
  51. public static function build(
  52. $data,
  53. $root = 'xml',
  54. $item = 'item',
  55. $attr = '',
  56. $id = 'id'
  57. ) {
  58. if (is_array($attr)) {
  59. $_attr = [];
  60. foreach ($attr as $key => $value) {
  61. $_attr[] = "{$key}=\"{$value}\"";
  62. }
  63. $attr = implode(' ', $_attr);
  64. }
  65. $attr = trim($attr);
  66. $attr = empty($attr) ? '' : " {$attr}";
  67. $xml = "<{$root}{$attr}>";
  68. $xml .= self::data2Xml($data, $item, $id);
  69. $xml .= "</{$root}>";
  70. return $xml;
  71. }
  72. /**
  73. * Build CDATA.
  74. *
  75. * @param string $string
  76. *
  77. * @return string
  78. */
  79. public static function cdata($string)
  80. {
  81. return sprintf('<![CDATA[%s]]>', $string);
  82. }
  83. /**
  84. * Object to array.
  85. *
  86. *
  87. * @param SimpleXMLElement $obj
  88. *
  89. * @return array
  90. */
  91. protected static function normalize($obj)
  92. {
  93. $result = null;
  94. if (is_object($obj)) {
  95. $obj = (array) $obj;
  96. }
  97. if (is_array($obj)) {
  98. foreach ($obj as $key => $value) {
  99. $res = self::normalize($value);
  100. if (('@attributes' === $key) && ($key)) {
  101. $result = $res;
  102. } else {
  103. $result[$key] = $res;
  104. }
  105. }
  106. } else {
  107. $result = $obj;
  108. }
  109. return $result;
  110. }
  111. /**
  112. * Array to XML.
  113. *
  114. * @param array $data
  115. * @param string $item
  116. * @param string $id
  117. *
  118. * @return string
  119. */
  120. protected static function data2Xml($data, $item = 'item', $id = 'id')
  121. {
  122. $xml = $attr = '';
  123. foreach ($data as $key => $val) {
  124. if (is_numeric($key)) {
  125. $id && $attr = " {$id}=\"{$key}\"";
  126. $key = $item;
  127. }
  128. $xml .= "<{$key}{$attr}>";
  129. if ((is_array($val) || is_object($val))) {
  130. $xml .= self::data2Xml((array) $val, $item, $id);
  131. } else {
  132. $xml .= is_numeric($val) ? $val : self::cdata($val);
  133. }
  134. $xml .= "</{$key}>";
  135. }
  136. return $xml;
  137. }
  138. }