1
1
<?php
2
+ use function Swlib \Http \stream_for ;
2
3
class Xml {
3
4
private static function intoObject (SimpleXMLElement $ data , array &$ need_array , string $ key ) {
4
5
$ s = $ data ->__toString ();
5
6
if (str_replace ([
6
- ' ' ,
7
- "\n" ,
8
- "\r" ,
9
- "\t"
10
- ], '' , $ s ) != '' ) {
7
+ ' ' ,
8
+ "\n" ,
9
+ "\r" ,
10
+ "\t"
11
+ ], '' , $ s ) != '' ) {
11
12
return $ s ;
12
13
}
13
14
$ result = new stdClass ();
14
15
$ flag = 0 ; // 0表示没有儿子 1表示有多个同键名儿子 2表示有儿子
15
16
$ map = [];
16
- foreach ($ data as $ k=> $ v ) {
17
+ foreach ($ data as $ k => $ v ) {
17
18
$ child_need_to_be_array = in_array ("$ key. $ k " , $ need_array );
18
- if ($ child_need_to_be_array && ! isset ($ result ->{$ k }))
19
+ if ($ child_need_to_be_array && ! isset ($ result ->{$ k })) {
19
20
$ result ->{$ k } = [];
21
+ }
20
22
21
23
// 有两项相同健值,说明这里需要转换为数组
22
24
if (! $ child_need_to_be_array && $ flag !== 1 && array_key_exists ($ k , $ map )) {
@@ -47,11 +49,75 @@ private static function intoObject(SimpleXMLElement $data, array &$need_array, s
47
49
}
48
50
public static function decodeAsObject (string $ data , array $ need_array = []): stdClass {
49
51
$ xml = simplexml_load_string ($ data );
50
- if ($ xml === false )
52
+ if ($ xml === false ) {
51
53
throw new XmlDecodeFailException ();
54
+ }
52
55
$ name = $ xml ->getName ();
53
56
$ ret = new stdClass ();
54
57
$ ret ->{$ name } = self ::intoObject ($ xml , $ need_array , $ name );
55
58
return $ ret ;
56
59
}
57
- }
60
+ private static function toXml (&$ data , \Psr \Http \Message \StreamInterface $ result , string $ outer_key ,
61
+ ?int $ level ): void {
62
+ $ is_fixed_array = true ;
63
+ $ i = 0 ;
64
+ foreach ($ data as $ key => &$ val ) {
65
+ if ($ key !== $ i ) {
66
+ $ is_fixed_array = false ;
67
+ break ;
68
+ }
69
+ ++$ i ;
70
+ }
71
+ unset($ val );
72
+
73
+ if (! $ is_fixed_array && '' !== $ outer_key ) {
74
+ if ($ level ) {
75
+ $ result ->write (str_repeat (' ' , $ level ));
76
+ }
77
+ $ result ->write ("< $ outer_key> " );
78
+ if (isset ($ level )) {
79
+ $ result ->write ("\n" );
80
+ }
81
+ }
82
+ foreach ($ data as $ key => &$ val ) {
83
+ if (is_scalar ($ val )) {
84
+ if (isset ($ level )) {
85
+ $ result ->write (str_repeat (' ' , $ is_fixed_array ? $ level : $ level + 1 ));
86
+ }
87
+ if ($ is_fixed_array ) {
88
+ $ result ->write ("< $ outer_key><![CDATA[ " );
89
+ $ result ->write ($ val );
90
+ $ result ->write ("]]></ $ outer_key> " );
91
+ } else {
92
+ $ result ->write ("< $ key><![CDATA[ " );
93
+ $ result ->write ($ val );
94
+ $ result ->write ("]]></ $ key> " );
95
+ }
96
+ if (isset ($ level )) {
97
+ $ result ->write ("\n" );
98
+ }
99
+ } else {
100
+ self ::toXml ($ val , $ result , $ is_fixed_array ? $ outer_key : $ key ,
101
+ isset ($ level ) ? ($ is_fixed_array ? $ level : $ level + 1 ) : null );
102
+ }
103
+ }
104
+ if (! $ is_fixed_array && '' !== $ outer_key ) {
105
+ if ($ level ) {
106
+ $ result ->write (str_repeat (' ' , $ level ));
107
+ }
108
+ $ result ->write ("</ $ outer_key> " );
109
+ if (isset ($ level )) {
110
+ $ result ->write ("\n" );
111
+ }
112
+ }
113
+ unset($ val );
114
+ }
115
+ public static function encode ($ valueToEncode , bool $ pretty_print = false ): string {
116
+ if (is_scalar ($ valueToEncode )) {
117
+ throw new \Exception ('Cannot xml encode scalar ' );
118
+ }
119
+ $ res = stream_for ('' );
120
+ self ::toXml ($ valueToEncode , $ res , '' , $ pretty_print ? -1 : null );
121
+ return $ res ->__toString ();
122
+ }
123
+ }
0 commit comments