Skip to content

Commit 194dbc9

Browse files
authored
Add method Xml::encode()
1 parent 9ab8dcf commit 194dbc9

File tree

1 file changed

+75
-9
lines changed

1 file changed

+75
-9
lines changed

src/Xml.php

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
<?php
2+
use function Swlib\Http\stream_for;
23
class Xml {
34
private static function intoObject(SimpleXMLElement $data, array &$need_array, string $key) {
45
$s = $data->__toString();
56
if (str_replace([
6-
' ',
7-
"\n",
8-
"\r",
9-
"\t"
10-
], '', $s) != '') {
7+
' ',
8+
"\n",
9+
"\r",
10+
"\t"
11+
], '', $s) != '') {
1112
return $s;
1213
}
1314
$result = new stdClass();
1415
$flag = 0; // 0表示没有儿子 1表示有多个同键名儿子 2表示有儿子
1516
$map = [];
16-
foreach ($data as $k=>$v) {
17+
foreach ($data as $k => $v) {
1718
$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})) {
1920
$result->{$k} = [];
21+
}
2022

2123
// 有两项相同健值,说明这里需要转换为数组
2224
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
4749
}
4850
public static function decodeAsObject(string $data, array $need_array = []): stdClass {
4951
$xml = simplexml_load_string($data);
50-
if ($xml === false)
52+
if ($xml === false) {
5153
throw new XmlDecodeFailException();
54+
}
5255
$name = $xml->getName();
5356
$ret = new stdClass();
5457
$ret->{$name} = self::intoObject($xml, $need_array, $name);
5558
return $ret;
5659
}
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

Comments
 (0)