@@ -53,11 +53,13 @@ public function encode($data, $format)
5353 */
5454 public function decode ($ data , $ format )
5555 {
56- $ xml = simplexml_load_string ($ data );
57- if (!$ xml ->count ()) {
58- return (string ) $ xml ;
56+ $ xml = \DOMDocument::loadXML ($ data );
57+ if (!$ xml ->documentElement ->hasChildNodes ()) {
58+ return "" ;
59+ } elseif ($ xml ->documentElement ->childNodes ->length == 1 && $ xml ->documentElement ->firstChild instanceof \DOMText) {
60+ return trim ((string )$ xml ->documentElement ->firstChild ->wholeText );
5961 }
60- return $ this ->parseXml ($ xml );
62+ return $ this ->parseXml ($ xml-> documentElement );
6163 }
6264
6365 /**
@@ -149,41 +151,62 @@ final protected function isElementNameValid($name)
149151 }
150152
151153 /**
152- * Parse the input SimpleXmlElement into an array
154+ * Parse the input DOMElement into an array
153155 *
154- * @param SimpleXmlElement $node xml to parse
156+ * @param DOMElement $node xml to parse
155157 * @return array
156158 */
157159 private function parseXml ($ node )
158160 {
159161 $ data = array ();
160- foreach ($ node ->children () as $ key => $ subnode ) {
161- if ($ subnode ->count ()) {
162+ foreach ($ node ->childNodes as $ subnode ) {
163+ //When xml is "beautiful" (with tabs and newlines...), tabs and newline are considered as text but we do not want them
164+ if ($ subnode instanceof DOMText && trim ($ subnode ->wholeText ) === "" ) {
165+ continue ;
166+ }
167+ if (!$ subnode ->hasChildNodes ()) {
168+ $ value = "" ;
169+ } elseif ($ subnode ->childNodes ->length == 1 && $ subnode ->firstChild instanceof \DOMText) {
170+ $ value = trim ((string )$ subnode ->firstChild ->wholeText );
171+ } else {
162172 $ value = $ this ->parseXml ($ subnode );
163- if ($ subnode ->attributes ()) {
164- foreach ($ subnode ->attributes () as $ attrkey => $ attr ) {
165- $ value ['@ ' .$ attrkey ] = (string ) $ attr ;
166- }
173+ }
174+
175+ if ($ subnode ->hasAttributes ()) {
176+ if (is_string ($ value ) && $ value !== "" ) {
177+ $ value = array ('# ' => $ value );
178+ } elseif (is_string ($ value )) {
179+ $ value = array ();
180+ }
181+ foreach ($ subnode ->attributes as $ attrKey => $ attr ) {
182+ $ value ['@ ' .$ attrKey ] = (string ) $ attr ->value ;
167183 }
168- } else {
169- $ value = (string ) $ subnode ;
170184 }
171- if ($ key === 'item ' ) {
172- if (isset ($ subnode ['key ' ])) {
173- $ data [(string )$ subnode ['key ' ]] = $ value ;
185+
186+ if ($ subnode ->tagName === 'item ' ) {
187+ if (isset ($ value ['@key ' ])) {
188+ $ key = $ value ['@key ' ];
189+ $ tmp = $ value ['# ' ];
190+ unset($ value ['@key ' ]);
191+ unset($ value ['# ' ]);
192+ if (!empty ($ value )) {
193+ $ data [$ key ] = array_merge (array ('# ' => $ tmp ), $ value );
194+ } else {
195+ $ data [$ key ] = $ tmp ;
196+ }
174197 } elseif (isset ($ data ['item ' ])) {
175198 $ tmp = $ data ['item ' ];
176199 unset($ data ['item ' ]);
177200 $ data [] = $ tmp ;
178201 $ data [] = $ value ;
179202 }
180- } elseif (key_exists ($ key , $ data )) {
181- if (false === is_array ($ data [$ key ] )) {
182- $ data [$ key ] = array ($ data [$ key ]);
203+ } elseif (key_exists ($ subnode -> tagName , $ data )) {
204+ if (( false === is_array ($ data [$ subnode -> tagName ])) || ( false === isset ( $ data [ $ subnode -> tagName ][ 0 ]) )) {
205+ $ data [$ subnode -> tagName ] = array ($ data [$ subnode -> tagName ]);
183206 }
184- $ data [$ key ][] = $ value ;
207+ $ data [$ subnode -> tagName ][] = $ value ;
185208 } else {
186- $ data [$ key ] = $ value ;
209+ $ data [$ subnode -> tagName ] = $ value ;
187210 }
188211 }
189212 return $ data ;
@@ -205,6 +228,8 @@ private function buildXml($parentNode, $data)
205228 //Ah this is the magic @ attribute types.
206229 if (0 === strpos ($ key , "@ " ) && is_scalar ($ data ) && $ this ->isElementNameValid ($ attributeName = substr ($ key ,1 ))) {
207230 $ parentNode ->setAttribute ($ attributeName , $ data );
231+ } elseif ($ key === '# ' ) {
232+ $ append = $ this ->selectNodeType ($ parentNode , $ data );
208233 } elseif (is_array ($ data ) && false === is_numeric ($ key )) {
209234 /**
210235 * Is this array fully numeric keys?
0 commit comments