1 | <?php |
---|
2 | |
---|
3 | class XmlSerializer extends Serializer |
---|
4 | { |
---|
5 | protected $header = array('<?xml version="1.0" encoding="UTF-8"?>', '<javascript>'); |
---|
6 | protected $footer = array('</javascript>'); |
---|
7 | |
---|
8 | protected function lineStarts($line) { |
---|
9 | if (preg_match('%^\t<object [^>]*location="([^"]+)"%', $line, $match)) { |
---|
10 | return $match[1]; |
---|
11 | } |
---|
12 | } |
---|
13 | |
---|
14 | protected function lineEnds($line) { |
---|
15 | if (preg_match('%^\t</object>$%', $line, $match)) { |
---|
16 | return true; |
---|
17 | } |
---|
18 | } |
---|
19 | |
---|
20 | protected function linesToRaw($lines) { |
---|
21 | return DOMDocument::loadXML(implode("\n", $lines)); |
---|
22 | } |
---|
23 | |
---|
24 | public function toObject($raw, $id=null) { |
---|
25 | return $this->ascend($raw, $raw->firstChild); |
---|
26 | } |
---|
27 | |
---|
28 | public function ascend($document, $node) { |
---|
29 | $object = array(); |
---|
30 | |
---|
31 | if ($node->hasAttributes()) { |
---|
32 | if ($node->attributes) { |
---|
33 | foreach ($node->attributes as $attribute) { |
---|
34 | $value = $attribute->value; |
---|
35 | if ($value == 'true') { |
---|
36 | $value = true; |
---|
37 | } |
---|
38 | elseif ($value == 'false') { |
---|
39 | $value = false; |
---|
40 | } |
---|
41 | $object['@' . $attribute->name] = $value; |
---|
42 | } |
---|
43 | } |
---|
44 | } |
---|
45 | if ($node->childNodes) { |
---|
46 | foreach ($node->childNodes as $child_node) { |
---|
47 | if ($child_node->tagName) { |
---|
48 | $object['#' . $child_node->tagName][] = $this->ascend($document, $child_node); |
---|
49 | } |
---|
50 | else { |
---|
51 | // Text node |
---|
52 | $object['content'] = $node->nodeValue; |
---|
53 | } |
---|
54 | } |
---|
55 | } |
---|
56 | |
---|
57 | return $object; |
---|
58 | } |
---|
59 | |
---|
60 | public function toString($raw, $id=null) { |
---|
61 | if (!$id) { |
---|
62 | if (!($id = $raw->firstChild->getAttribute('location'))) { |
---|
63 | throw new Exception('toString must be passed an ID or raw object must contain and ID'); |
---|
64 | } |
---|
65 | } |
---|
66 | |
---|
67 | $lines = explode("\n", str_replace('<?xml version="1.0" encoding="UTF-8"?>' . "\n", '', $raw->saveXML())); |
---|
68 | foreach ($lines as $i => $line) { |
---|
69 | $indent = 0; |
---|
70 | while (substr($line, 0, 2) == ' ') { |
---|
71 | ++$indent; |
---|
72 | $line = substr($line, 2); |
---|
73 | } |
---|
74 | $lines[$i] = str_repeat("\t", $indent) . $line; |
---|
75 | } |
---|
76 | |
---|
77 | if (count($lines) && substr($lines[0], -2) == '/>') { |
---|
78 | $lines[0] = substr($lines[0], 0, -2) . '>'; |
---|
79 | array_splice($lines, 1, 0, array('</object>')); |
---|
80 | } |
---|
81 | |
---|
82 | return implode("\n", $lines); |
---|
83 | } |
---|
84 | |
---|
85 | protected function descend($document, $node, $object) { |
---|
86 | foreach ($object as $key => $value) { |
---|
87 | if (is_bool($value)) { |
---|
88 | $value = $value ? 'true' : 'false'; |
---|
89 | } |
---|
90 | switch ($key{0}) { |
---|
91 | case '@': |
---|
92 | $node->setAttribute(substr($key, 1), $value); |
---|
93 | break; |
---|
94 | case '#': |
---|
95 | foreach ($value as $child) { |
---|
96 | $this->descend($document, $node->appendChild($document->createElement(substr($key, 1))), $child); |
---|
97 | } |
---|
98 | break; |
---|
99 | default: |
---|
100 | if ($key === 'content') { |
---|
101 | $node->appendChild($document->createTextNode($value)); |
---|
102 | } |
---|
103 | } |
---|
104 | } |
---|
105 | } |
---|
106 | |
---|
107 | public function convertToRaw($object) { |
---|
108 | $document = new DOMDocument('1.0', 'UTF-8'); |
---|
109 | $document->preserveWhiteSpace = true; |
---|
110 | $document->formatOutput = true; |
---|
111 | |
---|
112 | $this->descend($document, $document->appendChild($document->createElement('object')), $object); |
---|
113 | |
---|
114 | return $document; |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | ?> |
---|