OSDN Git Service

change default parameters
[php-libraries/Array2Xml.git] / src / Array2Xml.php
1 <?php
2
3 namespace frostbane;
4
5 class Array2Xml
6 {
7     private $comments;
8     private $cdata;
9     private $attribute;
10     private $version;
11     private $encoding;
12
13     public function __construct(array $options = array())
14     {
15         $default = array(
16             "comments"  => array(
17                 "<!--",
18                 "<!---->",
19             ),
20             "cdata"     => array(
21                 "<![CDATA[",
22                 "<![CDATA[]]>",
23             ),
24             "attribute" => "@",
25             "version"   => "1.0",
26             "encoding"  => "UTF-8",
27         );
28
29         $options = array_merge_recursive($default, $options);
30
31         $this->comments  = $options["comments"];
32         $this->cdata     = $options["cdata"];
33         $this->attribute = $options["attribute"];
34         $this->version   = $options["version"];
35         $this->encoding  = $options["encoding"];
36     }
37
38     private function getFirstItem(&$array)
39     {
40         if (count($array) !== 1) {
41             return null;
42         }
43
44         $element = array_keys($array)[0];
45
46         return $array[$element];
47     }
48
49     private function arrayIsNumeric(&$array)
50     {
51         if (count($array) !== 1) {
52             return false;
53         }
54
55         $keys = array_keys($this->getFirstItem($array));
56
57         foreach ($keys as $key) {
58             if ( !is_numeric($key)) {
59                 return false;
60             }
61         }
62
63         return true;
64     }
65
66     private function arrayIsComment(&$array)
67     {
68         if (count($array) !== 1) {
69             return false;
70         }
71
72         $key = array_keys($array)[0];
73
74         return in_array($key, $this->comments);
75     }
76
77     private function arrayIsCData(&$array)
78     {
79         if (count($array) !== 1) {
80             return false;
81         }
82
83         $key = array_keys($array)[0];
84
85         return in_array($key, $this->cdata);
86     }
87
88     private function escapeCData(&$value)
89     {
90         $cdataEsc = '<![CDATA[' . str_replace(']]>', ']]]]><![CDATA[>', $value) . ']]>';
91
92         return htmlentities($cdataEsc);
93     }
94
95     private function getAttributes(&$array)
96     {
97         $attributes = array();
98
99         if (is_array($array) && array_key_exists($this->attribute, $array)) {
100             $attributes = $array[$this->attribute];
101
102             unset($array[$this->attribute]);
103
104             $value = array_shift($array);
105             $array = $value;
106         }
107
108         $attributeStr = "";
109
110         foreach ($attributes as $name => $val) {
111             $val = htmlentities($val, ENT_QUOTES);
112
113             $attributeStr .= " $name='$val'";
114         }
115
116         return ltrim($attributeStr);
117     }
118
119     private function dataArray2xml(&$array, $element)
120     {
121         $xml = "";
122
123         foreach ($array as $index => $value) {
124             $attribute = $this->getAttributes($value);
125
126             if (is_array($value) && $this->arrayIsComment($value)) {
127                 $xml .= "<!-- " . htmlentities(array_values($value)[0]) . " -->";
128             } else if (is_array($value) && !empty($value)) {
129                 $xml .= "<$element $attribute>" . $this->array2xml($value) . "</$element>";
130             } elseif (empty($value)) {
131                 $xml .= "<$element $attribute/>";
132             } else {
133                 $xml .= "<$element $attribute>" . htmlentities($value) . "</$element>";
134             }
135         }
136
137         return $xml;
138     }
139
140     private function array2xml(&$array, $prevElement = "")
141     {
142         $xml = "";
143
144         foreach ($array as $element => $value) {
145             if (is_numeric($element) && empty($value)) {
146                 continue;
147             }
148
149             if (is_numeric($element) && !empty($prevElement)) {
150                 $element = $prevElement;
151             }
152
153             if (is_numeric($element)) {
154                 $element = "_$element";
155             }
156
157             $element = htmlentities($element);
158
159             $attribute = $this->getAttributes($value);
160
161             if (empty($value)) {
162                 $xml .= "<$element $attribute/>";
163             } else if (is_array($value) && $this->arrayIsComment($value)) {
164                 $xml .= "<!-- " . htmlentities(array_values($value)[0]) . " -->";
165             } else if (is_array($value) && $this->arrayIsCData($value)) {
166                 $xml .= "<$element $attribute><![CDATA[" . $this->escapeCData(array_values($value)[0]) . "]]></$element>";
167             } else if (is_array($value) && $this->arrayIsNumeric($array)) {
168                 $xml = $this->dataArray2xml($value, $element);
169             } else if (is_array($value) && !empty($value)) {
170                 $xml .= "<$element $attribute>" . $this->array2xml($value, $element) . "</$element>";
171             } else {
172                 $xml .= "<$element $attribute>" . htmlentities($value, ENT_QUOTES) . "</$element>";
173             }
174         }
175
176         return $xml;
177     }
178
179     public function createXml(&$data, $root = "root")
180     {
181         $array  = array($root => $data);
182         $xmlStr = $this->array2xml($array);
183
184         simplexml_load_string($xmlStr);
185
186         return "<?xml version='{$this->version}' encoding='{$this->encoding}'?>$xmlStr";
187     }
188 }
189