@@ -22,91 +22,131 @@ public function __construct(Router $router, Responder $responder, array $propert
22
22
$ this ->reflection = $ reflection ;
23
23
}
24
24
25
- private function convertFromJsonToXml ( string $ body ): string
25
+ private function json2xml ( $ json , $ types = ' null,boolean,number, string,object,array ' )
26
26
{
27
- $ objectElement = $ this ->getProperty ('objectElement ' , 'object ' );
28
- $ prolog = '<?xml version="1.0" encoding="UTF-8"?> ' . "\n" ;
29
- $ xml = new \SimpleXMLElement ($ prolog . '<root></root> ' );
30
- $ object = json_decode ($ body );
31
- if (is_scalar ($ object )) {
32
- $ xml = $ xml ->addChild ($ objectElement , $ object );
33
- } else {
34
- $ xml = $ xml ->addChild ($ objectElement );
35
- $ this ->convertFromObjectToXml ($ object , $ xml , $ objectElement );
36
- }
37
- return $ prolog . $ xml ->asXML ();
38
- }
39
-
40
- private function convertFromObjectToXml ($ object , $ xml , string $ objectElement ): void
41
- {
42
- if (is_array ($ object )) {
43
- $ xml ->addAttribute ('type ' , 'list ' );
44
- }
45
- foreach ($ object as $ key => $ value ) {
46
- if (!is_array ($ value ) && !is_object ($ value )) {
47
- if (is_object ($ object )) {
48
- $ xml ->addChild ($ key , (string ) $ value );
27
+ $ a = json_decode ($ json );
28
+ $ d = new \DOMDocument ();
29
+ $ c = $ d ->createElement ("root " );
30
+ $ d ->appendChild ($ c );
31
+ $ t = function ($ v ) {
32
+ $ type = gettype ($ v );
33
+ switch ($ type ) {
34
+ case 'integer ' :
35
+ return 'number ' ;
36
+ case 'double ' :
37
+ return 'number ' ;
38
+ default :
39
+ return strtolower ($ type );
40
+ }
41
+ };
42
+ $ ts = explode (', ' , $ types );
43
+ $ f = function ($ f , $ c , $ a , $ s = false ) use ($ t , $ d , $ ts ) {
44
+ if (in_array ($ t ($ a ), $ ts )) {
45
+ $ c ->setAttribute ('type ' , $ t ($ a ));
46
+ }
47
+ if ($ t ($ a ) != 'array ' && $ t ($ a ) != 'object ' ) {
48
+ if ($ t ($ a ) == 'boolean ' ) {
49
+ $ c ->appendChild ($ d ->createTextNode ($ a ? 'true ' : 'false ' ));
49
50
} else {
50
- $ xml ->addChild ($ objectElement , (string ) $ value );
51
+ $ c ->appendChild ($ d ->createTextNode ($ a ));
52
+ }
53
+ } else {
54
+ foreach ($ a as $ k => $ v ) {
55
+ if ($ k == '__type ' && $ t ($ a ) == 'object ' ) {
56
+ $ c ->setAttribute ('__type ' , $ v );
57
+ } else {
58
+ if ($ t ($ v ) == 'object ' ) {
59
+ $ ch = $ c ->appendChild ($ d ->createElementNS (null , $ s ? 'item ' : $ k ));
60
+ $ f ($ f , $ ch , $ v );
61
+ } else if ($ t ($ v ) == 'array ' ) {
62
+ $ ch = $ c ->appendChild ($ d ->createElementNS (null , $ s ? 'item ' : $ k ));
63
+ $ f ($ f , $ ch , $ v , true );
64
+ } else {
65
+ $ va = $ d ->createElementNS (null , $ s ? 'item ' : $ k );
66
+ if ($ t ($ v ) == 'boolean ' ) {
67
+ $ va ->appendChild ($ d ->createTextNode ($ v ? 'true ' : 'false ' ));
68
+ } else {
69
+ $ va ->appendChild ($ d ->createTextNode ($ v ));
70
+ }
71
+ $ ch = $ c ->appendChild ($ va );
72
+ if (in_array ($ t ($ v ), $ ts )) {
73
+ $ ch ->setAttribute ('type ' , $ t ($ v ));
74
+ }
75
+ }
76
+ }
51
77
}
52
- continue ;
53
- }
54
- $ node = $ xml ;
55
- if (is_object ($ object )) {
56
- $ node = $ node ->addChild ($ key );
57
- } elseif (is_object ($ value )) {
58
- $ node = $ node ->addChild ($ objectElement );
59
78
}
60
- $ this ->convertFromObjectToXml ($ value , $ node , $ objectElement );
61
- }
79
+ };
80
+ $ f ($ f , $ c , $ a , $ t ($ a ) == 'array ' );
81
+ return $ d ->saveXML ($ d ->documentElement );
62
82
}
63
83
64
- private function convertFromXmlToJson ( string $ body ) /*: object */
84
+ private function xml2json ( $ xml )
65
85
{
66
- $ objectElement = $ this ->getProperty ('objectElement ' , 'object ' );
67
- $ prolog = '<?xml version="1.0" encoding="UTF-8"?> ' . "\n" ;
68
- $ xml = new \SimpleXMLElement ($ prolog . $ body );
69
- $ object = $ this ->convertFromXmlToObject ($ xml , $ objectElement );
70
- return json_decode (json_encode ($ object ));
71
- }
72
-
73
- private function convertFromXmlToObject ($ xml ): array
74
- {
75
- $ result = [];
76
- foreach ($ xml ->children () as $ nodeName => $ nodeValue ) {
77
- if (count ($ nodeValue ->children ()) == 0 ) {
78
- $ object = strVal ($ nodeValue );
79
- } else {
80
- $ object = $ this ->convertFromXmlToObject ($ nodeValue );
81
- }
82
- $ attributes = $ xml ->attributes ();
83
- if ($ attributes ['type ' ] == 'list ' ) {
84
- $ result [] = $ object ;
85
- } else {
86
- $ result [$ nodeName ] = $ object ;
87
- }
86
+ $ a = @dom_import_simplexml (simplexml_load_string ($ xml ));
87
+ if (!$ a ) {
88
+ return null ;
88
89
}
89
- return $ result ;
90
+ $ t = function ($ v ) {
91
+ $ t = $ v ->getAttribute ('type ' );
92
+ $ txt = $ v ->firstChild ->nodeType == XML_TEXT_NODE ;
93
+ return $ t ?: ($ txt ? 'string ' : 'object ' );
94
+ };
95
+ $ f = function ($ f , $ a ) use ($ t ) {
96
+ $ c = null ;
97
+ if ($ t ($ a ) == 'null ' ) {
98
+ $ c = null ;
99
+ } else if ($ t ($ a ) == 'boolean ' ) {
100
+ $ b = substr (strtolower ($ a ->textContent ), 0 , 1 );
101
+ $ c = in_array ($ b , array ('1 ' , 't ' ));
102
+ } else if ($ t ($ a ) == 'number ' ) {
103
+ $ c = $ a ->textContent + 0 ;
104
+ } else if ($ t ($ a ) == 'string ' ) {
105
+ $ c = $ a ->textContent ;
106
+ } else if ($ t ($ a ) == 'object ' ) {
107
+ $ c = array ();
108
+ if ($ a ->getAttribute ('__type ' )) {
109
+ $ c ['__type ' ] = $ a ->getAttribute ('__type ' );
110
+ }
111
+ for ($ i = 0 ; $ i < $ a ->childNodes ->length ; $ i ++) {
112
+ $ v = $ a ->childNodes [$ i ];
113
+ $ c [$ v ->nodeName ] = $ f ($ f , $ v );
114
+ }
115
+ $ c = (object ) $ c ;
116
+ } else if ($ t ($ a ) == 'array ' ) {
117
+ $ c = array ();
118
+ for ($ i = 0 ; $ i < $ a ->childNodes ->length ; $ i ++) {
119
+ $ v = $ a ->childNodes [$ i ];
120
+ $ c [$ i ] = $ f ($ f , $ v );
121
+ }
122
+ }
123
+ return $ c ;
124
+ };
125
+ $ c = $ f ($ f , $ a );
126
+ return json_encode ($ c );
90
127
}
91
128
92
129
public function process (ServerRequestInterface $ request , RequestHandlerInterface $ next ): ResponseInterface
93
130
{
94
- $ operation = RequestUtils::getOperation ($ request );
95
-
96
131
parse_str ($ request ->getUri ()->getQuery (), $ params );
97
132
$ isXml = isset ($ params ['format ' ]) && $ params ['format ' ] == 'xml ' ;
98
133
if ($ isXml ) {
99
134
$ body = $ request ->getBody ()->getContents ();
100
135
if ($ body ) {
101
- $ json = $ this ->convertFromXmlToJson ($ body );
102
- $ request = $ request ->withParsedBody ($ json );
136
+ $ json = $ this ->xml2json ($ body );
137
+ $ request = $ request ->withParsedBody (json_decode ( $ json) );
103
138
}
104
139
}
105
140
$ response = $ next ->handle ($ request );
106
141
if ($ isXml ) {
107
142
$ body = $ response ->getBody ()->getContents ();
108
143
if ($ body ) {
109
- $ xml = $ this ->convertFromJsonToXml ($ body );
144
+ $ types = implode (', ' , $ this ->getArrayProperty ('types ' , 'null,array ' ));
145
+ if ($ types == '' || $ types == 'all ' ) {
146
+ $ xml = $ this ->json2xml ($ body );
147
+ } else {
148
+ $ xml = $ this ->json2xml ($ body , $ types );
149
+ }
110
150
$ response = ResponseFactory::fromXml (ResponseFactory::OK , $ xml );
111
151
}
112
152
}
0 commit comments